Tricks for Writing XML with Python 3

I’ve added a Python 3 XML example to my Shocksolution_Examples repo on GitHub.  The new example shows how to generate an XML file which functions as a template for building a GUI with wxGlade.  However, this example should be helpful for anyone who needs to create XML files with Python.  The full example is on GitHub, so I’m just going to highlight a few interesting snippets.

Use the SubElement factory function to create a new Element instance and add it to an existing element. Here, I create an element called templatedata and add it to the root element. I then create another element called author and add it to templatedata.

templatedata = etree.SubElement(root, "templatedata")
author = etree.SubElement(templatedata, "author")
author.text = "Craig Finch"

ElementTree automatically takes care of closing tags, so you can add more subelements at any time.
Writing the tree to text has a couple of little twists. ElementTree doesn’t have any of pretty-printing the trees, so you must use xml.dom.minidom:

reparsed = minidom.parseString(etree.tostring(root))
print(reparsed.toprettyxml())

The tostring function is used to generate an unformatted string representation of the tree, which is then parsed by minidom to create a minidom object. This object’s toprettyxml method is used to generate a pretty-printed string. This is probably horribly inefficient, so it’s mostly useful for debugging.
When writing the XML to a file, the pretty formatting is unnecessary if it’s only going to be read by another program. I used the tostring function from ElementTree, which returns an object of class bytes. The object needs to be decoded before it can be printed or written to a file, which is handled by the decode method:

f.write(etree.tostring(root, encoding='utf-8').decode('utf-8'))

I give credit to Eli Bendersky’s Python ElementTree XML tutorial and Doug Hellmann’s post about how to pretty-print an ElementTree.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.