I simply solved it with the indent() function:

xml.etree.ElementTree.indent(tree, space=" ", level=0) Appends whitespace to the subtree to indent the tree visually. This can be used to generate pretty-printed XML output. tree can be an Element or ElementTree. space is the whitespace string that will be inserted for each indentation level, two space characters by default. For indenting partial subtrees inside of an already indented tree, pass the initial indentation level as level.

tree = ET.ElementTree(root)
ET.indent(tree, space="\t", level=0)
tree.write(file_name, encoding="utf-8")

Note, the indent() function was added in Python 3.9.

Answer from Rafal.Py on Stack Overflow
Discussions

Proper indentation for XML files
I'm not sure if there is one correct way to add indentation to the XML files, but it works. You can use that before saving the XML files. If there are some other features you'd want to use in XML file handling but are not present in the built in xml APIs of Python, you can use lxml, a third party module. More on reddit.com
🌐 r/PythonLearning
1
4
April 8, 2025
Pretty printing XML in Python - Stack Overflow
etree.XMLParser(remove_blank_text=True) sometime can help to do the right printing 2017-10-15T09:02:32.067Z+00:00 ... Another solution is to borrow this indent function, for use with the ElementTree library that's built in to Python since 2.5. More on stackoverflow.com
🌐 stackoverflow.com
inserting newlines in xml file generated via xml.etree.ElementTree in python - Stack Overflow
I have created a xml file using xml.etree.ElementTree in python. I then use ... But when I open filename using a text editor, there are no newlines between the tags. Everything is one big line · How can I write out the document in a "pretty printed" format so that there are new lines (and hopefully indentations ... More on stackoverflow.com
🌐 stackoverflow.com
python - ElementTree : insert method and bad indentation output - Stack Overflow
As of Python 3.9, a new method named indent() has been added to xml.etree.ElementTree, which can be used to generate pretty-printed XML output without using another module or library. More on stackoverflow.com
🌐 stackoverflow.com
🌐
GitHub
github.com › BalzGuenat › CustomThreads › issues › 1
module 'xml.etree.ElementTree' has no attribute 'indent' · Issue #1 · BalzGuenat/CustomThreads
October 27, 2020 - When I try to run the code using pycharm with anaconda I get the following error: Traceback (most recent call last): File "C:/Users/berke/Downloads/CustomThreads-master/main.py", line 119, in ET.indent(tree) AttributeError: module 'xml.e...
Author   berkeoznalbant
🌐
Reddit
reddit.com › r/pythonlearning › proper indentation for xml files
r/PythonLearning on Reddit: Proper indentation for XML files
April 8, 2025 -

I'm working on a Python script that reads data from an Excel file and generates individual XML files based on each valid row. The script extracts various fields, handles date formatting, and builds a structured XML tree for each record. For certain entries, I also include duplicate tags with additional details (e.g., a second <Description> tag with a formatted date).

Now, I want the XML output to be properly indented for readability. I came across xml.etree.ElementTree.indent(tree, space=' ', level=0) as a possible way to format the XML. Is this the correct and recommended method to add indentation to the XML files I'm creating? If so, where exactly in my code should I use it for best results? Also im pretty new to python, like this would be my first time doing something on python apart from v basic code in the past. If anyone knows some resources that they think could help, i would really appreciate that too. Any help is appreciated :)

🌐
TutorialsPoint
tutorialspoint.com › pretty-printing-xml-in-python
Pretty Printing XML in Python
July 25, 2023 - Parse the XML string: Inside the `pretty_print_xml_elementtree` function, we use the `ET.fromstring()` method to parse the XML string and create an ElementTree object. Indent the XML: We call the `indent()` function on the root element of the XML to add the indentation recursively to all elements.
🌐
Oulub
oulub.com › en-US › Python › library.xml.etree.elementtree-xml.etree.ElementTree.indent
xml.etree.ElementTree.indent(tree, space=" ", level=0)... - Multilingual Manual - OULUB
December 11, 2024 - Appends whitespace to the subtree to indent the tree visually. This can be used to generate pretty-printed XML output. tree can be an Element or ElementTree. space is the whitespace string that will be inserted for each indentation level, two space characters by default.
🌐
Python Forum
python-forum.io › thread-40129.html
xml indent SubElements (wrapping) with multiple strings
(I updated the code with comments) Hi everyone, I am creating an xml file with python using xml.etree.ElementTree. In input I have a docx, where the titles are formatted like 'Header1' and the paragraphs under the title will be the text of the title...
Find elsewhere
🌐
lxml
lxml.de › tutorial.html
The lxml.etree Tutorial
This is a tutorial on XML processing with lxml.etree. It briefly overviews the main concepts of the ElementTree API, and some simple enhancements that make your life as a programmer easier.
Top answer
1 of 7
99

UPDATE 2022 - python 3.9 and later versions

For python 3.9 and later versions the standard library includes xml.etree.ElementTree.indent:

Example:

import xml.etree.ElementTree as ET

root = ET.fromstring("""<fruits><fruit>banana</fruit><fruit>apple</fruit></fruits>""")
tree = ET.ElementTree(root)
    
ET.indent(tree, '  ')
# writing xml
tree.write("example.xml", encoding="utf-8", xml_declaration=True)

Thanks Michał Krzywański for this update!

BEFORE python 3.9

I found a new way to avoid new libraries and reparsing the xml. You just need to pass your root element to this function (see below explanation):

def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

There is an attribute named "tail" on xml.etree.ElementTree.Element instances. This attribute can set an string after a node:

"<a>text</a>tail"

I found a link from 2004 telling about an Element Library Functions that uses this "tail" to indent an element.

Example:

# added triple quotes
root = ET.fromstring("""<fruits><fruit>banana</fruit><fruit>apple</fruit></fruits>""")
tree = ET.ElementTree(root)
    
indent(root)
# writing xml
tree.write("example.xml", encoding="utf-8", xml_declaration=True)

Result on "example.xml":

<?xml version='1.0' encoding='utf-8'?>
<fruits>
    <fruit>banana</fruit>
    <fruit>apple</fruit>
</fruits>
2 of 7
33

The easiest solution I think is switching to the lxml library. In most circumstances you can just change your import from import xml.etree.ElementTree as etree to from lxml import etree or similar.

You can then use the pretty_print option when serializing:

tree.write(filename, pretty_print=True)

(also available on etree.tostring)

🌐
GitHub
github.com › python › cpython › issues › 58670
xml.etree.ElementTree: add feature to prettify XML output · Issue #58670 · python/cpython
April 1, 2012 - bpo-14465: xml.etree.ElementTree pretty printing #4016 · bpo-14465: Provide simple prett printing for XML and ETree API #8933 · bpo-14465: Add an indent() function to xml.etree.ElementTree to pretty-print XML trees #15200 · Files · issue14465.patch: pretty printer patch, as implemented for issue 17372.
Author   tshepang
🌐
Basicexamples
basicexamples.com › example › python › xml-etree-elementtree-indent
Basic example of Python function xml.etree.ElementTree.indent()
Simple usage example of `xml.etree.ElementTree.indent()`. The `xml.etree.ElementTree.indent()` function is used to add indentation to an XML element in order to make it more readable. It adds spaces before the start tag and after the end tag of the element, as well as recursively indenting ...
🌐
my tiny TechBlog
norwied.wordpress.com › 2013 › 08 › 27 › 307
Pretty print XML trees in python – my tiny TechBlog
June 1, 2018 - from xml.etree import ElementTree as ET ''' copy and paste from http://effbot.org/zone/element-lib.htm#prettyprint it basically walks your tree and adds spaces and newlines so the tree is printed in a nice way ''' def indent(elem, level=0): i = "\n" + level*" " if len(elem): if not elem.text or not elem.text.strip(): elem.text = i + " " if not elem.tail or not elem.tail.strip(): elem.tail = i for elem in elem: indent(elem, level+1) if not elem.tail or not elem.tail.strip(): elem.tail = i else: if level and (not elem.tail or not elem.tail.strip()): elem.tail = i ''' function to build an example
🌐
pythontutorials
pythontutorials.net › blog › inserting-newlines-in-xml-file-generated-via-xml-etree-elementtree-in-python
How to Insert Newlines and Indent XML Files Generated with xml.etree.ElementTree in Python — pythontutorials.net
This function traverses the XML tree and inserts \n (newline) and space (indentation) before each child element: import xml.etree.ElementTree as ET def indent_xml(elem, space=" ", level=0): """Recursively add indentation to an ElementTree element ...
Top answer
1 of 1
1

You can do something like this:

from lxml import etree
import copy

client = etree.Element("Client")

client.append(etree.Element("ClientID"))
client[0].text = "12345"

client.append(etree.Element("ClientProfile"))
client[1].append(etree.Element("User"))

client[1][0].append(etree.Element("FirstName"))
client[1][0][0].text = "John"

client[1][0].append(etree.Element("LastName"))
client[1][0][1].text = "Doe"

client[1][0].append(etree.Element("AccountName"))
client[1][0][2].text = "Acme Inc"

client[1][0].append(etree.Element("EmailAddress"))
client[1][0][3].text = "[email protected]"

client.append(etree.Element("SalesMetric"))
client[2].text = "12345"

db_dump = etree.Element("DbDump")
version = etree.SubElement(db_dump, "ModelVersion")

db_dump.append(client)
client2 = copy.deepcopy(client)
db_dump.append(client2)
#etree.indent(db_dump, space="    ")
etree.dump(db_dump)

tree = etree.ElementTree(db_dump)
tree.write("output.xml", pretty_print=True, xml_declaration=True, encoding="utf-8")

Output:

<?xml version='1.0' encoding='UTF-8'?>
<DbDump>
  <ModelVersion/>
  <Client>
    <ClientID>12345</ClientID>
    <ClientProfile>
      <User>
        <FirstName>John</FirstName>
        <LastName>Doe</LastName>
        <AccountName>Acme Inc</AccountName>
        <EmailAddress>[email protected]</EmailAddress>
      </User>
    </ClientProfile>
    <SalesMetric>12345</SalesMetric>
  </Client>
  <Client>
    <ClientID>12345</ClientID>
    <ClientProfile>
      <User>
        <FirstName>John</FirstName>
        <LastName>Doe</LastName>
        <AccountName>Acme Inc</AccountName>
        <EmailAddress>[email protected]</EmailAddress>
      </User>
    </ClientProfile>
    <SalesMetric>12345</SalesMetric>
  </Client>
</DbDump>
🌐
University of New Brunswick
cs.unb.ca › ~bremner › teaching › cs2613 › books › python3-doc › library › xml.etree.elementtree.html
xml.etree.ElementTree — The ElementTree XML API — Python 3.9.2 documentation
This can be used to generate pretty-printed XML output. tree can be an Element or ElementTree. space is the whitespace string that will be inserted for each indentation level, two space characters by default. For indenting partial subtrees inside of an already indented tree, pass the initial ...