【问题标题】:Python Elementtree filtering by XPathXPath 的 Python Elementtree 过滤
【发布时间】:2020-09-04 09:29:40
【问题描述】:

想象一下我有一个这样的 XML:

<root>
  <elements>
    <element> foo </element>
    <element is="false"> foo </element>
    <element is="false"> bli </element>
    <element is="false"> bla </element>
  </elements>
</root>

我该怎么做:

import xml.etree.ElementTree as ET

root = ET.fromstring(XmlFromAbove)
res_a  = root.findall("element[@is='false']")) ##<- This gives me all elements with the specific attribute
res_b  = root.findall("element[not@is='false']")) ##<- This would be nice to give me all elements without that specific attribute (`<element> foo </element>` in this case)

现在,我知道 res_b 不起作用,但我想这是一个常见问题,所以有人知道解决方法是什么吗?

再多指出一点(抄自cmets)

我可以肯定地找到包含“foo”的元素,但我想知道是否有办法找到任何不包含属性 is="false" 的元素。

【问题讨论】:

  • 你想找什么?
  • foo 通过过滤掉属性 is="false"
  • 你可以直接找到 foo - 不是吗?为什么要将 foo 与 is=false 结合使用?试着解释一下这里的逻辑。
  • 我可以肯定找到“foo”,但我想知道是否有办法找到任何不包含属性 is="false" 的元素。
  • 知道了。看我的回答。

标签: python xml xpath elementtree


【解决方案1】:

见下文

import xml.etree.ElementTree as ET

xml = '''<root>
  <elements>
    <element> foo </element>
    <element is="false"> foo </element>
    <element is="false"> bli </element>
    <element is="false"> bla </element>
    <element please="false"> no_is </element>
    <element is="true"> with_true_is </element>
  </elements>
</root>'''

root = ET.fromstring(xml)

no_is_lst = [e for e in root.findall('.//element') if 'is' not in e.attrib]
for e in no_is_lst:
    print(e.text)

输出

 foo 
 no_is 

【讨论】:

  • 我会为我的实际代码尝试一下,但从我的感觉这应该可以工作并且尊重内置模块 xml.etree。到目前为止谢谢!
  • @goetzmoritz 接受的解决方案并不真正符合您的问题。下次请具体说明
  • @JaSON 这个答案提供了正确的输出。您的答案是提供一个 KeyError,与正确或不正确的 XPath 表达式无关。您的回答会更受欢迎,因为它更简单,但在技术上是错误的。
  • @goetzmoritz 我的意思是,根据您的问题,您正在寻找 XPath 解决方案,该解决方案允许获取 不包含具有特定值的@attribute 的节点。此解决方案与 XPath 无关,它不满足您的要求,因为它会忽略带有 is="true" 的节点,这也不是您最初想要的。
【解决方案2】:

您可以使用lxml

from lxml import etree

root = etree.fromstring(data)
res = root.xpath(".//element[not(@is)]")

print(res[0].text) #foo

【讨论】:

  • lxml 生产准备好了吗?我试图避免任何未正确维护的第 3 方库(顺便说一句,我不喜欢 node-js 的一件事。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多