Python 如何使用xml.etree.elementtree正确删除子xml标记?
我试图从xml文件中删除所有子标记,同时保持父标记不变。我已经尝试通过循环元素来创建一个列表,并以这种方式删除它们,但是elementtree模块不喜欢这样Python 如何使用xml.etree.elementtree正确删除子xml标记?,python,python-3.x,xml,elementtree,Python,Python 3.x,Xml,Elementtree,我试图从xml文件中删除所有子标记,同时保持父标记不变。我已经尝试通过循环元素来创建一个列表,并以这种方式删除它们,但是elementtree模块不喜欢这样 import xml.etree.ElementTree as ET tree = ET.parse("myfile") root = tree.getroot() for parent in root.find('parent'): child = parent.findall('child') #print(
import xml.etree.ElementTree as ET
tree = ET.parse("myfile")
root = tree.getroot()
for parent in root.find('parent'):
child = parent.findall('child')
#print(len(child))
root.remove(child)
tree.write("myfile")
我将print函数散列出来,以显示我可以在那里看到列表的正确长度
remove调用返回一个错误
TypeError: remove() argument must be xml.etree.ElementTree.Element, not list
我哪里做错了?我是否过分简化了ElementTree删除的工作方式?
findall
返回一个数组,因此您的子项也就是一个数组。如果要删除所有子项,则必须为child
as创建另一个循环
for parent in root.findall('parent'):
children = parent.findall('child')
for child in children:
root.remove(child)
根据
findall()只查找带有直接标记的元素
当前元素的子元素。find()查找第一个子元素
带有特定标签
因此,如果您只有一个孩子,您可以使用find
而不是findall
。
因此,以下截取的内容将是有效的
for parent in root.find('parent'):
child = parent.find('child')
parent.remove(child)
更新一个完整的工作示例,其中包含写入文件的内容
import xml.etree.ElementTree as ET
tree = ET.parse("test.xml")
root = tree.getroot()
for parent in root.findall('parent'):
children = parent.findall('child')
for child in children:
parent.remove(child)
tree.write("test1.xml")
这个片段会变成
<foo>
<parent>
<child>
<grandchild>
</grandchild>
</child>
<child>
<grandchild>
</grandchild>
</child>
<child>
<grandchild>
</grandchild>
</child>
</parent>
...
</foo>
...
进入
...
谢谢。循环似乎可以正常工作,因为它将无错误运行,并且xml文件指示在进行更改时需要重新加载它。但是,在重新加载时,实际上没有发生任何更改。您知道python如何处理文件更改吗?我们是否将更改存储在内存中,并在重写之前将其丢失?我添加了一个完全工作的代码示例,可以满足您的需要,并在答案中更新了代码示例。为了回答您的问题,xml模块将整个文件加载到树变量中(如果xml无效,则引发异常)。文件中的remove()
方法可能无法找到要删除的正确元素,因此文件中的最终输出不会更改。write
方法仍然更新了文件,即使内容相同,因此尽管没有得到所需的结果,仍然会通知您该文件已更改。如果我在父级和子级上使用findall(),则会得到ValueError:list.remove(x):x not in list
。我在循环中添加了类似这样的内容,虽然True:try:root.remove(child)except:break
删除了该错误,但文件仍然没有更新。我认为我不必在root.find(“./root/祖父母/祖父母/父母”)中为父项显式设置位置,例如。是这样吗?
<foo>
<parent>
</parent>
...
</foo>