Skip to main content

How to Format XML: A Practical Guide to Indenting, Reading, and Validating It

Pretty-print messy XML, read SOAP, RSS, config, and SVG files, check well-formedness, and keep sensitive payloads local with a browser XML formatter.

Published By Li Lei
#xml #formatter #soap #validation #developer-tools

How to Format XML: A Practical Guide to Indenting, Reading, and Validating It

XML still runs a lot of the plumbing most developers touch every week. SOAP services, RSS and Atom feeds, Maven and Spring config files, Android layouts, SVG graphics, sitemaps — they all arrive as XML, and they almost never arrive nicely indented. A SOAP endpoint hands you a 4KB envelope on one physical line. A merge leaves your pom.xml with tabs and spaces fighting each other. An RSS reader refuses a feed and gives you no clue why.

This guide walks through what "formatting XML" actually means, how to read the awkward formats you meet in the wild, how to check that a document is well-formed before you ship it, and why doing all of this in a browser tab matters when the payload contains a token you would rather not email to a stranger's server.

What pretty-printing XML really does

Pretty-printing is not cosmetic fluff. It rebuilds the document's visual structure so the nesting you already coded becomes nesting you can see. The rule is simple and worth stating plainly: each nested element indents one level deeper than its parent, and self-closing tags stay intact as a single <tag/> instead of being split into an empty open/close pair.

A good formatter walks the parsed document tree and emits each node type on its own terms. Elements print with their attributes in source order. Text content sits on the line of its element. Comments stay wrapped in <!--…-->, CDATA sections in <![CDATA[…]]>, processing instructions in <?…?>, and the XML declaration — if the input had one — stays pinned to the top. Nothing is invented and nothing is silently dropped; the formatter only changes whitespace between nodes.

Indentation width is a real choice, not a default to ignore. Two spaces keeps deep config files from sliding off the right edge of the screen. Four spaces reads better for shallow SOAP envelopes where you want the soap:Body block to stand out. Tabs let each reader pick their own width. Pick the one that matches where the output is going.

A worked example: minified in, indented out

Here is the kind of single-line XML a SOAP fault or an API response actually dumps on you:

<?xml version="1.0"?><note priority="high"><to>Team</to><from/><body><![CDATA[Ship it & test]]></body><!-- draft --></note>

Run it through a formatter set to two-space indent and you get:

<?xml version="1.0"?>
<note priority="high">
  <to>Team</to>
  <from/>
  <body><![CDATA[Ship it & test]]></body>
  <!-- draft -->
</note>

Look at what survived. The priority="high" attribute kept its place. The empty <from/> stayed self-closing rather than expanding to <from></from>. The CDATA section kept its raw & without it being escaped or stripped, because CDATA exists precisely to hold characters that would otherwise break parsing. The comment landed on its own line at the right depth. Every child of <note> sits one level in. That is the whole job, done without touching meaning.

Reading SOAP, RSS, config, and SVG

The formats differ but the workflow is identical: paste, indent, read.

SOAP is the classic case. A fault buried mid-envelope is invisible on one line; once indented, soap:Fault lines up under soap:Body and you can read faultcode and detail at a glance. Namespace prefixes like soap: and xsd: are kept exactly — a formatter that mangles namespace declarations is worse than useless here.

RSS and Atom feeds are where a single stray character breaks everything. An unescaped & in an episode title is the most common offender, and an indented view makes it trivial to spot which <item> is at fault.

Config filespom.xml, Spring beans, web.xml, Logback — benefit most from the comments-stay-put guarantee. The note above each dependency is often the only documentation you have, so a formatter that preserves comments keeps a code-review diff small and honest.

SVG is XML too, which surprises people. A hand-edited or tool-exported SVG with everything on one line becomes editable once it is indented; you can find the <path> you need to tweak instead of scrolling a horizontal wall. If you eventually want the data out of XML entirely, a converter like xml-to-json turns the tree into something a JavaScript build step can read.

Validating well-formedness before you ship

Formatting and validation are two different questions, and conflating them causes real bugs. A perfectly indented file can still be broken.

Well-formedness is the baseline every XML document must meet: exactly one root element, every open tag matched by a close tag, attributes quoted, no bare & or < in text. The browser's native DOMParser — the same engine that parses XML you receive over fetch — checks all of this and reports the exact line and column where it fails. That last part is what saves time: "no element found at line 14" beats staring at the whole file.

The three failures I see most often:

  1. Two top-level elements. XML allows exactly one root. Paste two siblings at the top and parsing fails. Wrap them in a parent like <root>…</root>.
  2. A hidden BOM or whitespace before <?xml. The declaration must be the very first bytes. An invisible byte-order mark makes the parser reject a document that looks flawless.
  3. HTML entities that XML never defined. &nbsp; is an HTML thing; raw XML only knows &amp;, &lt;, &gt;, &apos;, &quot;, and numeric refs like &#160;.

One honest limit: well-formedness is not schema validity. This kind of check does not confirm your document obeys an XSD or DTD — that needs the external schema files, which a browser parser does not load. For XSD checks, reach for xmllint --schema locally.

Why local processing matters for sensitive payloads

I spent an afternoon last month debugging a partner's SOAP integration where the envelope carried a signed assertion and a bearer token. Pasting that into a random "format my XML" website would have meant shipping someone else's credentials to a server I know nothing about. So I reached for a tool that does everything in the tab.

That is the quiet argument for client-side processing. When the parser runs in your own browser, the XML never leaves the page — no upload, no logging, no analytics on what you paste, and nothing written into the URL when you share the link. You can prove it: open DevTools, watch the Network panel, format your document, and confirm not a single request carries your data. For SOAP responses, signed XML, and config files with secrets in them, that is the difference between a safe paste and an incident report.

You can try all of this in the XML formatter right now — paste, pick an indent width, and validate in one click. If your next file is JSON instead, the same local-first approach lives in the JSON formatter.

Quick reference

  • Pretty-print to read; minify to transport or paste into a ticket.
  • Each nested element indents one level; self-closing tags stay as <tag/>.
  • CDATA, comments, processing instructions, namespaces, and the XML declaration are preserved verbatim.
  • Well-formedness ≠ schema validity — check the XSD separately with xmllint.
  • Keep tokens and signed payloads on a tool that never uploads.

Made by Toolora · Updated 2026-06-13