как удалить элемент в lxml
мне нужно полностью удалить элементы, основанные на содержании атрибута, используя lxml python. Пример:
import lxml.etree as et
xml="""
<groceries>
<fruit state="rotten">apple</fruit>
<fruit state="fresh">pear</fruit>
<fruit state="fresh">starfruit</fruit>
<fruit state="rotten">mango</fruit>
<fruit state="fresh">peach</fruit>
</groceries>
"""
tree=et.fromstring(xml)
for bad in tree.xpath("//fruit[@state='rotten']"):
#remove this element from the tree
print et.tostring(tree, pretty_print=True)
Я хотел бы это напечатать:
<groceries>
<fruit state="fresh">pear</fruit>
<fruit state="fresh">starfruit</fruit>
<fruit state="fresh">peach</fruit>
</groceries>
есть ли способ сделать это без сохранения временной переменной и печать его вручную, как это:
newxml="<groceries>n"
for elt in tree.xpath('//fruit[@state='fresh']'):
newxml+=et.tostring(elt)
newxml+="</groceries>"
3 ответа:
использовать
remove
метод xmlElement:tree=et.fromstring(xml) for bad in tree.xpath("//fruit[@state=\'rotten\']"): bad.getparent().remove(bad) # here I grab the parent of the element to call the remove directly on it print et.tostring(tree, pretty_print=True, xml_declaration=True)
Если бы мне пришлось сравнивать с версией @Acorn, мой будет работать, даже если удаляемые элементы не находятся непосредственно под корневым узлом вашего xml.
Я встретил одну ситуацию:
<div> <script> some code </script> text here </div>
div.remove(script)
удалитьtext here
часть, которую я не хотел.после ответа здесь, я обнаружил, что
etree.strip_elements
это лучшее решение для меня, которое вы можете контролировать, будете ли вы удалять текст позади сwith_tail=(bool)
парам.но все же я не знаю, Может ли это использовать фильтр xpath для тега. Просто положите это для информирования.
вот док:
strip_elements (tree_or_element, *tag_names, with_tail=True)
удалить все элементы с указанными именами тегов из дерева или поддерево. Это позволит удалить элементы и все их поддерево, включая все их атрибуты, текстовое содержимое и потомков. Оно также будет удален хвостовой текст элемента, если вы явно установите
with_tail
параметр аргумента ключевого слова для False.имена тегов могут содержать подстановочные знаки, как в
_Element.iter
.обратите внимание, что это не приведет к удалению элемента (или корня ElementTree элемент), который вы передали, даже если он соответствует. Это будет только лечить его потомок. Если вы хотите включить корневой элемент, проверьте его имя тега непосредственно перед вызовом этой функции.
пример использования::
strip_elements(some_element, 'simpletagname', # non-namespaced tag '{http://some/ns}tagname', # namespaced tag '{http://some/other/ns}*' # any tag from a namespace lxml.etree.Comment # comments )