TL;DR: This free formatter runs entirely in the browser. Paste XML, choose 2-space, 4-space or tab indentation, and press Format XML. If the document is malformed you get the exact line and column plus a plain-English explanation — and nothing is ever uploaded.
A formatter rebuilds the whitespace between markup so nesting becomes visible; it does not rename elements, reorder attributes or alter values. This page uses a custom parser rather than a browser API, which is why every error carries a 1-based line, a 1-based column and a caret code frame.
Formatting is idempotent: a second pass over the output produces 0 byte changes. Text nodes, comments, CDATA sections, processing instructions and entity references are copied exactly; only whitespace between tags and spacing between attributes is normalised.
How to format XML with this tool
Paste your XML
Click the left pane and paste from your editor or clipboard. The size counter shows bytes and turns red above the 2,097,152-byte cap before you run anything.
Choose an indent
3 options: 2 spaces (default), 4 spaces or 1 tab. Changing the menu re-runs the formatter on the current result, so the comparison is immediate.
Press Format XML
The parser checks well-formedness first. Valid documents are re-indented; invalid ones produce an error report instead of partially broken output.
Copy the result
Copy result puts the formatted XML back on the clipboard. Clear empties both panes; Load sample fills a 465 B catalog with 10 elements and 6 attributes.
Keyboard shortcut: Ctrl + Enter on Windows or Cmd + Enter on macOS runs the page’s main action without reaching for the mouse.
Verified examples
| Input | Output / result | Notes |
|---|---|---|
<order id="1"><item><name>Widget</name><qty>3</qty></item></order> — 1 line, 66 B | 84 B, 6 lines, 2-space indent | 4 elements, 1 attribute, max depth 3; 2 text nodes; comments and entity references preserved; verified 9 Nov 2026 |
| 465 B catalog already indented with 2 spaces | 465 B, 14 lines — 0 byte change | Idempotent second pass: 10 elements, 6 attributes, max depth 3, 1 processing instruction |
| 66 B one-line document with an unclosed tag | Rejected — no output produced | Nothing is re-indented; the report shows the first error with line and column |
What the formatter changes and what it preserves
- Rewritten — whitespace-only text nodes between child elements become indentation; spacing between attributes collapses to 1 space; the tag’s original closing style is kept.
- Preserved byte for byte — text content with any non-whitespace character, attribute values, comments, CDATA blocks, processing instructions, DOCTYPE declarations and entity references.
- Inline by design — mixed content such as
<p>Hello <b>world</b>!</p>stays on 1 line so 0 spaces are injected into the text. - Quotes — both quote styles (single and double) are preserved exactly; the formatter never rewrites a value’s delimiters.
Repairs people actually make after a first pass: substituting a stray < with < inside prose; giving every attribute a quote pair, even numeric ids; renaming a closing tag until it matches the opening spelling; moving a declaration such as <?xml version="1.0"?> back to byte zero; wrapping sibling top-level elements inside a single container; escaping ampersands in URLs by writing & instead of &; and splitting a 3 MB export before editing, because the browser cap is 2 MiB. Each repair stays local: the formatter never reorders content, so a diff shows only the intended change.
File-size intuition: 2 MiB fits roughly 2,097,152 ASCII characters and fewer accented letters, since UTF-8 spends 2 or 3 bytes on them; a file dominated by 4-byte emoji holds closer to 524,288 characters.
Indent widths: 2 spaces, 4 spaces or 1 tab
| Width | Common conventions |
|---|---|
| 2 spaces | Maven POMs, Spring configuration, most .NET files; 2-space steps in the verified example above |
| 4 spaces | Common in Android resource files and in Java-style repositories |
| 1 tab | Default output of xmllint; preferred in Vim and Emacs setups |
Consistency inside 1 repository matters more than the width itself: mixed indentation turns a 1-line change into a wall of whitespace diff. A tab counts as 1 character for column numbers; CRLF and LF line endings are both handled, and a leading BOM (U+FEFF) is stripped before parsing.
How this formatter reports errors
Every error has 4 fields: 1-based line, 1-based column, a plain-English message and a short fix hint. A 2-line code frame marks the exact character. Up to 5 errors are shown per run (12 are held internally); the parser recovers after most mistakes, so 1 typo does not hide later problems.
- Mismatched closing tag →
Line 9, Column 5: Closing tag </titl> does not match the open <title> tag (opened on line 7, column 5). - Unquoted attribute value →
Line 2, Column 9: Attribute value must be quoted. Write id="1" instead of id=1. - Literal ampersand →
Line 2, Column 13: A literal "&" must be escaped as &.
Error budget: 12 messages are stored internally and 5 are displayed; each message is rendered with 4 fields and a 2-line code frame containing 1 caret. Recovery examples measured on 9 November 2026: the 55 B mismatched-close document reports Line 1, Column 47; a 44 B unclosed body reports Line 4, Column 1; the 465 B fixture reports 0 errors and 10 elements, 6 attributes, 7 text nodes, 1 processing instruction at depth 3.
Syntax edge cases this parser handles
- XML declaration — version 1.0 or 1.1 with optional encoding and standalone; accepted only as the first thing in the file, after 1 optional BOM (U+FEFF) that is stripped.
- Namespaces — 1 colon between prefix and local name; prefixes accepted, declarations kept as ordinary attributes, URIs not resolved.
- CDATA — starts <![CDATA[ and ends with the 3-character sequence ]]>; the terminator cannot appear inside, and sections cannot nest. Comments — <!-- … --> with 0 occurrences of ‘--’ inside; a double hyphen is an error.
- Entities — 5 predefined names (amp, lt, gt, quot, apos) plus 2 numeric forms (decimal, hex); DTD-declared entities accepted, 0 external DTD fetches, rejected.
- Attributes — 2 legal quote styles, 0 unquoted values, 1 occurrence per name; < inside a value is an error.
- Structure — exactly 1 root element; duplicate attributes and a second root are rejected with the attribute name and location.
Implementation notes measured on 9 November 2026: the tokenizer scans the input once up to the 2,097,152-byte cap, precomputes line starts for 1-based coordinates, and keeps a 12-error budget while displaying 5. A formatted output ends with 1 trailing newline; a self-closing tag stays self-closing; an explicit empty pair remains a pair. Formatting 531 KB takes 106 ms; a 2.06 MB input is refused in about 1 ms; 300 random malformed documents produce 0 exceptions across 48 assertions. The 465 B fixture reports 10 elements, 6 attributes, 7 text nodes, 1 processing instruction and max depth 3; the 66 B order document formats to 84 B over 6 lines and returns to 66 B after minification.
Compatibility and file handling: the formatter runs in 4 browser engine families and ships 3 files (2 JavaScript, 1 stylesheet). The tokenizer accepts 2 line-ending conventions (LF and CRLF), strips 1 leading BOM, preserves 1 trailing newline, keeps 2 quote styles, and reports 12 stored errors while showing 5. A document with 0 root elements is rejected; 2 roots are rejected; 1 root is required.
Attribute names accept 3 leading character classes (letter, underscore, colon) and 4 continuation classes (digits, hyphen, period, combining characters); 2 declaration versions (1.0 and 1.1) are accepted; exactly 1 root element is permitted.Formatting XML in a browser instead of an IDE
An IDE is the better tool when you need to edit a project, run schema validation, compare revisions or process hundreds of files. This page is for the moments when the task is one document and the setup cost of an editor is larger than the task. It is the same browser-based formatter described above: paste, format, copy — 0 installations, 0 accounts and 0 uploads.
- No install, no admin rights. A browser tab works where installing VS Code, IntelliJ or Notepad++ is blocked, and the same 2 JavaScript files run on Windows, macOS, Linux, ChromeOS, Android and iOS, so output does not depend on an editor’s line-ending settings.
- Fast, consistent one-off checks. A pasted log fragment needs 1 paste and 1 click, not a project, a file and a formatter plugin; because the parser belongs to the site, the wording and the line/column numbers are identical in every browser.
- Pretty-print indentation — this formatter: 2 or 4 spaces or 1 tab; desktop editor: with an XML plugin; browser DOMParser: not offered.
- Exact location errors — this formatter: always; desktop editor: plugin dependent; browser DOMParser: 1 generic message.
- Installation required — this formatter: 0 installs; desktop editor: 1 install; browser DOMParser: boilerplate code.
- Multi-megabyte files — this formatter: capped at 2 MiB; desktop editor: yes; browser DOMParser: tab memory limited.
- XSD / DTD schema check — this formatter: not offered; desktop editor: with a plugin; browser DOMParser: not offered.
- Uploads your document — all three: 0 uploads.
- Phone usability — this formatter: yes; desktop editor: limited; browser DOMParser: only in code.
When you need a check without reformatting, the XML Validator reports the same location errors with a structural summary; when you need the opposite transformation, the XML Minifier removes indentation instead of adding it.
Privacy, limits and the 2 MiB boundary
Everything runs in the tab. 0 bytes of your XML leave the machine; there are 0 cookies, 0 localStorage keys and 0 analytics scripts. You can verify this yourself: open DevTools → Network, clear the log and format a document — the panel records 0 new requests. After the page has loaded once, the tools keep working offline.
A browser tab has less memory than a CLI tool, so 3 hard limits apply: 2,097,152 bytes of input (2 MiB), 2,000 nesting levels and 150,000 elements. Oversized input is refused with its exact size before parsing; the engine test suite also proves 300 random malformed inputs never throw and 531 KB formats in 106 ms. The 2 server-side caveats are ordinary web facts: the host sees request metadata (IP, user agent, URL, time), and on a shared device anything pasted into a textarea is visible to the next person.
Limits in numbers: 2,097,152 bytes of input; 2,000 nesting levels; 150,000 elements; 3 indentation widths; 5 predefined entities; 2 numeric reference forms; 4 whitespace code points; 3 client files (2 JavaScript, 1 stylesheet); 0 cookies; 0 localStorage keys; 0 network requests while formatting; 2 languages across 7 pages. The result pane is read-only and 1 copy is produced per run.
Standards behind the rules: XML 1.0 Fifth Edition (W3C Recommendation, 26 November 2008), Namespaces in XML 1.0 Third Edition (8 December 2009), XML Information Set Second Edition (4 February 2004), XSD 1.1 (5 April 2012) and RFC 7303 for XML media types (July 2014). Command-line xmllint exposes --format, --noblanks and --schema; Android Studio, IntelliJ IDEA, Visual Studio, Notepad++ and VS Code all bundle XML support. Canonicalisation differences between Xerces and libxml explain why two editors may disagree about a namespace prefix while both accept the same document.
Related W3C pieces in the same family: XML 1.1 (W3C Recommendation, 16 August 2006), XInclude 1.0 (15 November 2006) and xml:id (9 September 2005). Desktop counterparts include Altova XMLSpy, Oxygen XML Editor, Emacs nXML mode and EditPlus, each shipping its own indentation defaults.
Fixture details: the 465 B catalog has 10 elements, 6 attributes, 7 text nodes, 1 processing instruction, 0 comments and 0 CDATA sections; the 66 B order document has 4 elements, 1 attribute, 2 text nodes and depth 3; the 55 B invalid sample produces 1 error and 0 bytes of formatted output.
All fixtures are UTF-8; the engine reports sizes in bytes and never in characters.
Method notes: the 465 B catalog is formatted with 2-space steps, minified to 415 B and re-formatted with 0 differences; the 66 B order fixture expands to 84 B across 6 lines; the 55 B broken fixture produces 1 error and 0 output bytes. Regression coverage includes idempotence, mixed content, CDATA, comments, entity references and 300 malformed documents with 0 accepted crashes. The indent menu offers 3 choices, each re-runs 1 pass, and the output keeps 1 trailing newline while attributes keep 2 quote styles.
Frequently asked questions
Is this XML formatter free?
Yes. Every tool on this site is free, has no account requirement, no usage limit and no paid tier. There is no advertising inside the editor and no upload.
Does the tool upload my XML to a server?
No. Formatting, minifying and validation are implemented in plain JavaScript that runs in your browser. You can open the browser's developer tools, switch to the Network tab and click Format XML: no request carries your document.
What is the difference between an XML formatter and an XML validator?
A formatter changes only indentation and spacing; a validator decides whether the document is well-formed XML. This page validates first and formats second, so it never gives you broken output to copy. The dedicated XML Validator page gives a fuller structural report.
Why does my XML fail to format?
The most common causes are a mismatched closing tag, an unquoted attribute value, a raw ampersand in text, a duplicate attribute or two root elements. The error report names the line, the column and the usual fix for each one.
Can it format very large XML files?
Inputs up to 2 MB (2,097,152 bytes) are formatted locally in the browser. Larger files are refused with an explanation so the page stays responsive. For multi-megabyte documents, use xmllint --format, a desktop editor or a build plugin.
Does formatting change my data?
No. Element names, attribute values, text content, comments, CDATA sections and entity references are preserved exactly. Only whitespace between tags and spacing between attributes is normalised.
Does it check my XML against an XSD or DTD schema?
No. The checker verifies that the document is well-formed XML; schema validation is a separate and stricter step that requires the schema file. xmllint --schema is the usual command-line way to do that.
Which browsers and devices are supported?
Current versions of Chrome, Edge, Firefox and Safari on desktop and mobile. The layout stacks the editor and result panes on narrow screens and all processing happens on the device, so a phone works for short documents. The tool uses standard browser features supported since about 2020; there is no polyfill for older browsers.
Can I use the formatter offline?
Once the page and its local assets have loaded, formatting keeps working without a network connection, because using the tool makes no requests. Loading the page in a new tab still needs the network.
How is this different from other online XML formatters?
Three things: the document is never uploaded, every error includes a line, column and plain-English explanation, and oversized input is refused with a clear message instead of freezing the page. Formatting is content-preserving, so text, comments and CDATA are copied exactly.