Skip to content

Instantly share code, notes, and snippets.

@anentropic
Created October 28, 2010 17:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anentropic/651801 to your computer and use it in GitHub Desktop.
Save anentropic/651801 to your computer and use it in GitHub Desktop.
Code for better cloning of ElementTree (XML) objects in Python
import xml.etree.cElementTree as ET
"""
ripped off from:
http://effbot.python-hosting.com/file/stuff/sandbox/elementlib/clone.py
apparently this is faster than using copy.deepcopy on an ElementTree
"""
##
# Turns an element tree into a cloning factory. The callable object
# returned by this function returns copies of the original tree.
#
# @param elem An element tree.
# @return A callable factory object.
def make_factory(elem):
def generate_elem(append, elem, level):
var = "e" + str(level)
arg = repr(elem.tag)
if elem.attrib:
arg += ", **%r" % elem.attrib
if level == 1:
append(" e1 = Element(%s)" % arg)
else:
append(" %s = SubElement(e%d, %s)" % (var, level-1, arg))
if elem.text:
append(" %s.text = %r" % (var, elem.text))
if elem.tail:
append(" %s.tail = %r" % (var, elem.tail))
for e in elem:
generate_elem(append, e, level+1)
# generate code for a function that creates a tree
output = ["def element_factory():"]
generate_elem(output.append, elem, 1)
output.append(" return e1")
# setup global function namespace
namespace = {"Element": ET.Element, "SubElement": ET.SubElement}
# create function object
exec "\n".join(output) in namespace
return namespace["element_factory"]
import xml.etree.cElementTree as ET
"""
ripped off from:
http://effbot.python-hosting.com/file/stuff/sandbox/elementlib/clone.py
apparently this is faster than using copy.deepcopy on an ElementTree
"""
##
# Turns an element tree into a cloning factory. The callable object
# returned by this function returns copies of the original tree.
#
# @param elem An element tree.
# @return A callable factory object.
def make_factory(elem):
def generate_elem(append, elem, level):
var = "e" + str(level)
arg = repr(elem.tag)
if elem.attrib:
arg += ", **%r" % elem.attrib
if level == 1:
append(" e1 = Element(%s)" % arg)
else:
append(" %s = SubElement(e%d, %s)" % (var, level-1, arg))
if elem.text:
append(" %s.text = %r" % (var, elem.text))
if elem.tail:
append(" %s.tail = %r" % (var, elem.tail))
for e in elem:
generate_elem(append, e, level+1)
# generate code for a function that creates a tree
output = ["def element_factory():"]
generate_elem(output.append, elem, 1)
output.append(" return e1")
# setup global function namespace
namespace = {"Element": ET.Element, "SubElement": ET.SubElement}
# create function object
exec "\n".join(output) in namespace
return namespace["element_factory"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment