Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Elementtree move xml nodes using append?

I'm trying to move one set of nodes to be children of a different element.

SampleFile.xml

<root>
    <OuterNode>
        <Node>
            <Name>NodeA</Name>
        </Node>
        <Node>
            <Name>NodeB</Name>
        </Node>
        <SpecialNode>
            <Name>NodeZ</Name>
        </SpecialNode>
    </OuterNode>
</root>

Using this code, I can only get the first "Node" to move

import xml.etree.ElementTree as etree


tree = etree.parse('sampleFile.xml')
root = tree.getroot()

next_node = etree.Element('NextOuterNode')
root.append(next_node)

for parent in root:
    if parent.tag == 'OuterNode':
        for child in parent:
            if child.tag == 'Node':
                parent.remove(child)
                next_node.append(child)

After fumbling around for a while I found that this will move both nodes

outer_node = tree.find('./OuterNode')
for e in tree.findall('./OuterNode/Node'):
    next_node.append(e)
    outer_node.remove(e)

So my question is what is the difference in the iterable lists that

for child in parent

and

for e in tree.findall

generate?

like image 874
Brian Hewson Avatar asked Nov 27 '25 21:11

Brian Hewson


1 Answers

I can't say for certain (and I'm guessing the only way to definitively answer is by digging through the source), but I would guess that the difference is the first is positional and iterates through the parent and the second makes a new list and iterates through that.

Consider, when you run this:

for child in parent

If you have two elements, and it is iterating through the parent, if you remove the first element, the second becomes the first and since the loop has already done the first element, its not repeated and the looping is complete.

With the second:

for e in tree.findall

iteration through the parent isn't implemented like this (as the elements could be anywhere), so a new list of references is made. Moving these doesn't change the references, so it loops correctly.

This is all conjecture of course, but it fits with what you describe.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!