XML gets a lot of hate, but it hasn't gone anywhere. You'll still hit it in SOAP responses, Maven and Android config files, RSS feeds, sitemaps, SVG, and the guts of every Office document. And nine times out of ten, when you pull XML off the wire or out of a log, it arrives as one giant unreadable line. Formatting it — turning that soup into indented, human-readable structure — is one of those small tasks you do constantly.

What "formatting" XML actually means

Formatting (or pretty-printing) XML means adding consistent indentation and line breaks so the nesting is visible. It doesn't change the meaning of the document — the parsed result is identical. It's purely for humans.

Compare this minified blob:

<order id="1042"><customer><name>Ada Lovelace</name><email>[email protected]</email></customer><items><item sku="BK-01" qty="2"/><item sku="PN-09" qty="1"/></items></order>

With the formatted version:

<order id="1042">
  <customer>
    <name>Ada Lovelace</name>
    <email>[email protected]</email>
  </customer>
  <items>
    <item sku="BK-01" qty="2"/>
    <item sku="PN-09" qty="1"/>
  </items>
</order>

Same data. But the second one you can actually read, diff, and reason about.

When you reach for it

  • Debugging API responses. A SOAP or XML-REST endpoint hands you a wall of text. Format it and the structure — and the missing field you were hunting — jumps out.
  • Reviewing diffs. Version-controlling config? Consistent formatting keeps diffs small and meaningful instead of showing an entire file as one changed line.
  • Writing by hand. Editing a pom.xml or an Android layout is far less error-prone when the indentation reflects the hierarchy.
  • Copying into docs or tickets. Nobody wants a 4,000-character single line pasted into a bug report.

Common gotchas

1. Formatting an invalid document

Formatters need to parse the XML first. If a tag isn't closed or an attribute is missing a quote, you'll get an error rather than pretty output. That's actually useful — it catches structural problems early. But don't be surprised when a broken snippet won't format; fix the syntax first.

2. Whitespace is sometimes significant

This is the big one. In elements with mixed content — text and child elements together — adding indentation can change what the document means. Consider:

<p>Hello <b>world</b>!</p>

If a formatter naively breaks that across lines and indents it, you introduce spaces and newlines inside the text that weren't there before. For prose-style XML (XHTML, DocBook), that can matter. The xml:space="preserve" attribute exists precisely to tell processors to leave whitespace alone. A good formatter respects it; a careless one doesn't.

3. Encoding and the BOM

XML declares its encoding in the prolog (<?xml version="1.0" encoding="UTF-8"?>). If the actual bytes don't match — say you've got Latin-1 content claiming to be UTF-8 — parsing fails on the first accented character. A leading byte-order mark can also confuse some parsers. When formatting mysteriously breaks, check the encoding before blaming the formatter.

4. CDATA and comments

Content inside <![CDATA[ ... ]]> must be left exactly as-is — that's the whole point of CDATA. The same goes for comments. Reindenting the guts of a CDATA block would corrupt it. Make sure whatever tool you use treats these as opaque.

5. Attribute order and namespaces

Formatting shouldn't reorder attributes or rewrite namespace prefixes — semantically it could, but it makes diffs noisy and can surprise downstream tooling. Preserve what's there.

A quick worked example

Say you've logged a raw response and need to check it. On the command line, xmllint (ships with libxml2, so it's already on most Macs and Linux boxes) does the job:

xmllint --format response.xml

Piping works too:

curl -s https://api.example.com/orders/1042 | xmllint --format -

If you're in Python, the standard library has you covered:

import xml.dom.minidom

raw = "<order id='1042'><items><item sku='BK-01'/></items></order>"
print(xml.dom.minidom.parseString(raw).toprettyxml(indent="  "))

One thing to watch with minidom: if your source already contains stray whitespace text nodes, toprettyxml can produce extra blank lines. You'll often need to strip those or reach for lxml, which handles it more gracefully.

When I'm mid-debug and just want to eyeball something quickly, I don't want to fire up a script or remember flags. A browser tab is faster. Paste the blob into an XML Formatter, get clean indented output, done. No install, nothing leaves as a dependency in your project, and it handles the encoding and CDATA edge cases for you.

Formatting vs. validating vs. minifying

Worth keeping these straight, because people conflate them:

  • Formatting makes it readable. Meaning unchanged.
  • Minifying strips the whitespace back out to save bytes — handy before sending over the wire.
  • Validating checks the document against a schema (XSD) or DTD. That's a different, stronger guarantee than well-formedness. A document can be perfectly well-formed and still violate its schema.

A formatter gets you well-formedness checking for free (it has to parse to format), but it won't tell you your <quantity> should have been an integer. For that you need actual schema validation.

A few habits worth adopting

  • Pick a consistent indent — two spaces is common, tabs are fine, just don't mix them.
  • Format config files before committing so diffs stay clean. Some editors do this on save.
  • Don't format XML you're about to hash or sign. Canonicalization (C14N) is its own spec for a reason — reformatting can invalidate a digital signature.
  • When something won't format, read the parser error. It usually points at the exact line and column of the problem.

Formatting XML is a two-second task that saves you from squinting at a wall of angle brackets. The gotchas — significant whitespace, CDATA, encoding — only bite when a tool cuts corners, so use one that doesn't, and move on with your day.

Photo by Ilya Pavlov on Unsplash