下面有一个XMl文件。我希望能够删除所有未被称为john的子计划并输出到新文件。
<data>
<plan_main>
<plan>
<name>John</name>
<id>1</id>
</plan>
<plan>
<name>Charlie</name>
<id>2</id>
</plan>
</plan_main>
<location>
<country>
<code>GB</code>
</country>
<country>
<code>DE</code>
</country>
</location>
</data>
我已经尝试了以下代码,但获得了ValueError Not in list
for plan in root.findall('./plan_main/plan'):
name = plan.find('name').text
if name =! "john":
root.remove(plan)
tree.write('output.xml')
我希望我的输出文件看起来像这样:
<data>
<plan_main>
<plan>
<name>John</name>
<id>1</id>
</plan>
</plan_main>
<location>
<country>
<code>GB</code>
</country>
<country>
<code>DE</code>
</country>
</location>
</data>
但是我收到以下错误:
ValueError: list.remove(x): x not in list
答案 0 :(得分:2)
假设=!
只是一个复制/粘贴错误。问题是您尝试使用Element.remove()
方法从root
节点中删除元素,但.remove()
只会删除root
的直接子元素。
如果您想使用ElementTree
本身,可以将XPath更改为循环遍历所有plan_main
元素,然后针对每个plan_main
元素循环遍历其所有子元素,并且如果有任何孩子的姓名不是john
,请将其删除。实施例 -
for plan_main in root.findall('./plan_main'):
for plan in plan_main:
name = plan.find('name').text
if name.lower() != "john":
plan_main.remove(plan)
演示 -
>>> import xml.etree.ElementTree as ET
>>> s = """ <data>
... <plan_main>
... <plan>
... <name>John</name>
... <id>1</id>
... </plan>
... <plan>
... <name>Charlie</name>
... <id>2</id>
... </plan>
... </plan_main>
... <location>
... <country>
... <code>GB</code>
... </country>
... <country>
... <code>DE</code>
... </country>
... </location>
... </data>"""
>>> root = ET.fromstring(s)
>>> for plan_main in root.findall('./plan_main'):
... for plan in plan_main:
... name = plan.find('name').text
... if name.lower() != "john":
... plan_main.remove(plan)
...
>>> print(ET.tostring(root).decode('utf-8'))
<data>
<plan_main>
<plan>
<name>John</name>
<id>1</id>
</plan>
</plan_main>
<location>
<country>
<code>GB</code>
</country>
<country>
<code>DE</code>
</country>
</location>
</data>
如果您可以使用lxml.etree
,则可以使用.getparent()
方法获取要删除的子项的直接父级,从而对代码进行少量更改以使其正常工作。示例 -
for plan in root.findall('./plan_main/plan'):
name = plan.find('name').text
if name.lower() != "john":
plan.getparent().remove(plan)