Simplify the code when creating XHTML or XML hierarchies with ElementTree.
Usually, I have code like this:
table = ET.SubElement(body, 'table')
table.attrib['border'] = '1'
tr = ET.SubElement(table, 'tr')
ET.SubElement(tr, 'td').text = 'some text'
Using Python's __getattr__ and partial function evaluation allows to create an object that will yield a much simplified syntax.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import xml.etree.ElementTree as ET
import functools
class XMLMaker(object):
def __getattr__(self, _name):
return functools.partial(self.make_node, _name)
def make_node(self, _name, node, **kwargs):
node = ET.SubElement(node, _name)
for (key, value) in kwargs.items():
if key == 'text':
node.text = value
else:
node.attrib[key] = value
return node
|
To create the same structure as above, I can write:
xm = XMLMaker()
table = xm.table(body, border='1')
tr = xm.tr(table)
xm.td(tr, text='some text')
Saves some typing and makes the code clearer in my opinion.
Tags: xml
If you're using lxml, you can get similar behavior from lxml.builder.E, albeit in a bottom-up instead of top-down direction:
Or just
The main difference is that the args to E are the contents of the element, not the parent.
Nice! I tend to prefer the top-down approach, maybe just because I'm now used to thinking this way. And lxml does not come standard with ActivePython, ElementTree does.