2017-03-29 3 views
1

Ich wurde beauftragt, einige alte XML-Parsing-Code zu Python zu schreiben und ich stolperte in die Freude, die cElementTree ist und ich liebe es, weil ich so viel in so wenigen Zeilen tun kann.Parsing XML mit cElementTree

Mein Erfahrungslevel mit xpath ist nicht so umfangreich und diese Frage ist mehr über Bohren weiter unten in der Struktur.

Ich habe dies in test.xml

<?xml version="1.0"?> 
    <ownershipDocument> 
    <issue> 
     <ic>0000030305</ic> 
     <iname>DUCOMM</iname> 
     <its>DCP</its> 
    </issue> 
    <ndt> 
     <ndtran> 
      <tc> 
       <tft>4</tft> 
       <tc>P</tc> 
       <esi>0</esi> 
      </tc> 
     </ndtran> 
     <ndtran> 
      <tc> 
       <tft>4</tft> 
       <tc>P</tc> 
       <esi>0</esi> 
      </tc> 
      </ndtran> 
    </ndt> 
</ownershipDocument> 

schrieb ich dieses Skript in Python:

import xml.etree.cElementTree as ET 
tree = ET.parse('test.xml') 
root = tree.getroot() 
print root.tag 
print root.attrib 
for child in root: 
    print(child.tag, child.attrib) 

for issue in root.findall('issue'): 
    ic = issue.find('ic').text 
    iname= issue.find('iname').text 
    print(ic,iname) 

Das gibt mir:

ownershipDocument 
{} 
('issue', {}) 
('ndt', {}) 
('0000030305', 'DUCOMM') 

Das bringt mich erfolgreich die Informationen, die ich brauche in Das Thema".

Problem ist, dass ich auf mehrere "ndtran" Knoten (im "ndt" -Knoten) zugreifen muss. Während der Analyse kann ich die "tft", "tc" und "esi" Werte als Gruppen extrahieren, aber ich muss über jeden "tc" Knoten iterieren, die "tft", "tc", "esi" Werte extrahieren, in sie einfügen eine Datenbank und dann zum nächsten "tc" -Knoten gehen und es erneut tun.

Was ich über jede dieser iterieren zu verwenden versucht, war dies:

for tc in root.findall("./ndt/ndtran/tc"): 
    tft = tc.find('tft').text 
    tc = tc.find('tc').text 
    esi = tc.find('esi').text 
    print(tft,tc,esi) 

Das bin ich fast da bekommt (glaube ich), aber es tut mir ein Fehler geben.

esi = tc.find('esi').text 
AttributeError: 'int' object has no attribute 'text' 

Ich hoffe, dass das Sinn macht. Ich glaube, was ich möchte, ist die DOM-Parsing-Methode, die gut ist, da diese Dokumente nicht so groß sind.

Ich freue mich über Ratschläge oder Hinweise in die richtige Richtung.

+0

Versuchen Sie, 'tc' von' for' durch das untergeordnete Element oder irgendeinen anderen Namen als tc iter'for child in root.findall ("./ ndt/ndtran/tc") 'zu ändern –

Antwort

2

Sie ersetzten Wert von tc Attribute string in der vorhergehenden Zeile zu sein:

for tc in root.findall("./ndt/ndtran/tc"): 
    tft = tc.find('tft').text 
    tc = tc.find('tc').text 
    #^^ use different variable name here 
    esi = tc.find('esi').text 
     #^^ at this point, `tc` is no longer referencing the outer <tc> elements 

interessanter Zufall, dass string auch find() Methode hat die int (-1), wenn das Schlüsselwort zurückkehren wird nicht gefunden, daher die 'int' Objekt hat kein Attribut 'text' Fehler.