2013-07-08 99 views
-1

我已经盯住了这个问题。lxml将“<”转换为<。为什么?

我将XML封装的HTML数据存入Atlassian Confluence。对于我需要添加span标签的标签。但不管我如何尝试,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 

正如你所看到的 - 标签内部是未触及过的,而我是被转换的。我无法理解这个错误。

为什么我的文本转换已完成,而未改变现有文本?

回答

5

您正在将文本插入到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 ' 
+0

好点。我还没有找到如何添加这个新的标签,围绕td标签的所有内容。那就是:​​foo =>​​ foo。它可以在纯文本框中使用,但当​​包含其他标签时会失败,如,
等。 –
bos

+0

@bos:您可以在新的“span”中使用'span.insert(index,elem)''元素将*现有元素移动到跨度中。将循环结合到'td'的现有子元素上,您可以立即将所有元素移动到一个跨度中。 :-) –

1

当您撰写

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

您是说节点的内容就是文本。由于<>是XML中的保留字符,因此需要将其转义。

它看起来像你正在试图创建新的<span>节点,并做到这一点,你将不得不创建节点。

相关问题