web-dev-qa-db-fra.com

Comment rechercher récursivement une balise XML en utilisant LXML?

<?xml version="1.0" ?>
<data>
    <test >
        <f1 />
    </test >
    <test2 >
        <test3>
         <f1 />
        </test3>
    </test2>
    <f1 />
</data>

En utilisant lxml, est-il possible de trouver récursivement la balise "f1"? J'ai essayé la méthode findall mais elle ne fonctionne que pour les enfants immédiats.

Je pense que je devrais opter pour BeautifulSoup pour cela !!!

49
shahjapan

Vous pouvez utiliser XPath pour effectuer une recherche récursive:

>>> from lxml import etree
>>> q = etree.fromstring('<xml><hello>a</hello><x><hello>b</hello></x></xml>')
>>> q.findall('hello')     # Tag name, first level only.
[<Element hello at 414a7c8>]
>>> q.findall('.//hello')  # XPath, recursive.
[<Element hello at 414a7c8>, <Element hello at 414a818>]
76
Max Shawabkeh

iterfind() itère sur tous les éléments qui correspondent à l'expression du chemin

findall() renvoie une liste des éléments correspondants

find() ne renvoie efficacement que la première correspondance

findtext() renvoie le contenu .text de la première correspondance

Exemples illustratifs:

>>> root = etree.XML("<root><a x='123'>aText<b/><c/><b/></a></root>")
#Find a child of an Element:
>>> print(root.find("b"))
None
>>> print(root.find("a").tag)
a
#Find an Element anywhere in the tree:
>>> print(root.find(".//b").tag)
b
>>> [ b.tag for b in root.iterfind(".//b") ]
['b', 'b']
#Find Elements with a certain attribute:
>>> print(root.findall(".//a[@x]")[0].tag)
a
>>> print(root.findall(".//a[@y]"))
[]

Référence: http://lxml.de/tutorial.html#elementpath

(Cette réponse est une sélection sélective pertinente à partir du contenu de ce lien)

30
codersofthedark