2016-07-29 20 views
4

Ich versuche, einige XML zu analysieren, die in folgendem Format ist:lxml eTree iterparse Tiefe

<label> 
     <name></name> 
     <sometag></sometag> 
     <sublabels> 
      <label></label> 
      <label></label> 
     </sublabel> 
</label> 

es mit diesem

for event, element in etree.iterparse(gzip.GzipFile(f), events=('end',), tag='label'): 
    if event == 'end': 
     name = element.xpath('name/text()') 

Parsing produziert leer Name Variable wegen der

<sublabels> 
     <label></label> 
     <label></label> 
</sublabel> 

Die Frage:

Gibt es eine Möglichkeit, die Tiefe der Iterparse festzulegen oder die Beschriftung der Sublabel zu ignorieren, außer zu prüfen, ob sie leer ist?

Antwort

0

Das erste, was von der vorherigen Antwort für mich

path = [] 
for event, element in etree.iterparse(gzip.GzipFile(f), events=('start', 'end')): 
    if event == 'start': 
     path.append(element.tag) 
    elif event == 'end': 
     if element.tag == 'label': 
      if not 'sublabels' in path: 
       name = element.xpath('name/text()') 
     path.pop() 
3

Das funktioniert und ist inspiriert in den Sinn kam:

name = None 
level = 0 
for event, element in etree.iterparse(gzip.GzipFile(f), events=('end', 'start'), tag='label'): 
    # Update current level 
    if event == 'start': level += 1; 
    elif event == 'end': level -= 1; 
    # Get name for top level label 
    if level == 0: 
     name = element.xpath('name/text()') 

Als alternative Lösung, analysieren die gesamte Datei und verwenden XPath Holen Sie sich die Top-Bezeichnung:

from lxml import html 

with gzip.open(f, 'rb') as f: 
    file_content = f.read() 
    tree = html.fromstring(file_content) 
    name = tree.xpath('//label/name/text()') 
+0

Die Datei ist riesig. Das Loch Ding sofort zu parse ist keine Option. – abruski