Home / Guides / XML formatting guide

XML Formatting Guide

How to indent, wrap and minify XML without changing its meaning: what white space is data, what is not, and the tools that do the job.

Format a document now with the XML formatter.

Why format XML?

XML is read by people as often as by programs. A well-laid-out document shows its structure, makes a missing element or a wrong attribute easy to find, and makes a version control diff show only the lines that really changed. A minified document is the opposite: it is small, and nobody can read it. The same document can be both, and a formatter moves it from one form to the other.

The central question: which spaces are data?

In XML, white space inside text can be part of the data. A formatter adds and removes white space, so it must know where it is safe. The safe cases depend on the kind of element:

  • Element-only content. The children are all elements, as in <items><item/><item/></items>. The spaces and line breaks between children carry no data. They can be replaced by indentation, or removed.
  • Text-only content. An element with just text, as in <name>Alex</name>. The text is the data. Leading and trailing spaces are usually not meant, but only the application knows. A formatter should keep this element on one line and let you choose whether to trim.
  • Mixed content. Text and elements together, as in a paragraph with an emphasized word. Every space here belongs to the text.

Why mixed content must not be re-indented

Take this paragraph:

<p>Ships in <em>2 days</em> worldwide.</p>

A formatter that treats every element the same way would write:

<p>
  Ships in
  <em>2 days</em>
  worldwide.
</p>

Now the text contains line breaks and runs of spaces that were not there before. Depending on the application, the sentence can come out as "Ships in 2 days worldwide." with extra spaces, or the layout of a document can change. A careful formatter copies mixed content exactly, and the XML formatter on this site does the same.

xml:space="preserve"

The attribute xml:space="preserve" tells every program that the white space inside an element must be kept. It is used for code samples, poetry and similar content. A formatter must leave such an element untouched.

Style conventions

  • Indent with two spaces (or four, or a tab). Two spaces are the most common, because XML nests deeply. Choose one for the whole project.
  • One element per line in element-only content.
  • Wrap long start tags. When a tag has many attributes, put one attribute on each line, indented by one level. A common limit is 100 or 120 characters.
  • Use <a/> for empty elements, unless the schema or the consumer needs <a></a>. Both mean the same in XML.
  • Use double quotes for attribute values. Single quotes are valid, but mixing both styles is untidy.
  • Sort attributes if you compare files often, because attribute order has no meaning in XML, and a stable order makes diffs shorter. Put the xmlns declarations first.

Minifying XML

Minifying removes the white space that formatting adds, and often the comments. It is useful for messages in a queue, for SOAP requests, for a value stored in a single line, and for files that are shipped to users. Do it only on a copy, and keep the formatted file as the source. Over a network with gzip, the gain is small, because gzip compresses white space well. Use the XML minifier and look at the gzip size that it shows.

When not to format at all

  • Signed XML. A digital signature, such as XML Signature or a SAML assertion, covers the exact content. Changing white space can break it. To compare signed documents, use canonical XML (C14N) and not a formatter.
  • Files that are compared by hash, because any change of bytes changes the hash.
  • Documents with significant white space that is not marked with xml:space. Ask what the consumer expects before you change it.

Formatting in code and on the command line

# xmllint (libxml2): indent a file
xmllint --format file.xml

# xmllint: remove ignorable white space
xmllint --noblanks file.xml

# xmlstarlet: format with 2 spaces
xmlstarlet fo -s 2 file.xml
# Python 3.9 or later
import xml.etree.ElementTree as ET
tree = ET.parse("file.xml")
ET.indent(tree, space="  ")
tree.write("pretty.xml", encoding="utf-8", xml_declaration=True)
<?php
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->loadXML($xml);
$dom->formatOutput = true;
echo $dom->saveXML();

In the PHP example, preserveWhiteSpace = false drops the existing white space between elements, so use it only for data in which that is safe, and not for documents with mixed content.

Common mistakes

  • Formatting XML that is not well-formed. A formatter cannot do its job on a missing end tag. Run the XML validator first.
  • Re-indenting mixed content, such as HTML-like text inside XML.
  • Mixing styles in one project, such as 2 spaces in one file and tabs in the next.
  • Changing the format and the data in one commit. Format first, and commit it on its own, so that a reviewer can see the real change.

Tools on this site

Frequently asked questions

How should I indent XML?

Use two spaces per level (or four, or a tab) and put each element on its own line in element-only content. The important thing is that the whole project uses one style.

Does formatting XML change its meaning?

It should not, when it only changes the white space between elements. White space inside text and mixed content can be data, so a careful formatter copies it exactly.

What does xml:space="preserve" do?

It tells programs to keep all white space inside that element. A formatter must leave the element as it is.

Can formatting break a digitally signed XML document?

Yes. A signature covers the exact content, so changing white space can invalidate it. Use canonical XML (C14N) to compare signed documents.

Does minifying XML help when the server uses gzip?

Only a little. Gzip already compresses white space well. Minifying helps more for files on disk, for values in a log or a database, and for systems that do not compress.