4

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

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

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

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

但随后 desc 仅包含“第 1 行”。我读了一些关于 .tail 属性的东西,所以我也尝试了:

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

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

4

4 回答 4

3

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

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

如果您不能进行这些更改,并且 ElementTree 不能忽略未包含在 xml 架构中的标签,那么您将不得不对文件进行预处理。当然,如果架构与 html 重叠,那么您就不走运了。

于 2009-07-06T18:22:37.567 回答
3

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

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

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

    <tag><elem>这进入了elem的
    文本属性</elem>这进入
    elem 的尾部属性</tag>

用于打印 xml/xhtml 中所有元素的文本和尾部属性的简单代码片段。

将 xml.etree.ElementTree 导入为 ET

def processElem(elem):
    如果 elem.text 不是无:
        打印元素.text
    对于 elem 中的孩子:
        processElem(孩子)
        如果 child.tail 不是无:
            打印child.tail

xml = '''<课程>
    <Description>第 1 行<br />第 2 行 <span>子文本</span>子尾部</Description>
    </课程>'''

根 = ET.fromstring(xml)
processElem(根)

输出:

1号线
2号线
子文本
孩子尾巴

请参阅http://code.activestate.com/recipes/498286-elementtree-text-helper/以获得更好的解决方案。它可以修改以适应。

PS 我从下一篇文章中引用的 user839338 更改了我的名字

于 2011-07-11T17:13:53.223 回答
1

“<”和“&”之类的字符在 XML 元素中是非法的。

"<" 将产生错误,因为解析器将其解释为新元素的开始。

"&" 将产生错误,因为解析器将其解释为字符实体的开始。

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

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

CDATA 部分以“”开头:

更多信息:http ://www.w3schools.com/xml/xml_cdata.asp

希望这可以帮助!

于 2009-07-06T18:25:28.230 回答
1

user839338 的回答启发,我没有寻找一个合理的解决方案,看起来有点像这样。

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

于 2011-07-15T17:46:02.687 回答