如何使用xml.etree.elementtree正确删除子xml标签?

时间:2019-12-03 01:21:53

标签: 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(len(child))
    root.remove(child)

tree.write("myfile")

我将打印函数保留了一定的哈希值,以表明可以在那里看到正确的列表长度。

remove调用返回错误

TypeError: remove() argument must be xml.etree.ElementTree.Element, not list

我要去哪里错了?我是否简化了ElementTree删除的工作方式?

1 个答案:

答案 0 :(得分:1)

findall返回一个数组,因此您的child也是一个数组。如果要删除所有子项,则必须为child作另外一个循环

for parent in root.findall('parent'):
    children = parent.findall('child')
    for child in children:
        root.remove(child)

根据19.7.1.3. of the xml package docs

  

Element.findall()仅查找带有标签的直接元素   当前元素的子元素。 Element.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>

进入

<foo>
    <parent>
        </parent>
    ...
</foo>