2015-03-27 8 views
5

Questo è il mio dati XMLCome recuperare tutti i nodi figli in una singola query utilizzando lxml & XPATH

<location> 
    <city> 
     <name> New York</name> 
     <type>non-capital</type> 
    </city> 

    <city> 
     <name> London</name> 
     <type>capital</type> 
    </city> 
</location> 

utilizzando lxml & pitone

from lxml import etree as ET 

parser = ET.XMLParser(recover=True) 

tree = ET.fromstring(xml_data,parser) 
print(tree.xpath('//city//name/text() | //city//type/text()')) 

Le opere di codice di cui sopra, ma mi piacerebbe un descrizione nested-array come [['New York','non-capital'],['London','capital']]

Quale sarebbe la query xpath accurata/combinazione di query/cicli per ottenere quanto sopra?

risposta

5

Questo è un modo possibile:

....... 
result = [] 
for city in tree.xpath('//city'): 
    result.append([city.find('name').text, city.find('type').text]) 

print(result) 
# output : 
#[[' New York', 'non-capital'], [' London', 'capital']] 
2

Lista soluzione comprensione:

xml_data='''<location> 
    <city> 
     <name> New York</name> 
     <type>non-capital</type> 
    </city> 
    <city> 
     <name> London</name> 
     <type>capital</type> 
    </city> 
</location>''' 

from lxml import etree as ET 

parser = ET.XMLParser(recover=True) 

tree = ET.fromstring(xml_data,parser) 
print(tree.xpath('//city')) 


cities = [[c.text for c in n if c.tail] for n in tree.xpath('//city')] 

risultati in:

[[' New York', 'non-capital'], [' London', 'capital']] 
+0

'[[c.text per c n] per n in tree.xpath ('// city')] 'funziona bene, cosa fa c.tail? – wolfgang

+0

È solo la mia abitudine che ho, ma nel tuo caso non è necessario. lxml può avere testo normale e il cosiddetto tail tail. Altro [here] (http://lxml.de/tutorial.html) – Marcin

+0

Continua a ricevere questo errore: ValueError: le stringhe Unicode con la dichiarazione di codifica non sono supportate. Si prega di utilizzare byte di input o frammenti XML senza dichiarazione. –