如何删除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的根节点下,也可以工作。
您正在寻找remove
function。 调用树的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 )