Element objects have no .getroot() method. Drop that call, and the .tostring() call works:

xmlstr = ElementTree.tostring(et, encoding='utf8')

You only need to use .getroot() if you have an ElementTree instance.

Other notes:

  • This produces a bytestring, which in Python 3 is the bytes type.
    If you must have a str object, you have two options:

    1. Decode the resulting bytes value, from UTF-8: xmlstr.decode("utf8")

    2. Use encoding='unicode'; this avoids an encode / decode cycle:

      xmlstr = ElementTree.tostring(et, encoding='unicode')
      
  • If you wanted the UTF-8 encoded bytestring value or are using Python 2, take into account that ElementTree doesn't properly detect utf8 as the standard XML encoding, so it'll add a <?xml version='1.0' encoding='utf8'?> declaration. Use utf-8 or UTF-8 (with a dash) if you want to prevent this. When using encoding="unicode" no declaration header is added.

Answer from Martijn Pieters on Stack Overflow
Top answer
1 of 6
188

Element objects have no .getroot() method. Drop that call, and the .tostring() call works:

xmlstr = ElementTree.tostring(et, encoding='utf8')

You only need to use .getroot() if you have an ElementTree instance.

Other notes:

  • This produces a bytestring, which in Python 3 is the bytes type.
    If you must have a str object, you have two options:

    1. Decode the resulting bytes value, from UTF-8: xmlstr.decode("utf8")

    2. Use encoding='unicode'; this avoids an encode / decode cycle:

      xmlstr = ElementTree.tostring(et, encoding='unicode')
      
  • If you wanted the UTF-8 encoded bytestring value or are using Python 2, take into account that ElementTree doesn't properly detect utf8 as the standard XML encoding, so it'll add a <?xml version='1.0' encoding='utf8'?> declaration. Use utf-8 or UTF-8 (with a dash) if you want to prevent this. When using encoding="unicode" no declaration header is added.

2 of 6
81

How do I convert ElementTree.Element to a String?

For Python 3:

xml_str = ElementTree.tostring(xml, encoding='unicode')

For Python 2:

xml_str = ElementTree.tostring(xml, encoding='utf-8')

Example usage (Python 3)

from xml.etree import ElementTree

xml = ElementTree.Element("Person", Name="John")
xml_str = ElementTree.tostring(xml, encoding='unicode')
print(xml_str)

Output:

<Person Name="John" />

Explanation

ElementTree.tostring() returns a bytestring by default in Python 2 & 3. This is an issue because Python 3 switched to using Unicode for strings.

In Python 2 you could use the str type for both text and binary data. Unfortunately this confluence of two different concepts could lead to brittle code which sometimes worked for either kind of data, sometimes not. [...]

To make the distinction between text and binary data clearer and more pronounced, [Python 3] made text and binary data distinct types that cannot blindly be mixed together.

Source: Porting Python 2 Code to Python 3

If you know what version of Python is being used, you should specify the encoding as unicode or utf-8. For reference, I've included a comparison of .tostring() results between Python 2 and Python 3.

ElementTree.tostring(xml)
# Python 3: b'<Person Name="John" />'
# Python 2: <Person Name="John" />

ElementTree.tostring(xml, encoding='unicode')
# Python 3: <Person Name="John" />
# Python 2: LookupError: unknown encoding: unicode

ElementTree.tostring(xml, encoding='utf-8')
# Python 3: b'<Person Name="John" />'
# Python 2: <Person Name="John" />

ElementTree.tostring(xml).decode()
# Python 3: <Person Name="John" />
# Python 2: <Person Name="John" />

Note: While xml_str = ElementTree.tostring().decode() is compatible with both Python 2 & 3, Christopher Rucinski pointed out that this method fails when dealing with non-Latin characters).

Thanks to Martijn Peters for pointing out that the str datatype changed between Python 2 and 3.


Why not use str()?

In most scenarios, using str() would be the "canonical" way to convert an object to a string. However, using str() with Element returns the object's location in memory as a hexstring, rather than a string representation of the object's data.

from xml.etree import ElementTree

xml = ElementTree.Element("Person", Name="John")
print(str(xml))  # <Element 'Person' at 0x00497A80>
🌐
lxml
lxml.de › tutorial.html
The lxml.etree Tutorial
Serialisation commonly uses the tostring() function that returns a string, or the ElementTree.write() method that writes to a file, a file-like object, or a URL (via FTP PUT or HTTP POST).
🌐
Python
docs.python.org › 3 › library › xml.etree.elementtree.html
xml.etree.ElementTree — The ElementTree XML API
January 29, 2026 - Source code: Lib/xml/etree/ElementTree.py The xml.etree.ElementTree module implements a simple and efficient API for parsing and creating XML data. Tutorial: This is a short tutorial for using xml....
🌐
GitHub
github.com › python › cpython › issues › 77742
Add .tostring() method to xml.etree.ElementTree.Element · Issue #77742 · python/cpython
May 17, 2018 - Add .tostring() method to xml.etree.ElementTree.Element#77742 · Copy link · Labels · topic-XMLtype-featureA feature request or enhancementA feature request or enhancement · stevoisiakmannequin · opened · on May 17, 2018 · Issue body actions · BPO · 33561 ·
Published   May 17, 2018
Author   stevoisiak
🌐
DataCamp
datacamp.com › tutorial › python-xml-elementtree
Python XML Tutorial: Element Tree Parse & Read | DataCamp
December 10, 2024 - Since ElementTree is a powerful library that can interpret more than just XML. You must specify both the encoding and decoding of the document you are displaying as the string. For XMLs, use 'utf8' - This is the typical document format for an XML. print(ET.tostring(root, encoding='utf8').decode('utf8'))
🌐
Snyk
snyk.io › advisor › defusedxml › functions › defusedxml.elementtree.tostring
How to use the defusedxml.ElementTree.tostring function in defusedxml | Snyk
@staticmethod def _get_raw_xml(data, path): xml = data.find(path) if xml is not None: return ElementTree.tostring(xml, encoding="utf-8") else: return ""
🌐
ProgramCreek
programcreek.com › python › example › 56001 › xml.etree.ElementTree.tostring
Python Examples of xml.etree.ElementTree.tostring
def _generate_chat(self, to, from_, body): data = _FormData() data.add_text('from', from_, 'plain') data.add_text('to', to, 'plain') data.add_text('body', body, 'plain') message_element = ElementTree.Element( ElementTree.QName('jabber:client', 'message'), {'from': from_, 'to': to, 'type': 'chat'}) body_element = ElementTree.SubElement( message_element, ElementTree.QName('jabber:client', 'body')) body_element.text = body data.add_text('stanza', ElementTree.tostring(message_element, encoding='utf-8'), 'xml') return data
Find elsewhere
🌐
Python
bugs.python.org › issue10942
Issue 10942: xml.etree.ElementTree.tostring returns type bytes, expected type str - Python tracker
This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/55151
🌐
GitHub
gist.github.com › jack-zheng › e5e0613b8f048a46c123d7884561be2f
python ElementTree's tostring method return byte instead of string · GitHub
python ElementTree's tostring method return byte instead of string · Raw · python ElementTree.tostring method.md · take care when user this method, only if the encoding of this method is unicode, it will return str else byte will be back. ...
Top answer
1 of 2
22

This should work:-

xmlstr = ET.tostring(root, encoding='utf8', method='xml')
2 of 2
10

How do I convert ElementTree.Element to a String?

For Python 3:

xml_str = ElementTree.tostring(xml, encoding='unicode')

For Python 2:

xml_str = ElementTree.tostring(xml, encoding='utf-8')

For compatibility with both Python 2 & 3:

xml_str = ElementTree.tostring(xml).decode()

Example usage

from xml.etree import ElementTree

xml = ElementTree.Element("Person", Name="John")
xml_str = ElementTree.tostring(xml).decode()
print(xml_str)

Output:

<Person Name="John" />

Explanation

Despite what the name implies, ElementTree.tostring() returns a bytestring by default in Python 2 & 3. This is an issue in Python 3, which uses Unicode for strings.

In Python 2 you could use the str type for both text and binary data. Unfortunately this confluence of two different concepts could lead to brittle code which sometimes worked for either kind of data, sometimes not. [...]

To make the distinction between text and binary data clearer and more pronounced, [Python 3] made text and binary data distinct types that cannot blindly be mixed together.

Source: Porting Python 2 Code to Python 3

If we know what version of Python is being used, we can specify the encoding as unicode or utf-8. Otherwise, if we need compatibility with both Python 2 & 3, we can use decode() to convert into the correct type.

For reference, I've included a comparison of .tostring() results between Python 2 and Python 3.

ElementTree.tostring(xml)
# Python 3: b'<Person Name="John" />'
# Python 2: <Person Name="John" />

ElementTree.tostring(xml, encoding='unicode')
# Python 3: <Person Name="John" />
# Python 2: LookupError: unknown encoding: unicode

ElementTree.tostring(xml, encoding='utf-8')
# Python 3: b'<Person Name="John" />'
# Python 2: <Person Name="John" />

ElementTree.tostring(xml).decode()
# Python 3: <Person Name="John" />
# Python 2: <Person Name="John" />

Thanks to Martijn Peters for pointing out that the str datatype changed between Python 2 and 3.


Why not use str()?

In most scenarios, using str() would be the "cannonical" way to convert an object to a string. Unfortunately, using this with Element returns the object's location in memory as a hexstring, rather than a string representation of the object's data.

from xml.etree import ElementTree

xml = ElementTree.Element("Person", Name="John")
print(str(xml))  # <Element 'Person' at 0x00497A80>
🌐
Python
bugs.python.org › issue33561
Issue 33561: Add .tostring() method to xml.etree.ElementTree.Element - Python tracker
May 17, 2018 - This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/77742
🌐
HotExamples
python.hotexamples.com › examples › xml.etree › ElementTree › tostring › python-elementtree-tostring-method-examples.html
Python ElementTree.tostring Examples, xml.etree.ElementTree.tostring Python Examples - HotExamples
def _write_root_tag_open(self): repomd_attributes = {'xmlns': REPO_XML_NAME_SPACE, 'xmlns:rpm': RPM_XML_NAME_SPACE} repomd_element = ElementTree.Element('repomd', repomd_attributes) revision_element = ElementTree.SubElement(repomd_element, 'revision') revision_element.text = str(int(time.time())) bogus_element = ElementTree.SubElement(repomd_element, '') repomd_element_string = ElementTree.tostring(repomd_element, 'utf-8') bogus_element_string = ElementTree.tostring(bogus_element, 'utf-8') opening_tag, closing_tag = repomd_element_string.split(bogus_element_string, 1) self.metadata_file_handle.write(opening_tag + '\n') # Setup the corresponding _write_root_tag_close as a closure def _write_root_tag_close_closure(*args): self.metadata_file_handle.write(closing_tag + '\n') self._write_root_tag_close = _write_root_tag_close_closure ·
🌐
Runebook.dev
runebook.dev › en › docs › python › library › xml.etree.elementtree › xml.etree.ElementTree.tostring
From Element to String: Troubleshooting Python's tostring() Function
By default, tostring() returns a byte string (bytes type), which can look like b'<root><child/></root>'. If you need a regular Unicode string (str type) for printing or further text manipulation, you'll need to handle the decoding.
🌐
Read the Docs
stackless.readthedocs.io › en › 3.7-slp › library › xml.etree.elementtree.html
xml.etree.ElementTree — The ElementTree XML API — Stackless-Python 3.7.9 documentation
August 8, 2021 - Use encoding="unicode" to generate a Unicode string (otherwise, a bytestring is generated). method is either "xml", "html" or "text" (default is "xml"). short_empty_elements has the same meaning as in ElementTree.write(). Returns a list of (optionally) encoded strings containing the XML data. It does not guarantee any specific sequence, except that b"".join(tostringlist(element)) == tostring(element).
🌐
Readthedocs
ironpython-test.readthedocs.io › en › latest › library › xml.etree.elementtree.html
19.13. xml.etree.ElementTree — The ElementTree XML API — IronPython 2.7.2b1 documentation
Returns a list of encoded strings containing the XML data. It does not guarantee any specific sequence, except that "".join(tostringlist(element)) == tostring(element). New in version 2.7. xml.etree.ElementTree.XML(text, parser=None)¶ · Parses an XML section from a string constant.
🌐
GitHub
github.com › python › cpython › issues › 91810
ElementTree should use UTF-8 for xml declaration. · Issue #91810 · python/cpython
April 22, 2022 - $ LANG=ja_JP.eucJP ./python.exe Python 3.11.0a7+ (heads/bytes-alloc-dirty:7fbc7f6128, Apr 19 2022, 16:53:54) [Clang 12.0.0 (clang-1200.0.32.29)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import xml.etree.ElementTree as ET >>> et = ET.fromstring("<t>hello</t>") >>> ET.tostring(et, encoding="unicode", xml_declaration=True) "<?xml version='1.0' encoding='eucJP'?>\n<t>hello</t>" Code: cpython/Lib/xml/etree/ElementTree.py ·
Author   methane
🌐
GitHub
github.com › python › cpython › issues › 80408
Add default_namespace argument to xml.etree.ElementTree.tostring() · Issue #80408 · python/cpython
March 7, 2019 - assignee = None closed_at = <Date 2019-04-14.08:16:04.080> created_at = <Date 2019-03-07.18:57:14.191> labels = ['expert-XML', '3.8', 'type-feature', 'library'] title = 'Add default_namespace argument to xml.etree.ElementTree.tostring()' updated_at = <Date 2019-04-14.08:16:04.070> user = 'https://github.com/codeape2'
Published   Mar 07, 2019
🌐
GitHub
github.com › python › cpython › issues › 113581
ElementTree.tostring(..., default_namespace=...) incorrectly strips namespace from attributes · Issue #113581 · python/cpython
December 30, 2023 - import xml.etree.ElementTree as ET foo = ET.Element('{http://example.com}foo', {'{http://example.com}baz': '1234'}) # Expected output: <foo xmlns="http://example.com" xmlns:ns0="http://example.com" ns0:baz="1234" /> # Prints: <foo xmlns="http://example.com" baz="1234" /> print(ET.tostring(foo, default_namespace='http://example.com', encoding="unicode"))
Author   hexagonrecursion