Python – lxml: Modify the tree in place

lxml: Modify the tree in place… here is a solution to the problem.

lxml: Modify the tree in place

I have this simple feature to add new elements when they are missing :

def add_missing(root):
    """ Add missing elements and return `root` """
    for tag, missing_el in missing_tags.items():
        for elem in root.iterfind(".//" + tag):
            if elem.find(missing_el.tag) is None:
                elem.append(missing_el)
                print tostring(elem)
    print tostring(root)
    return root

However, when I checked if root contains the missing element, I found that only the last element contained the newly added element.

Can someone point to a way to modify etree while iterating?

Solution

Adding the same element in a different position on the tree only moves that element. Solved this problem using deepcopy:

from copy import deepcopy
def add_missing(root):
    """ Add missing elements and return `root` """
    for tag, missing_el in missing_tags.items():
        for elem in root.findall(".//" + tag):
            if elem.find(missing_el.tag) is None:
                elem.append(deepcopy(missing_el))
                print tostring(elem)
    print tostring(root)
    return root

Related Problems and Solutions