В lxml как удалить тег, но сохранить все содержимое? - PullRequest
18 голосов
/ 13 января 2011

Проблема заключается в следующем: у меня есть фрагмент XML, например:

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

Для результата я хочу удалить все <a> - и <c> -Tag, но сохранить их (текстовое) содержимое и дочерние узлы такими, какие они есть. Кроме того, элемент <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 ]

33 голосов
/ 13 января 2011

Попробуйте это: 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 голос
/ 20 мая 2015

Используйте функцию Cleaner из lxml для удаления тегов из html-содержимого.Ниже приведен пример, чтобы делать то, что вы хотите.Для HTML-документа Cleaner является лучшим общим решением проблемы, чем использование strip_elements, потому что в подобных случаях вы хотите удалить больше, чем просто тег;Вы также хотите избавиться от таких вещей, как атрибуты onclick = function () для других тегов.

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

Список тегов, которые нужно удалить.Будут удалены только теги, их содержимое будет перенесено в родительский тег.

...