nó dentro HTML usando ElementTree
-
23-08-2019 - |
Pergunta
Eu estou usando ElementTree para analisar um arquivo XML. Em algumas áreas, haverá dados HTML. Por exemplo, considere uma declaração da seguinte forma:
<Course>
<Description>Line 1<br />Line 2</Description>
</Course>
Agora, supondo _course é uma variável Elemento que detêm este elemento Couse. Eu quero acessar descrição deste curso, então eu faço:
desc = _course.find("Description").text;
Mas então desc contém apenas "Line 1". Eu li algo sobre o atributo .tail, então eu tentei também:
desc = _course.find("Description").tail;
E eu recebo a mesma saída. O que devo fazer para que desc ser "Linha 1 | Linha 2" (ou, literalmente, qualquer coisa entre e)? Em outras palavras, eu estou procurando algo semelhante à propriedade .innerText em C # (e muitas outras línguas eu acho).
Solução
Você tem controle sobre a criação do arquivo xml? O conteúdo de etiquetas XML que contêm etiquetas XML (ou semelhante), ou caracteres de marcação ( '<
', etc.) deve ser codificada para evitar este problema. Você pode fazer isso com:
- CDATA seção
- na base 64 ou algum outro codificação (que não inclui xml caracteres reservados)
- Codificação Entity ( '
<
'==
'<
')
Se você não pode fazer essas alterações, e ElementTree não pode ignorar as tags não incluídos no esquema XML, então você terá a pré-processar o arquivo. Claro, você está fora de sorte se o esquema sobrepõe html.
Outras dicas
Você está tentando ler o atributo cauda do elemento errado. Tentar
desc = _course.find("br").tail;
O atributo cauda é usada para armazenar arrastando os nós de texto ao ler arquivos XML misto de conteúdo; texto que segue diretamente depois de um elemento são armazenados no atributo cauda para esse elemento:
<tag><elem>this goes into elem's text attribute</elem>this goes into elem's tail attribute</tag>
código simples snippet para imprimir texto e atributos cauda de todos os elementos em 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)
Output:
Line 1 Line 2 child text child tail
http://code.activestate.com/recipes/498286- ElementTree-text-helper / para uma solução melhor. Ele pode ser modificado para se adequar.
P.S. Eu mudei meu nome de user839338 como citado no próximo post
Personagens como "<" e "&" são ilegais em elementos XML.
"<" irá gerar um erro porque os interpreta analisador-lo como o início de um novo elemento.
"&" irá gerar um erro porque os interpreta analisador-lo como o início de uma entidade de caráter.
Algum texto, como o código JavaScript, contém uma grande quantidade de "<" ou "&" caracteres. Para erros a evitar código de script pode ser definida como CDATA.
Tudo dentro de uma seção CDATA é ignorado pelo analisador.
A CDATA seção começa com "":
Mais informações em: http://www.w3schools.com/xmL/xml_cdata.asp
Espero que isso ajude!
Inspirado pela de user839338 resposta , eu wen't e olhou para uma solução razoável, que parece um pouco com isso.
>>> 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'
>>>
Não há nenhuma maneira simples de eliminar a tag circundante (originalmente <Description>
), mas é facilmente modificado em algo que poderia ser usado conforme necessário, por exemplo <div>
ou <span>