HTML dentro del nodo usando ElementTree
-
23-08-2019 - |
Pregunta
Estoy usando ElementTree para analizar un archivo XML.En algunos campos, habrá datos HTML.Por ejemplo, considere una declaración de la siguiente manera:
<Course>
<Description>Line 1<br />Line 2</Description>
</Course>
Ahora, supongamos que _curso es una variable Elemento que contiene este elemento Couse.Quiero acceder a la descripción de este curso, entonces lo hago:
desc = _course.find("Description").text;
Pero entonces desc solo contiene la "Línea 1".Leí algo sobre el atributo .tail, así que probé también:
desc = _course.find("Description").tail;
Y obtengo el mismo resultado.¿Qué debo hacer para que desc sea "Línea 1"?
¿Línea 2" (o literalmente cualquier cosa entre y)?En otras palabras, estoy buscando algo similar a la propiedad .innerText en C# (y supongo que en muchos otros lenguajes).
Solución
¿Tiene alguna control sobre la creación del archivo XML? El contenido de etiquetas XML que contienen las etiquetas XML (o similares), o caracteres de marcado ( '<
', etc.) deben ser codificados para evitar este problema. Esto se puede hacer ya sea con:
- a CDATA sección
- Base64 o alguna otra codificación (que no incluye caracteres reservados XML)
- Entidad codificación ( '
<
'==
'<
')
Si no puede hacer estos cambios, y elementtree no puede ignorar las etiquetas no incluidos en el esquema XML, entonces se tiene que pre-procesar el archivo. Por supuesto, usted está de suerte si el esquema se superpone html.
Otros consejos
Usted está tratando de leer el atributo de cola del elemento equivocado. Trate
desc = _course.find("br").tail;
El atributo de cola se utiliza para almacenar arrastrando los nodos de texto al leer archivos XML de contenido mixto; texto que sigue directamente después de un elemento se almacena en el atributo de la cola para ese elemento:
<tag><elem>this goes into elem's text attribute</elem>this goes into elem's tail attribute</tag>
código simple fragmento de código para imprimir el texto y los atributos de la cola de todos los elementos de XML / XHTML.
import xml.etree.ElementTree as ET def processElem(elem): if elem.text is not None: print elem.text for child in elem: processElem(child) if child.tail is not None: print child.tail xml = '''<Course> <Description>Line 1<br />Line 2 <span>child text </span>child tail</Description> </Course>''' root = ET.fromstring(xml) processElem(root)
Salida:
Line 1 Line 2 child text child tail
http://code.activestate.com/recipes/498286- elementtree-texto-helper / una solución mejor. Puede ser modificado para adaptarse.
P.S. He cambiado mi nombre de user839338 como se cita en el próximo post
Caracteres como "<" y "&" son ilegales en elementos XML.
"<" generará un error porque el analizador lo interpreta como el inicio de un nuevo elemento.
"&" generará un error porque el analizador lo interpreta como el inicio de una entidad de carácter.
Algunos textos, como el código JavaScript, contienen muchos caracteres "<" o "&".Para evitar errores, el código del script se puede definir como CDATA.
El analizador ignora todo lo que hay dentro de una sección CDATA.
Una sección CDATA comienza con "":
Más información sobre: http://www.w3schools.com/xmL/xml_cdata.asp
¡Espero que esto ayude!
de user839338 respuesta , me miré y wen't para una solución razonable, que parece un poco a esto.
>>> from xml.etree import ElementTree as etree
>>> corpus = '''<Course>
... <Description>Line 1<br />Line 2</Description>
... </Course>'''
>>>
>>> doc = etree.fromstring(corpus)
>>> desc = doc.find("Description")
>>> desc.tag = 'html'
>>> etree.tostring(desc)
'<html>Line 1<br/>Line 2</html>\n'
>>>
No hay forma sencilla de eliminar la etiqueta que rodea (originalmente <Description>
), pero es fácilmente modificada en algo que podría ser utilizado cuando sea necesario, por ejemplo <div>
o <span>