XML refuses to die, and honestly it shouldn't. It's still the backbone of plenty of real systems: Maven POMs, Android layouts, SVG, RSS feeds, SOAP services, half the enterprise integration world. And at some point you'll be handed a blob of it that looks like someone deleted every newline on purpose. Formatting that mess back into something readable is a small task you'll do hundreds of times over a career, so it's worth doing it right.

What "formatting" XML actually means

Formatting (or pretty-printing) XML is purely cosmetic. You're adding indentation and line breaks so the nesting structure is visible to a human. The parsed document is identical before and after — same elements, same attributes, same values. A machine doesn't care whether your <item> tags sit on one line or a hundred. You do.

There's a related operation, minifying, which strips the whitespace back out to shrink payload size. Both are the same idea from opposite directions, and both only touch the whitespace between nodes — never text that matters.

When you'll reach for it

  • Debugging API responses. SOAP and other XML APIs love to return everything on a single 40KB line. Formatting it is the fastest way to find the one field that's wrong.
  • Diffing config. A well-formatted file produces clean, line-by-line git diffs. One giant line means every change looks like the whole file changed.
  • Writing or editing by hand. Nested config is painful to edit when the indentation is random.
  • Code review and documentation. Pasting a readable snippet into a PR is just good manners.

Common gotchas

Whitespace inside elements is significant

This is the big one. By default XML treats whitespace between elements as insignificant, so a formatter can safely add newlines there. But text content is different. Consider:

<note>Call me <b>before</b> noon</note>

If a naive formatter reindents that into multiple lines, you can introduce spaces around <b> that weren't there. For mixed content like this, reformatting can change what the text renders as. The xml:space="preserve" attribute exists precisely to tell processors "hands off the whitespace here" — respect it, and be cautious with any element that mixes text and child tags.

CDATA sections

Anything inside <![CDATA[ ... ]]> is raw. A good formatter leaves it completely untouched. Watch out for tools that try to indent the contents — that silently corrupts embedded scripts, SQL, or HTML.

Encoding and the declaration

If the document declares <?xml version="1.0" encoding="UTF-8"?>, make sure whatever you use actually reads it as UTF-8. Mangled accented characters or smart quotes usually mean an encoding mismatch, not a formatting bug.

Comments and processing instructions

Comments (<!-- -->) and PIs should survive formatting. Some quick-and-dirty regex-based "formatters" strip or mis-indent them. Use something that parses the document properly rather than guessing at angle brackets.

It won't fix broken XML

A formatter is not a validator in disguise, but a proper one will choke on malformed input — unclosed tags, mismatched names, an ampersand that should've been &amp;. That's actually useful: if formatting fails, your XML isn't well-formed, and you've found a bug before it hit production.

A worked example

Here's the kind of thing you get back from an API, all on one line:

<order id="1042"><customer>Ada Lovelace</customer><items><item sku="A1" qty="2">Cable</item><item sku="B7" qty="1">Adapter</item></items><total currency="GBP">19.99</total></order>

Technically valid, completely unreadable. Formatted with two-space indentation it becomes:

<order id="1042">
  <customer>Ada Lovelace</customer>
  <items>
    <item sku="A1" qty="2">Cable</item>
    <item sku="B7" qty="1">Adapter</item>
  </items>
  <total currency="GBP">19.99</total>
</order>

Now the structure is obvious: an order with a customer, two line items, and a total. You can scan it in a second, and if the total is wrong you know exactly where to look.

Doing it in code vs. doing it quickly

When you need formatting as part of a pipeline, use your language's real parser. In Python, for instance:

import xml.dom.minidom

raw = '<order id="1042"><customer>Ada</customer></order>'
print(xml.dom.minidom.parseString(raw).toprettyxml(indent="  "))

That works, though minidom has a well-known quirk of adding extra blank lines around existing text nodes, so you may need to clean up afterwards. In Java there's Transformer with the indent property set; in Node, libraries like fast-xml-parser handle it. Each has its own edge cases around whitespace, so test with mixed content before you trust it.

For the everyday case — you've got a messy response in your clipboard and just want to read it — scripting it is overkill. That's when I paste it into an XML Formatter and move on. No install, no dependency juggling, and it handles the CDATA and comment cases for you.

A few habits worth keeping

  • Pick an indentation style (two spaces is common for XML) and stay consistent across a project.
  • Commit config files pre-formatted so diffs stay meaningful.
  • If formatting fails, treat it as a validity warning rather than a tooling annoyance.
  • Never reformat a file where whitespace is load-bearing without checking — SVG and some data formats can be sensitive.

Formatting XML is a tiny skill, but getting the gotchas right saves you from the far worse job of debugging a payload that "looks fine" and isn't. Parse properly, respect whitespace rules, and keep a fast tool handy for the throwaway cases.

Photo by Florian Olivo on Unsplash