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 = "
" + 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:
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>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…