2011-01-13 2 views
17

Проблема заключается в следующем: У меня есть фрагмент XML следующим образом:В lxml, как удалить тег, но сохранить все содержимое?

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

результата, я хочу, чтобы удалить все <a> - и <c> -Tags, но сохраняют (текст) -contents и ChildNodes просто как они есть. Кроме того, элемент <b>-Element должен быть оставлен нетронутым. В результате должно выглядеть таким образом

<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 собственный подход?

Для справки: Я попытался получить там с element.replace lxml, но так как я хочу вставить текст, где раньше был элемент, я не думаю, что смогу это сделать.

ответ

31

Попробуйте это: 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>' 
+0

Спасибо, это работает отлично. Термин «полоска» мне не приходил, или я мог бы найти ответ сам :) – Thor

+0

Серьезно. Вы собираетесь быть в PyCon 2011? Если да, позвольте мне купить вам пиво или любой другой предпочтительный напиток. Вы только что сделали свою ночь :) – mkelley33

+0

Также потрясающе: '' etree.strip_elements (фрагмент, * ['tag1', 'tag2']) '' – mkelley33

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: 

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

Смежные вопросы