Python Elementtree Filterung nach XPath

Sep 04 2020

Stellen Sie sich vor, ich habe eine XML wie diese:

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

Wie kann ich das machen:

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)

Nun, ich weiß, dass res_bdas nicht funktionieren wird, aber ich denke, dies ist ein häufiges Problem, sodass jemand eine Idee hat, wie die Problemumgehung dafür aussehen soll.

Um es ein bisschen mehr hervorzuheben (aus den Kommentaren kopiert)

Ich könnte das Element, das "foo" enthält, sicher finden, aber ich möchte wissen, ob es eine Möglichkeit gibt, ein Element zu finden, das das Attribut NICHT enthält, ist = "false".

Antworten

2 balderman Sep 04 2020 at 17:10

siehe unten

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)

Ausgabe

 foo 
 no_is 
deadshot Sep 04 2020 at 16:59

Sie können lxml verwenden

from lxml import etree

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

print(res[0].text) #foo