2016-08-21 7 views
1

Я пытаюсь получить данные из XML-файла под ним. Для каждого типа объяснение должно быть рядом с ним.Пропустить XML-тег, если атрибут отсутствует

Например:

Оранжевый Они принадлежат к Citrus.They не может расти при температуре ниже Lemon Они принадлежат к Citrus.They не может расти при температуре ниже

<Fruits> 
    <Fruit> 
     <Family>Citrus</Family> 
     <Explanation>They belong to the Citrus.They cannot grow at a temperature below</Explanation> 
     <Type>Orange</Type> 
     <Type>Lemon</Type> 
     <Type>Lime</Type> 
     <Type>Grapefruit</Type> 
    </Fruit> 
     <Fruit> 
     <Family>Pomes</Family> 
     <Type>Apple</Type> 
     <Type>Pear</Type>   
    </Fruit> 
</Fruits> 

Это хорошо работает с кодом внизу. Однако для второй семьи фруктов у меня есть проблема, потому что нет пояснения.

import os 
from xml.etree import ElementTree 
file_name = "example.xml" 
full_file = os.path.abspath(os.path.join("xml", file_name)) 
dom = ElementTree.parse(full_file) 
Fruit = dom.findall("Fruit") 

for f in Fruit: 
    Explanation = f.find("Explanation").text 
    Types = f.findall("Type") 
    for t in Types: 
     Type = t.text 
     print ("{0}, {1}".format(Type, Explanation)) 

Как я могу пропустить теги типа Fruit Family (Pomes), если атрибут Explanation отсутствует?

ответ

1

Использование xml.etree, просто попробуйте найти Объяснение ребенка:

from xml.etree import ElementTree as et 
root = et.fromstring(xml) 

for node in root.iter("Fruit"): 
    if node.find("Explanation") is not None: 
     print(node.find("Family").text) 

Вы также можете использовать XPath, где вы получите фрукты узлы только если они имеют Объяснение ребенка с помощью lxml :

import lxml.etree as et 

root = et.fromstring(xml) 

for node in root.xpath("//Fruit[Explanation]"): 
    print(node.xpath("Family/text()")) 

Если мы запустим его на образце вы увидите, что мы просто получить Citrus:

In [1]: xml = """<Fruits> 
    ...:  <Fruit> 
    ...:   <Family>Citrus</Family> 
    ...:   <Explanation>They belong to the Citrus.They cannot grow at a temperature below</Explanation> 
    ...:   <Type>Orange</Type> 
    ...:   <Type>Lemon</Type> 
    ...:   <Type>Lime</Type> 
    ...:   <Type>Grapefruit</Type> 
    ...:  </Fruit> 
    ...:   <Fruit> 
    ...:   <Family>Pomes</Family> 
    ...:   <Type>Apple</Type> 
    ...:   <Type>Pear</Type> 
    ...:  </Fruit> 
    ...: </Fruits>""" 


In [2]: import lxml.etree as et 

In [3]: root = et.fromstring(xml) 

In [4]: for node in root.xpath("//Fruit[Explanation]"): 
    ...:   print(node.xpath("Family/text()")) 
    ...:  
['Citrus'] 
+1

Отличное решение (+1). Pro tip: '// Fruit [./ Пояснение]' и '// Fruit [Объяснение]' эквивалентны. – kjhughes

+0

@kjhughes, ура, исправлено. –