2015-03-25 13 views
5

Mam następujący plik XML jako wejście:Uzyskiwanie wszystkich wystąpień węzła potomnego za pomocą xml.etree.ElementTree

<Test> 
    <callEvents> 
    <moc> 
     <causeForTermination>0</causeForTermination> 
     <serviceCode> 
     <teleServiceCode>11</teleServiceCode> 
     </serviceCode> 
     <dialledDigits>5555555</dialledDigits> 
     <connectedNumber>77777</connectedNumber> 
    </moc> 

    <moc> 
     <causeForTermination>0</causeForTermination> 
     <serviceCode> 
     <teleServiceCode>11</teleServiceCode> 
     </serviceCode> 
     <dialledDigits>2222222</dialledDigits> 
    </moc> 
    </callEvents> 
    <callEventsCount>100</callEventsCount> 
</Test> 

Chcę wyjście Wszystkie wartości dla dialledDigits. Jednak mój kod wyświetla tylko pierwszą instancję dialledDigits.

dialledDigits {} 5555555 

Moje pożądane wyniki powinny zawierać obie instancje.

dialledDigits {} 5555555 
dialledDigits {} 2222222 

Oto mój kod

import xml.etree.ElementTree as ET 
tree = ET.parse('as.xml') 
root = tree.getroot() 
callevent=root.find('callEvents') 

Moc1=callevent.find('moc') 

for node in Moc1.getiterator(): 
    if node.tag=='dialledDigits': 
     print node.tag, node.attrib, node.text 

Odpowiedz

6

Zastosowanie findall:

Moc1=callevent.findall('moc') 

for moc in Moc1: 
    for node in moc.getiterator(): 
     if node.tag=='dialledDigits': 
      print node.tag, node.attrib, node.text 

wyjściowa:

dialledDigits {} 5555555 
dialledDigits {} 2222222 
+0

Ale nie powinno tam być sposób, aby to zrobić bez wyraźnego jeśli check, ale raczej jak „do węzła moc.inter ("dialledDigits") "? – LazyCat

0

find() powróci pierwszy znacznik obiektu, więc używaj finadall() która zwraca całą tag objects`

>>> Moc1=callevent.find('moc') 
>>> Moc1 
<Element 'moc' at 0x869a2ac> 
>>> Moc1=callevent.findall('moc') 
>>> Moc1 
[<Element 'moc' at 0x869a2ac>, <Element 'moc' at 0x869a4ec>] 
>>> 

iteracyjne na nim:

>>> Mocs=callevent.findall('moc') 
>>> for moc in Mocs: 
...  for node in moc.getiterator(): 
...   if node.tag=='dialledDigits': 
...    print node.tag, node.attrib, node.text 
... 
dialledDigits {} 5555555 
dialledDigits {} 2222222 
6

Można również napisać wyrażenie XPath. Zaledwie 2 linie zamiast 5 i jedna pętla:

for node in tree.findall('.//callEvents/moc/dialledDigits'): 
    print node.tag, node.attrib, node.text 

Demo:

>>> import xml.etree.ElementTree as ET 
>>> 
>>> 
>>> tree = ET.parse('as.xml') 
>>> root = tree.getroot() 
>>> 
>>> for node in tree.findall('.//callEvents/moc/dialledDigits'): 
...  print node.tag, node.attrib, node.text 
... 
dialledDigits {} 5555555 
dialledDigits {} 2222222 
+0

Tak, xpath zadziała, dziękuję. Metoda 'xpath' nie jest dostępna dla ET. Jest obecny w 'lxml'. + upvote –

Powiązane problemy