2015-03-09 1 views
0

У меня есть неизвестная структура XML, где я бы хотел найти все узлы с атрибутом Name, содержащим FooBar, которые сами не имеют аналогичного предка. То есть все узлы соответствия самого высокого уровня, исключая их детей.Как я могу использовать ElementTree для поиска всех совпадающих узлов верхнего уровня?

Это текущий код прототипа, который у меня есть для поиска узлов с соответствующим атрибутом. ElementTree не имеет полной реализации XPath, поэтому мы не можем использовать .

found = [] 
    for node in root.iter(): 
     if 'FooBar' in node.attrib.get('Name', ''): 
      found.append(node) 

Там, как представляется, способы получения родителя через .find('..'), но это также возвращает null при вызове его из узла вы начинаете с.

Пример ввода:

<root> 
    <ElementTypeA Name="..........FooBar."> 
     ... 
     <ElementTypeB Name=".......FooBar......."/> 
     <ElementTypeC Name="...FooBar..........."/> 
     <ElementTypeD Name="....................."/> 
     <ElementTypeE Name="..........FooBar."> 
     ..... 
     </ElementTypeE> 
     ... 
    </ElementTypeA> 

    <ElementTypeF Name="..........."> 
     <ElementTypeG Name="..........FooBar."> 
      ... 
      <ElementTypeH Name=".......FooBar......."/> 
      <ElementTypeI Name="..........FooBar."> 
      ..... 
      </ElementTypeI> 
      ... 
     </ElementTypeG> 
    </ElementTypeF> 
</root> 

В приведенном выше ввода, только ElementTypeA и ElementTypeG должны быть выбраны. ElementTypeE имеет соответствующего предка, тогда как ElementTypeF не соответствует.

+0

Вы можете обеспечить ввод & вывод образца? Если я правильно понял, то вы хотите найти все узлы с именем атрибута «Имя» и его значениями «FooBar». И эти узлы не могут иметь аналогичного предка (родительские узлы с одинаковыми именами). –

+0

@VinodSharma Да, но «Имя» может частично совпадать. Я добавил пример для ясности. – Annan

ответ

0

Это крик для рекурсии.

import xml.etree.ElementTree as ET 

def recur(node): 
    # if this node is a foobar, return a one-item list containing it 
    if 'Name' in node.attrib: 
     if "FooBar" in node.attrib['Name']: 
      return [ node ] 
    # otherwise return a list of the results on the children 
    found = [] 
    for child in node: 
     found += recur(child) 
    return found 

tree = ET.parse('test.xml') 
root = tree.getroot() 
print(recur(root)) 

Выход:

[<Element 'ElementTypeA' at 0x7f3890ef4dd0>, <Element 'ElementTypeG' at 0x7f3890eea310>]