Filtrage de Python Elementtree par XPath

Sep 04 2020

imaginez que j'ai un XML comme celui-ci:

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

Comment puis-je faire ceci:

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)

Maintenant, je sais que res_bcela ne fonctionnera pas, mais je suppose que c'est un problème courant, donc tout le monde a une idée de la solution de contournement pour cela?

Pour le souligner un peu plus (copié des commentaires)

Je pourrais trouver l'élément contenant "foo" pour sûr, mais ce que je veux savoir, c'est s'il existe un moyen de trouver un élément qui ne contient PAS l'attribut est = "false".

Réponses

2 balderman Sep 04 2020 at 17:10

voir ci-dessous

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)

production

 foo 
 no_is 
deadshot Sep 04 2020 at 16:59

Vous pouvez utiliser lxml

from lxml import etree

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

print(res[0].text) #foo