2010-04-27 4 views
35
<?xml version="1.0" ?> 
<data> 
    <test > 
     <f1 /> 
    </test > 
    <test2 > 
     <test3> 
     <f1 /> 
     </test3> 
    </test2> 
    <f1 /> 
</data> 

Mit lxml ist es möglich rekursiv für Tag "f1" zu finden? Ich habe versucht, findall Methode, aber es funktioniert nur für unmittelbare Kinder.Wie finden Sie rekursiv für ein XML-Tag mit LXML?

Ich denke, ich sollte BeautifulSoup dafür gehen !!!

Antwort

56

Sie können XPath verwenden rekursiv durchsuchen:

>>> 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>] 
22

iterfind() iteriert über alle Elemente, die den Pfad Ausdruck

findall() gibt eine Liste der passenden Elemente

find() effizient liefert nur das erste Spiel Übereinstimmung

findtext() ret Urnen mit dem .text Inhalt des ersten Treffers

Illustrative Beispiele:

>>> 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]")) 
[] 

Referenz: http://lxml.de/tutorial.html#elementpath

(Diese Antwort aus dem Inhalt an dieser Verbindung relevant selektive Auswahl ist)