lxml转换“<”到<。为什么?

时间:2013-07-08 09:57:40

标签: python lxml

我盯着我看这个问题。

我正在将XML封装的HTML数据融入Atlassian Confluence。对于-tags,我需要添加span-tag。但无论我如何尝试,lxml-lib都会转换我的<和>进入<和>分别。但是,转换只适用于我的新标签,其中的任何现有标签都不会受到影响!

看看这个Python代码:

for x in doc.iter():
    if x.tag == "td":
        print x.text
        x.text = "no tags"
        print etree.dump(x)
        x.text = "<span>one tag</span>"
        print etree.dump(x)

对于此输入:

<tr>
  <td>apa</td>
  <td>1.2</td>
  <td>
    <a href="http://korv.com/apa.tar.gz">3.4</a>
  </td>
  <td>no</td>
</tr>
<tr>
  <td>coreutils</td>
  <td>6.12</td>
  <td>
    <a href="http://ftp.gnu.org/gnu/coreutils/coreutils-8.21.tar.xz">8.21</a>
  </td>
  <td>no</td>
</tr>

这是输出:

<td>no tags</td>None
<td>&lt;span&gt;one tag&lt;/span&gt;</td>None
1.2
<td>no tags</td>None
<td>&lt;span&gt;one tag&lt;/span&gt;</td>None
None
<td>no tags<a href="http://korv.com/apa.tar.gz">3.4</a></td>None
<td>&lt;span&gt;one tag&lt;/span&gt;<a href="http://korv.com/apa.tar.gz">3.4</a></td>None
no
<td>no tags</td>None
<td>&lt;span&gt;one tag&lt;/span&gt;</td>None
coreutils
<td>no tags</td>None
<td>&lt;span&gt;one tag&lt;/span&gt;</td>None
6.12
<td>no tags</td>None
<td>&lt;span&gt;one tag&lt;/span&gt;</td>None
None
<td>no tags<a href="http://ftp.gnu.org/gnu/coreutils/coreutils-8.21.tar.xz">8.21</a></td>None
<td>&lt;span&gt;one tag&lt;/span&gt;<a href="http://ftp.gnu.org/gnu/coreutils/coreutils-8.21.tar.xz">8.21</a></td>None
no
<td>no tags</td>None
<td>&lt;span&gt;one tag&lt;/span&gt;</td>None

正如你所看到的那样,-tag是不受影响的,而我的转换。我无法理解这个错误。

为什么我的文字完成了转换,而现有的文件没有改变?

2 个答案:

答案 0 :(得分:5)

您正在将 text 插入XML元素。文本始终将被转义为XML安全。

如果您想添加新标记,请创建一个新的Element; ElementTree.SubElement() factory最简单:

from lxml import etree

etree.SubElement(td, 'span').text = 'one tag'

如果您想换行 td的内容,只需移动所有元素(加上.text属性:

def wrap(parent, tagname, **kw):
    sub = etree.SubElement(parent, tagname, **kw)
    parent.text, sub.text = None, parent.text
    for index, child in enumerate(parent.iterchildren()):
        if child is not sub:
            sub.insert(index, child)
    return parent

wrap(td, 'span')

演示:

>>> etree.tostring(doc.findall('.//td')[2])
'<td>\n    <a href="http://korv.com/apa.tar.gz">3.4</a>\n  </td>\n  '
>>> etree.tostring(wrap(tree.findall('.//td')[2], 'span'))
'<td><span>\n    <a href="http://korv.com/apa.tar.gz">3.4</a>\n  </span></td>\n  '

答案 1 :(得分:1)

写作时

x.text = "<span>one tag</span>"

你说节点的内容就是那个文本。由于<>是XML中的保留字符,因此需要对其进行转义。

看起来您正在尝试创建新的<span>节点,为此,您必须创建节点。

相关问题