2016-07-29 1 views
4

Я пытаюсь разобрать некоторые XML, который находится в следующем формате:LXML eTree iterparse глубина

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

PARSING его с этим

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

производит пустой имя переменную из-за

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

Вопрос:

Есть ли способ установить глубину iterparse или игнорировать метку подкласса, кроме проверки, является ли она пустой?

ответ

0

Первое, что пришло на ум

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

Это работает для меня, и вдохновлен предыдущим ответом:

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()') 

В качестве альтернативного решения, анализировать весь файл и использовать XPath для получите название верхней метки:

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

Файл огромный. Размышление о свертке сразу не является вариантом. – abruski