2010-08-09 20 views
10

En Python 2.6 usando ElementTree, ¿cuál es una buena manera de buscar el XML (como una cadena) dentro de un elemento particular, como lo que puede hacer en HTML y javascript con innerHTML ?Python y ElementTree: return "inner XML" excluyendo elemento padre

He aquí una muestra simplificada del nodo XML estoy empezando con:

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

me gustaría terminar con esta cadena:

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

He intentado iteración sobre el padre nodo y la concatenación de los tostring() de los niños, pero eso me dio sólo los subnodos:

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

puedo hackear una solución usando expresiones regulares, pero tenía la esperanza de que habría algo menos hacky que esto:

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

Respuesta

8

¿Qué tal:

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')) 

El resultado es:

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

Los siguientes trabajó para mí:

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 '' se utiliza para obtener el texto al comienzo del elemento root. Si no hay texto dom.text es None.

Tenga en cuenta que el resultado no es un XML válido: un XML válido solo debe tener un elemento raíz.

Eche un vistazo a ElementTree docs about mixed content.


utilizar Python 2.6.5, Ubuntu 10.04

+0

hi Emil - su solución funciona bien si todo el texto es dentro de los subelementos, pero se rompe en mi caso donde el texto está directamente dentro del elemento padre. Su nota sobre contenido mixto se aplica claramente aquí, aunque no estoy seguro (todavía) de cómo combinar cabeza, cola y subelementos para emitir una secuencia coherente. –

+0

más cerca ... pero etree.tostring() no incluye la cola de cada subelemento. Y creo que el dom.tail final no es necesario ya que esa es la cadena * después de * un elemento y no dentro de él. –

+0

Parece que no te entiendo Justin - 'empieza aquí',' y' y 'termina aquí' es un texto que está dentro del elemento raíz ?! El fragmento de arriba puede requerir algunos ajustes - puede crear algunos casos de prueba y mejorarlo - consulte el enlace para obtener la documentación sobre cómo manejar el contenido mixto. –

Cuestiones relacionadas