If you are building a lot of XML, it can be somewhat cumbersome to take several lines of code to build a single element. For elements with text content, you'll write a lot of two-line sequences like this:
mainTitle = et.Element('h1')
mainTitle.text = "Welcome to Your Title Here!"
The brilliant and productive Fredrik Lundh has written a
very nice module called builder.py that makes building
XML a lot easier.
See Lundh's original page, An ElementTree
Builder, for an older version of
his module, with documentation and examples.
You may wish to use the current version of builder.py
from Lundh's SVN repository page.
The author has written a modified version based heavily
on Lundh's version. The source for this
etbuilder.py module is available online.
For the instructions for use of the author's version,
see Section 12.1, “Using the etbuilder module”.
For the actual implementation in lightweight literate programming
form, see Section 13, “Implementation of etbuilder”.
Instead of importing the ElementTree
package as et, use this importation:
from etbuilder import et, E
The name E is a factory object that
creates et.Element instances.
Here is the calling sequence for E:
E(tag, *p, **kw)
The first argument, , is the element's name as a string.
The return value is a new taget.Element
instance.
You can supply any number of positional
arguments ,
followed by any number of keyword arguments. The
interpretation of each argument depends on its type. The
displays with “p>>>”
prompts are interactive examples.
Any keyword argument of the form “” becomes an XML
attribute “name=value” of the new element.
name='value'
>>> colElt=E('col', valign='top', align='left')
>>> et.tostring(colElt)
'<col align="left" valign="top" />'
String arguments are added to the content of the tag.
>>> p14 = E("p", "Welcome to ", "Your Paragraph Here.")
>>> et.tostring(p14)
'<p>Welcome to Your Paragraph Here.</p>'
An argument of type int is converted
to a string and added to the tag's content.
If you pass a dictionary to the factory, its members also become XML attributes. For instance, you might create an XHTML table cell element like this:
>>> cell = E('td', {'valign': 'top', 'align': 'right'}, 14)
>>> et.tostring(cell)
'<td align="right" valign="top">14</td>'
You can pass in an et.Element
instance, and it becomes a child element of the
element being built. This allows you to nest calls
within calls, like this:
>>> head = E('head',
... E('title', 'Your Page Title Here'),
... E('link', rel='stylesheet', href='/tcc/style.css'))
>>> print et.tostring(head, pretty_print=True)
<head>
<title>Your Page Title Here</title>
<link href="/tcc/style.css" rel="stylesheet" />
</head>
This module has one more nice wrinkle. If the name of
the tag you are creating is also a valid Python name, you
can use that name as the name of a method call on the
E instance. That is,
E.name(...)
is functionally equivalent to
E("name", ...)
Here is an example:
>>> head = E.head(
... E.title('Your title'),
... E.link(rel='stylesheet', href='/tcc/style.css'))
>>> print et.tostring(head, pretty_print=True)
<head>
<title>Your title</title>
<link href="/tcc/style.css" rel="stylesheet" />
</head>