ElementTree and clone element toot

Gerard Flanagan grflanagan at gmail.com
Mon Feb 2 09:37:36 EST 2009


m.banaouas wrote:
> Hi all,
> Working with the ElementTree module, I looked for clone element function but not
> found such tool:
> 
> def CloneElment(fromElem, destRoot = None)
> fromElem is the element to clone
> destRoot is the parent element of the new element ; if None so the new element
> will be child of fromElem parent. The clone operation is recursive to make it
> process all subtree of the element to clone.
> 
> here is my first implementation:
> 
> def CloneElement(fromElem, destRoot = None):
>   if destRoot == None:
>     fromRoot = ET.ElementTree(fromElem).getroot()
>     destRoot = fromRoot
>   destElem = destRoot.makeelement(fromElem.tag, fromElem.attrib)
>   destRoot.append(destElem)
>   destElem.text = fromElem.text
>   for e in fromElem.findall('*'):
>     CloneElement(e, destElem)
> #
> this function works fine only if destRoot parameter is defined by the caller
> context. The problem is about retreiving parent element: I didn't found any way
> to determine the parent element of an element "elem" by asking elem itself!
> and ET.ElementTree(fromElem).getroot() is wrong because it returns fromElem
> itself, not its parent.
> 
> Thanks for any help.
> --
> http://mail.python.org/mailman/listinfo/python-list
> 


Maybe `dest = ET.fromstring(ET.tostring(src))` would do?

Or as follows:

from xml.etree import ElementTree as ET

s = '''
<root>
    <a name="A">text
    <b name="B"><bb name="BB">BBtext
    </bb></b>
    </a>
    <c />
    <d name="D" />
    <e>EEText</e>
</root>
'''

e = ET.fromstring(s)

def clone(elem):
     ret = elem.makeelement(elem.tag, elem.attrib)
     ret.text = elem.text
     for child in elem:
         ret.append(clone(child))
     return ret

f = clone(e)

assert ''.join(ET.tostring(e).split()) == ''.join(ET.tostring(f).split())

assert f[0].get('name') == e[0].get('name')

f[0].set('name', 'NEWNAME')

assert f[0].get('name') == 'NEWNAME'
assert f[0].get('name') != e[0].get('name')




More information about the Python-list mailing list