nota design
La risposta da @tdelaney è fondamentalmente giusto, ma voglio puntare a una sfumatura di Python elemento albero API. Ecco una citazione da the lxml
tutorial:
Gli elementi possono contenere testo:
<root>TEXT</root>
In molti documenti XML (documenti data-centric), questo è l'unico posto in cui il testo può essere trovato. È incapsulato da un tag foglia in fondo alla gerarchia dell'albero.
Tuttavia, se XML è utilizzato per i documenti di testo con tag come HTML (X), il testo può apparire anche tra elementi diversi, proprio nel bel mezzo di un albero:
<html><body>Hello<br/>World</body></html>
Qui, il tag <br/>
è circondato da testo. Questo è spesso definito come stile documento o XML a contenuto misto. Gli elementi supportano questo attraverso la loro proprietà tail
. Contiene il testo che segue direttamente l'elemento, fino all'elemento successivo nell'albero XML.
Le due proprietà text
e tail
sono sufficienti per rappresentare qualsiasi contenuto di testo in un documento XML. In questo modo, l'API ElementTree non richiede alcun nodo di testo speciale oltre alla classe Element, che tende a intromettersi abbastanza spesso (come potreste sapere dalle classiche API DOM).
Attuazione
Prendendo queste proprietà in considerazione è possibile recuperare il testo del documento senza forzare l'albero di nodi di testo in uscita.
#!/usr/bin/env python3.3
import itertools
from pprint import pprint
try:
from lxml import etree
except ImportError:
from xml.etree import cElementTree as etree
def textAndElement(node):
'''In py33+ recursive generators are easy'''
yield node
text = node.text.strip() if node.text else None
if text:
yield text
for child in node:
yield from textAndElement(child)
tail = node.tail.strip() if node.tail else None
if tail:
yield tail
if __name__ == '__main__':
xml = '''
<species>
Mammals: <dog/> <cat/>
Reptiles: <snake/> <turtle/>
Birds: <seagull/> <owl/>
</species>
'''
doc = etree.fromstring(xml)
pprint(list(textAndElement(doc)))
#[<Element species at 0x7f2c538727d0>,
#'Mammals:',
#<Element dog at 0x7f2c538728c0>,
#<Element cat at 0x7f2c53872910>,
#'Reptiles:',
#<Element snake at 0x7f2c53872960>,
#<Element turtle at 0x7f2c538729b0>,
#'Birds:',
#<Element seagull at 0x7f2c53872a00>,
#<Element owl at 0x7f2c53872a50>]
gen = textAndElement(doc)
next(gen) # skip root
groups = []
for _, g in itertools.groupby(gen, type):
groups.append(tuple(g))
pprint(dict(zip(*[iter(groups)] * 2)))
#{('Birds:',): (<Element seagull at 0x7fc37f38aaa0>,
# <Element owl at 0x7fc37f38a820>),
#('Mammals:',): (<Element dog at 0x7fc37f38a960>,
# <Element cat at 0x7fc37f38a9b0>),
#('Reptiles:',): (<Element snake at 0x7fc37f38aa00>,
# <Element turtle at 0x7fc37f38aa50>)}
se si guarda oltre alla tua destra ... sembra che il 4 ° uno verso il basso sotto correlata dovrebbe puntare nella giusta direzione ... –
Hai sotto controllo del formato XML?Normalmente, i classificatori come i Mammiferi, ecc., Sono espressi come nomi di elementi xml o attributi (ad es.) in modo che i selettori di xpath siano facilmente scritti. –
tdelaney
No, non posso modificare l'XML. – Alicia