这里是Python菜鸟。想知道 remove 所有
profile
属性值为 updated
的“true
”标签的最干净、最好的方法是什么。
我尝试了以下代码,但它抛出:SyntaxError(“不能在元素上使用绝对路径”)
root.remove(root.findall("//Profile[@updated='true']"))
XML:
<parent>
<child type="First">
<profile updated="true">
<other> </other>
</profile>
</child>
<child type="Second">
<profile updated="true">
<other> </other>
</profile>
</child>
<child type="Third">
<profile>
<other> </other>
</profile>
</child>
</parent>
如果您使用
xml.etree.ElementTree
,您应该使用 remove()
方法来删除节点,但这需要您有父节点引用。因此,解决方案:
import xml.etree.ElementTree as ET
data = """
<parent>
<child type="First">
<profile updated="true">
<other> </other>
</profile>
</child>
<child type="Second">
<profile updated="true">
<other> </other>
</profile>
</child>
<child type="Third">
<profile>
<other> </other>
</profile>
</child>
</parent>"""
root = ET.fromstring(data)
for child in root.findall("child"):
for profile in child.findall(".//profile[@updated='true']"):
child.remove(profile)
print(ET.tostring(root))
打印:
<parent>
<child type="First">
</child>
<child type="Second">
</child>
<child type="Third">
<profile>
<other> </other>
</profile>
</child>
</parent>
请注意,使用
lxml.etree
这会更简单一些:
root = ET.fromstring(data)
for profile in root.xpath(".//child/profile[@updated='true']"):
profile.getparent().remove(profile)
其中
ET
是:
import lxml.etree as ET
我寻找一种使用内置
xml
库直接寻址要删除的元素的方法。解决办法如下:
import itertools
from xml.etree import ElementTree
def removeall(root: ElementTree.Element, match, namespaces=None):
parent_by_child=dict(itertools.chain.from_iterable(
((child, element) for child in element) for element in root.iter()))
for element in root.findall(match, namespaces):
parent_by_child[element].remove(element)
应用于您的数据:
data = """
<parent>
<child type="First">
<profile updated="true">
<other> </other>
</profile>
</child>
<child type="Second">
<profile updated="true">
<other> </other>
</profile>
</child>
<child type="Third">
<profile>
<other> </other>
</profile>
</child>
</parent>"""
root = ElementTree.fromstring(data)
removeall(root, "./child/profile[@updated='true']")
print(ElementTree.tostring(root, encoding='unicode'))
打印:
<parent>
<child type="First">
</child>
<child type="Second">
</child>
<child type="Third">
<profile>
<other> </other>
</profile>
</child>
</parent>
由于问题标有python2.7:我需要承认,我不知道我用来构建child-parent-dict的
itertools.chain.from_iterable
是否已经存在于python2.7中。