Удалить дочерние узлы после определенного дочернего узла - PullRequest
0 голосов
/ 22 октября 2018

Я хочу удалить все узлы (включая текст) внутри элемента, которые находятся ниже элемента <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 голосов
/ 22 октября 2018

Попробуйте использовать приведенный ниже код для удаления узлов:

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>
...