通过 python 中带有任何前缀的标签解析 xml 个节点子列表

Parse xml node children list by tag with any prefix in python

我想要一个独立于前缀的项目列表。 我的目标是创建方法(如果存在这样的东西请通知我),它有一个参数(标记名)和 returns 个元素列表。

例如,在参数 'item' <media:item> 的情况下,<abc:item> 应该是此函数结果的一部分。

最好使用 lxml,但它可以是任何基于 python DOM 的解析器。

不幸的是,我不能假设 xml 有 xmlns,这就是为什么我需要解析任何前缀。

lxml 是一个不错的选择,主要是因为除了许多其他有用的实用程序之外,它还通过 xpath() 方法完全支持 XPath 1.0 版。在 XPath 中,您可以使用注释中提到的 local-name() 来忽略元素命名空间。

lxml 也可以通过设置参数 recover=True 来处理未定义的前缀,但现在问题来了; local-name() 仍然 return 前缀 'tagname' 对于具有未定义前缀的元素。有一种匹配这种元素的 hacky 方法,通过查找本地名称 包含 :tagname 的元素 - 或者更准确地说,找到本地名称 [=22= 的元素] :tagname 而不是 包含 -。

以下是演示的工作示例。该演示使用两个表达式结合逻辑运算符 or;一个用于处理具有未定义前缀的元素,另一个用于处理没有前缀或正确定义前缀的元素:

from lxml import etree

xml = """<root foo="bar">
    <media:item>a</media:item>
    <abc:item>b</abc:item>
    <foo:item>c</foo:item>
    <item>d</item>
</root>"""
parser = etree.XMLParser(recover=True)
tree = etree.fromstring(xml, parser=parser)
tagname = "item"
#expression to match element undefined prefix
predicate1 = "contains(local-name(),':{0}')".format(tagname)
#expression to match element with properly defined prefix or with no prefix
predicate2 = "local-name()='{0}'".format(tagname)
elements = tree.xpath("//*[{0} or {1}]".format(predicate1, predicate2))
for e in elements:
    print(etree.tostring(e))

输出:

<media:item>a</media:item>

<abc:item>b</abc:item>

<foo:item>c</foo:item>

<item>d</item>