在lxml中,如何删除标记但保留所有内容?

时间:2011-01-13 14:46:56

标签: python xml lxml

问题在于:我有一个像这样的XML片段:

<fragment>text1 <a>inner1 </a>text2 <b>inner2</b> <c>t</c>ext3</fragment>

对于结果,我想删除所有<a> - 和<c> - 标签,但保留其(文本)内容和子节点。此外,<b> - 元素应保持不变。那么结果应该是

<fragment>text1 inner<d>1</d> text2 <b>inner2</b> text3</fragment>

暂时,我将恢复一个非常脏的技巧:我将etree.tostring片段,通过正则表达式删除有问题的标签,并用etree.fromstring结果替换原始片段(不是真正的代码,但应该是这样的):

from lxml import etree
fragment = etree.fromstring("<fragment>text1 <a>inner1 </a>text2 <b>inner2</b> <c>t</c>ext3</fragment>")
fstring = etree.tostring(fragment)
fstring = fstring.replace("<a>","")
fstring = fstring.replace("</a>","")
fstring = fstring.replace("<c>","")
fstring = fstring.replace("</c>","")
fragment = etree.fromstring(fstring)

我知道我可以使用xslt实现这一点,我知道lxml可以使用xslt,但是必须有更多的lxml本机方法吗?

供参考:我已经尝试过使用lxml的element.replace,但由于我想在之前有元素节点的地方插入文本,我认为我不能这样做。

2 个答案:

答案 0 :(得分:33)

试试这个:http://lxml.de/api/lxml.etree-module.html#strip_tags

>>> etree.strip_tags(fragment,'a','c')
>>> etree.tostring(fragment)
'<fragment>text1 inner1 text2 <b>inner2</b> text3</fragment>'

答案 1 :(得分:1)

使用lxml的清除功能从html内容中删除标签。 下面是一个做你想做的事情的例子。对于HTML文档,Cleaner是一个比使用strip_elements更好的通用解决方案,因为在这种情况下你想要剥离的不仅仅是标签;你也想摆脱其他标签上的onclick = function()属性。

import lxml
from lxml.html.clean import Cleaner
cleaner = Cleaner()
cleaner.remove_tags = ['p']
remove_tags:

要删除的标记列表。只会删除标记,其内容将被拉入父标记。