提问人:Альберт Александров 提问时间:9/5/2023 最后编辑:mzjnАльберт Александров 更新时间:9/6/2023 访问量:89
XML - 不带命名空间的查找
XML - Find without namespace
问:
下面有 xml:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:mt_queryRequest xmlns:ns0="http://x5.ru/mdm/common">
<messageHeader>
<reqId>6437636</reqId>
<targetSystem>GGG</targetSystem>
<serviceInterface>NS</serviceInterface>
<interfaceNamespace/>
</messageHeader>
<Item xmlns="http://www.ibm.com/mdm/entry01">
<MDM_ID xmlns="">897346</MDM_ID>
<NAME xmlns="">
<ru_RU is_delta="True" xmlns="http://www.ibm.com/mdm/entry01">NANANN</ru_RU>
</NAME>
<SAPNAME xmlns="">
<ru_RU xmlns="http://www.ibm.com/mdm/entry01">NANANN</ru_RU>
</SAPNAME>
<FULLNAME xmlns="">
<ru_RU xmlns="http://www.ibm.com/mdm/entry01">NANANN</ru_RU>
</FULLNAME>
<IS_RESIDENT xmlns="">Yes</IS_RESIDENT>
<INN xmlns="">549348892</INN>
<KPP xmlns="">693628032</KPP>
<CONTRAGENT_FORM xmlns="">UL</CONTRAGENT_FORM>
<CONTRAGENT_GROUP occ="6543234" xmlns="">
<GROUP xmlns="http://www.ibm.com/mdm/entry01">Sub (Z013)</GROUP>
<SAPCODE xmlns="http://www.ibm.com/mdm/entry01">8012312</SAPCODE>
<IS_ARCHIVE xmlns="http://www.ibm.com/mdm/entry01">No</IS_ARCHIVE>
<GROUP_ID xmlns="http://www.ibm.com/mdm/entry01">P013</GROUP_ID>
<IS_ARCHIVE_ID xmlns="http://www.ibm.com/mdm/entry01">0</IS_ARCHIVE_ID>
</CONTRAGENT_GROUP>
<NAMES_HISTORY occ="1715174529" xmlns="">
<SAPNAME xmlns="http://www.ibm.com/mdm/entry01">
<ru_RU xmlns="">Ghcsjdhc</ru_RU>
</SAPNAME>
</NAMES_HISTORY>
<NORMALIZATION_STATUS xmlns="">Normalized</NORMALIZATION_STATUS>
<CONTRAGENT_FORM_ID xmlns="">3</CONTRAGENT_FORM_ID>
<IS_RESIDENT_ID xmlns="">1</IS_RESIDENT_ID>
</Item>
</ns0:mt_queryRequest>
我不得不在路径中使用命名空间:
import xml.etree.ElementTree as ET
xml = ET.fromstring(xml_string)
res = xml.find('.//{http://www.ibm.com/mdm/entry01}Item/CONTRAGENT_GROUP/{http://www.ibm.com/mdm/entry01}GROUP')')
如您所见,路径中的命名空间是硬编码的,我担心命名空间可能会更改,或者会有多个命名空间(不知何故,我不知道)。
是否有可能摆脱命名空间?我发现的唯一方法是通过 xmltodict lib 将 xml 转换为 dict 并使用 dict。
答:
1赞
Hermann12
9/6/2023
#1
您可以像以下网站一样进行搜索:
res = root.find('.//{*}GROUP')
print(res.text)
输出:
Sub (Z013)
1赞
LMC
9/6/2023
#2
使用 XPath 功能,xpath 函数将有助于查找元素,而不管其命名空间如何lxml
local-name()
>>> from lxml import etree
>>> doc = etree.parse("tmp.xml")
>>> grp = doc.xpath('.//*[local-name()="Item"]/CONTRAGENT_GROUP/*[local-name()="GROUP"]')
>>> print(grp[0].text)
Sub (Z013)
2赞
Michael Kay
9/6/2023
#3
原则上,如果命名空间发生变化,那么所有的赌注都会关闭,因为当命名空间发生变化时,其他一切都可能发生变化。只有命名空间才能告诉您这是哪种类型的 XML 文档。
您似乎正在使用(并且被建议使用)XPath 1.0 的一些非标准扩展。在 XPath 2.0 中,可以使用以下语法按命名空间 URI 和本地名称查找元素
//Q{http://www.ibm.com/mdm/entry01}Item
并且仅通过本地名称和语法
//*:Item
但我认为 ElementTree 不支持这些。
评论