【问题标题】:Parse xml node children list by tag with any prefix in python按标签解析xml节点子列表,在python中带有任何前缀
【发布时间】:2015-07-27 15:09:40
【问题描述】:

我想获得一个项目列表,与它们的前缀无关。 我的目标是创建一个方法(如果存在类似的东西,请注意我),它有一个参数(标记名)并返回元素列表。

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

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

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

【问题讨论】:

  • 也许这会有所帮助:stackoverflow.com/questions/19302594/…
  • 你说的是什么意思?“我不能假设,xml有xmlns”。这是否意味着,例如,media 前缀可能永远不会在任何地方声明(XML 文档中的任何地方都没有xmlns:media="...")?
  • @har07 是的,xml 创建者经常忘记 xmlns 声明。

标签: python xml lxml domparser


【解决方案1】:

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

lxml 也可以通过设置参数recover=True 来处理未定义的前缀,但现在问题来了; local-name() 仍然为具有未定义前缀的元素返回前缀“标记名”。有一种匹配这种元素的 hacky 方法,通过查找本地名称 包含 :tagname 的元素 - 或者更准确地说,查找本地名称 ends with :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>

【讨论】:

  • 谢谢,这正是我需要的 :) 我以前从未使用过 xpath。
猜你喜欢
  • 2013-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 2016-11-12
  • 1970-01-01
  • 2017-04-21
  • 1970-01-01
相关资源
最近更新 更多