在某个子节点之后删除子节点

时间:2018-10-22 14:32:08

标签: python xpath lxml

我想删除<hr/>元素(包括<hr/>)下面的元素内的所有节点(包括文本)。

例如,此:

<td class="one">
    Some text
    <a href="page1.html"/>
    <br/>
    Some more text
    <br/>
    <a href="page2.html"/>
    <hr/>
    Bottom text
    <br/>
    <a href="page3.html"/>
</td>

应成为:

<td class="one">
    Some text
    <a href="page1.html"/>
    <br/>
    Some more text
    <br/>
    <a href="page2.html"/>
</td>

我有这个XPath可以找到<hr/>下面的所有元素:

./node()[ preceding-sibling::hr[not(following-sibling::hr)] ]

但是我不知道如何删除这些元素。 我试图这样做:

xp = './node()[ preceding-sibling::hr[not(following-sibling::hr)] ]'
els = self.xpath(xp, td_el)
for el in els:
    el.getparent().remove(el)

但是它不适用于文本节点。

最好的方法是什么? 谢谢。

1 个答案:

答案 0 :(得分:3)

尝试使用以下代码删除节点:

from lxml import etree, html

source = """<td class="one">
    Some text
    <a href="page1.html"/>
    <br/>
    Some more text
    <br/>
    <a href="page2.html"/>
    <hr/>
    Bottom text
    <br/>
    <a href="page3.html"/>
</td>"""
html = html.fromstring(source)
parent = html.xpath('//td')[0]
redundant = html.xpath('//hr/preceding-sibling::*[1]/following-sibling::*')

for node in redundant:
    parent.remove(node)

print(etree.tostring(parent))

输出

<td class="one">
    Some text
    <a href="page1.html"/>
    <br/>
    Some more text
    <br/>
    <a href="page2.html"/>
</td>