2010-08-09 11 views
10

In Python 2.6 utilizzando ElementTree, quale è un buon modo per recuperare l'XML (come una stringa) all'interno di un particolare elemento, ad esempio ciò che è possibile fare in HTML e javascript con innerHTML ?Python e ElementTree: restituisce "inner XML" escluso l'elemento padre

Ecco un esempio semplificato del nodo XML sto iniziando con:

<label attr="foo" attr2="bar">This is some text <a href="foo.htm">and a link</a> in embedded HTML</label> 

mi piacerebbe finire con questa stringa:

This is some text <a href="foo.htm">and a link</a> in embedded HTML 

Ho provato iterare sul genitore nodo e concatenando il tostring() dei figli, ma che mi ha dato solo i sottonodi:

# returns only subnodes (e.g. <a href="foo.htm">and a link</a>) 
''.join([et.tostring(sub, encoding="utf-8") for sub in node]) 

posso incidere su una soluzione che utilizza le espressioni regolari, ma speravo ci sarebbe qualcosa di meno hacky di questo:

re.sub("</\w+?>\s*?$", "", re.sub("^\s*?<\w*?>", "", et.tostring(node, encoding="utf-8"))) 

risposta

8

ne dite:

from xml.etree import ElementTree as ET 

xml = '<root>start here<child1>some text<sub1/>here</child1>and<child2>here as well<sub2/><sub3/></child2>end here</root>' 
root = ET.fromstring(xml) 

def content(tag): 
    return tag.text + ''.join(ET.tostring(e) for e in tag) 

print content(root) 
print content(root.find('child2')) 

Con conseguente:

start here<child1>some text<sub1 />here</child1>and<child2>here as well<sub2 /><sub3 /></child2>end here 
here as well<sub2 /><sub3 /> 
1

Di seguito ha lavorato per me:

from xml.etree import ElementTree as etree 
xml = '<root>start here<child1>some text<sub1/>here</child1>and<child2>here as well<sub2/><sub3/></child2>end here</root>' 
dom = etree.XML(xml) 

(dom.text or '') + ''.join(map(etree.tostring, dom)) + (dom.tail or '') 
# 'start here<child1>some text<sub1 />here</child1>and<child2>here as well<sub2 /><sub3 /></child2>end here' 

dom.text or '' viene utilizzato per ottenere il testo all'inizio dell'elemento root. Se non c'è il testo dom.text è None.

Si noti che il risultato non è un XML valido: un XML valido dovrebbe avere solo un elemento radice.

Dai uno sguardo allo ElementTree docs about mixed content.


Usare Python 2.6.5, Ubuntu 10.04

+0

hi Emil - la soluzione funziona bene se tutto il testo è all'interno dei sottoelementi, ma si interrompe nel mio caso in cui il testo è direttamente all'interno dell'elemento genitore. La tua nota sui contenuti misti si applica chiaramente qui, anche se non sono ancora sicuro (ancora) come combinare testa, coda e sottoelementi insieme per emettere una stringa coerente. –

+0

closer ... ma etree.tostring() non include la coda di ciascun sottoelemento. E penso che il finale dom.tail non è necessario dal momento che è la stringa * dopo * un elemento e non al suo interno. –

+0

Non sembra capirti Justin - 'inizia qui',' and' e 'end here' è un testo che si trova proprio all'interno dell'elemento root ?! Il frammento di cui sopra potrebbe richiedere un po 'di giocherellando - è possibile creare alcuni casi di test e migliorarlo - consultare il link per la documentazione su come gestire il contenuto misto. –

Problemi correlati