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

Foi útil?

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 ( '<' == '&lt;')

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>

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top