如何删除lxml中的元素

我需要使用python的lxml完全删除基于属性内容的元素。 例:

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> 

有没有办法做到这一点,而不是存储一个临时variables,并手动打印,如:

 newxml="<groceries>\n" for elt in tree.xpath('//fruit[@state=\'fresh\']'): newxml+=et.tostring(elt) newxml+="</groceries>" 

使用xmlElement的remove方法:

 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的根节点下,也可以工作。

您正在寻找removefunction。 调用树的remove方法,并传递一个子元素来删除。

 import lxml.etree as et xml=""" <groceries> <fruit state="rotten">apple</fruit> <fruit state="fresh">pear</fruit> <punnet> <fruit state="rotten">strawberry</fruit> <fruit state="fresh">blueberry</fruit> </punnet> <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']"): bad.getparent().remove(bad) print et.tostring(tree, pretty_print=True) 

结果:

 <groceries> <fruit state="fresh">pear</fruit> <fruit state="fresh">starfruit</fruit> <fruit state="fresh">peach</fruit> </groceries> 

我遇到了一种情况:

 <div> <script> some code </script> text here </div> 

div.remove(script)将删除text here我不是那个意思的部分。

按照这里的答案,我发现etree.strip_elements是一个更好的解决scheme,你可以控制是否将删除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 )