2013-07-08 124 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>節點,並做到這一點,你將不得不創建節點。

相關問題