使用ElementTree在节点内部的HTML

时间:2009-07-06 18:17:48

标签: python html xml elementtree

我正在使用ElementTree来解析XML文件。在某些字段中,会有HTML数据。例如,考虑如下声明:

<Course>
    <Description>Line 1<br />Line 2</Description>
</Course>

现在,假设_course是一个Element变量,它保存了这个Couse元素。我想访问这门课程的描述,所以我这样做:

desc = _course.find("Description").text;

但是desc只包含“Line 1”。我读了一些关于.tail属性的内容,所以我也试过了:

desc = _course.find("Description").tail;

我得到了相同的输出。我该怎么做才能使desc成为“Line 1
Line 2”(或者字面上的任何东西)?换句话说,我正在寻找类似于C#中的.innerText属性(以及我猜的许多其他语言)。

4 个答案:

答案 0 :(得分:3)

您是否可以控制xml文件的创建?应编码包含xml标记(或类似)或标记字符('<'等)的xml标记的内容以避免此问题。您可以使用以下任一方式执行此操作:

  • CDATA部分
  • Base64或其他一些编码(不包含xml保留字符)
  • 实体编码('<'=='&lt;')

如果您无法进行这些更改,并且ElementTree无法忽略xml架构中未包含的标记,则您必须预处理该文件。当然,如果架构与html重叠,那你就不走运了。

答案 1 :(得分:3)

您正在尝试从错误的元素中读取tail属性。尝试

desc = _course.find("br").tail;

tail属性用于在读取混合内容XML文件时存储尾随文本节点;在元素存储在该元素的tail属性中之后直接跟随的文本:

    <tag><elem>this goes into elem's
    text attribute</elem>this goes into
    elem's tail attribute</tag>

简单的代码片段,用于打印xml / xhtml中所有元素的text和tail属性。

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)

输出:

Line 1
Line 2 
child text 
child tail

有关更好的解决方案,请参阅http://code.activestate.com/recipes/498286-elementtree-text-helper/。它可以修改为适合。

P.S。我在user839338中更改了我的名字,如下一篇文章所述

答案 2 :(得分:1)

像“&lt;”这样的字符和“&amp;”在XML元素中是非法的。

“&LT;”将生成错误,因为解析器将其解释为新元素的开头。

“&安培;”将生成错误,因为解析器将其解释为字符实体的开头。

有些文字,比如JavaScript代码,包含很多“&lt;”或“&amp;”字符。为避免错误,脚本代码可以定义为CDATA。

解析器会忽略CDATA部分内的所有内容。

CDATA部分以“”开头:

有关以下内容的更多信息:http://www.w3schools.com/xmL/xml_cdata.asp

希望这有帮助!

答案 3 :(得分:1)

受到user839338's answer的启发,我没有找到合理的解决方案,看起来有点像这样。

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

没有简单的方法可以消除周围的标记(最初为<Description>),但很容易将其修改为可以根据需要使用的内容,例如<div><span>