How to write XML declaration using xml.etree.ElementTree

I am generating an XML document in Python using an ElementTree, but the tostring function doesn't include an XML declaration when converting to plaintext.

from xml.etree.ElementTree import Element, tostring

document = Element('outer')
node = SubElement(document, 'inner')
node.NewValue = 1
print tostring(document)  # Outputs "<outer><inner /></outer>"

I need my string to include the following XML declaration:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

However, there does not seem to be any documented way of doing this.

Is there a proper method for rendering the XML declaration in an ElementTree?


I am surprised to find that there doesn't seem to be a way with ElementTree.tostring(). You can however use ElementTree.ElementTree.write() to write your XML document to a fake file:

from io import BytesIO
from xml.etree import ElementTree as ET

document = ET.Element('outer')
node = ET.SubElement(document, 'inner')
et = ET.ElementTree(document)

f = BytesIO()
et.write(f, encoding='utf-8', xml_declaration=True) 
print(f.getvalue())  # your XML file, encoded as UTF-8

See this question. Even then, I don't think you can get your 'standalone' attribute without writing prepending it yourself.


I would use lxml (see http://lxml.de/api.html).

Then you can:

from lxml import etree
document = etree.Element('outer')
node = etree.SubElement(document, 'inner')
print(etree.tostring(document, xml_declaration=True))

If you include the encoding='utf8', you will get an XML header:

xml.etree.ElementTree.tostring writes a XML encoding declaration with encoding='utf8'

Sample Python code (works with Python 2 and 3):

import xml.etree.ElementTree as ElementTree

tree = ElementTree.ElementTree(
    ElementTree.fromstring('<xml><test>123</test></xml>')
)
root = tree.getroot()

print('without:')
print(ElementTree.tostring(root, method='xml'))
print('')
print('with:')
print(ElementTree.tostring(root, encoding='utf8', method='xml'))

Python 2 output:

$ python2 example.py
without:
<xml><test>123</test></xml>

with:
<?xml version='1.0' encoding='utf8'?>
<xml><test>123</test></xml>

With Python 3 you will note the b prefix indicating byte literals are returned (just like with Python 2):

$ python3 example.py
without:
b'<xml><test>123</test></xml>'

with:
b"<?xml version='1.0' encoding='utf8'?>\n<xml><test>123</test></xml>"

xml_declaration Argument

Is there a proper method for rendering the XML declaration in an ElementTree?

YES, and there is no need of using .tostring function. According to ElementTree Documentation, you should create an ElementTree object, create Element and SubElements, set the tree's root, and finally use xml_declaration argument in .write function, so the declaration line is included in output file.

You can do it this way:

import xml.etree.ElementTree as ET

tree = ET.ElementTree("tree")

document = ET.Element("outer")
node1 = ET.SubElement(document, "inner")
node1.text = "text"

tree._setroot(document)
tree.write("./output.xml", encoding = "UTF-8", xml_declaration = True)  

And the output file is:

<?xml version='1.0' encoding='UTF-8'?>
<outer><inner>text</inner></outer>