Note
Nevermind, this has been fixed in lxml.
lxml has a very nice element builder though it doesn't seem to work with CDATA objects:
>>> from lxml.builder import E
>>> from lxml.etree import CDATA
>>> E.stuff(CDATA('Some stuff that needs to be in a CDATA section'))
Traceback (most recent call last):
File "<ipython-input-4-40103024e8d8>", line 1, in <module>
E.stuff(CDATA('Some stuff that needs to be in a CDATA section'))
File "/usr/lib/python2.7/dist-packages/lxml/builder.py", line 220, in __call__
raise TypeError("bad argument type: %r" % item)
TypeError: bad argument type: <lxml.etree.CDATA object at 0x238a130>
To fix it, do this:
from lxml.builder import ElementMaker
from lxml.etree import CDATA
def add_cdata(element, cdata):
assert not element.text, "Can't add a CDATA section. Element already has some text: %r" % element.text
element.text = cdata
E = ElementMaker(typemap={
CDATA: add_cdata
})
Then everything works as expected:
>>> from lxml import etree
>>> etree.tostring(E.stuff(CDATA('Some stuff that needs to be in a CDATA section')))
'<stuff><![CDATA[Some stuff that needs to be in a CDATA section]]></stuff>'