简体   繁体   中英

How do I correctly remove a child xml tag with xml.etree.elementtree?

I'm trying to remove all child tags from a xml file while keeping the parent tags intact. I have tried looping through the elements to make a list and remove them that way, but the elementtree module does not like that.

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")

I left the print function hashed out to show that I can see the correct length of the list there.

The remove call returns an error

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

Where am I going wrong? Am I oversimplifying how ElementTree removals should work?

findall return an array, thus your child is also an array. If you want to remove all the children, you have to make another loop for child as

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

According to the 19.7.1.3.of the xml package docs

Element.findall() finds only elements with a tag which are direct children of the current element. Element.find() finds the first child with a particular tag

Thus if you only have a single child, you can use find instead of findall . thus the following snipped would then be valid

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

Update with a fully working example with write to file what turns

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")

This snippet would turn

<foo>
    <parent>
        <child>
            <grandchild>
            </grandchild>
        </child>
        <child>
            <grandchild>
            </grandchild>
        </child>
        <child>
            <grandchild>
            </grandchild>
        </child>
    </parent>
    ...
</foo>

into

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM