Processed entirely on your device — nothing is uploaded
How to use the xml formatter
- 1Paste your XML into the box above.
- 2Watch the status line — it names the root element, counts the elements and reports a parse error the moment there is one.
- 3Choose Format, Minify or Convert to JSON, and set the indent.
- 4Press the button and copy the result.
Formatting, minifying and checking that it parses
Formatting re-indents a document so its nesting is visible, which is the difference between reading a configuration file and squinting at one. Machine-written XML — an API response, a build file, an export from a system — usually arrives as a single line thousands of characters long, and the first thing anyone needs to do with it is see its shape.
Minifying does the reverse: whitespace between elements is removed and the document goes back to one line. That is what you want before pasting XML into a field with a length limit, or embedding it in a script.
Validation is continuous rather than a separate button. As you type or paste, the tool parses the document and reports either its root element, element count and nesting depth, or the specific reason it will not parse. That covers the errors that actually happen — an unclosed tag, a stray angle bracket, a missing root element, an unterminated attribute. What it does not do is validate against a schema: this checks that a document is well-formed XML, not that it conforms to an XSD or a DTD, which is a different and much larger job.
The XML-to-JSON conventions, stated plainly
There is no standard mapping from XML to JSON, which is why two converters give you two different results for the same input. This one uses the most common set of conventions, and it is worth stating them explicitly so you know what you are getting.
Attributes become keys prefixed with `@`, so `<book id="1">` yields `"@id": "1"`. Text content sits under `#text` when the element also has attributes or children, and becomes a plain string when the element has neither. Child elements become keys named after the element.
The rule that matters most is repetition: an element that appears more than once under the same parent becomes an array. A converter that emits an object for one `<item>` and an array for two produces JSON whose shape depends on the data, and every consumer of that JSON then needs a special case. Knowing which convention was used is the difference between JSON you can write code against and JSON you have to inspect first.
Where this parser came from
The parser behind this page was not written for it. It was written because every Microsoft Office format is a ZIP archive full of XML: a .docx contains its text in `word/document.xml`, an .xlsx its cells in `xl/worksheets/sheet1.xml`, a .pptx a part per slide. Converting those files in a browser means reading XML, and the browser's own `DOMParser` — while excellent — does not exist in Node, which would have put the whole document pipeline beyond the reach of the unit tests.
So a small XML reader was written to cover the dialect those formats use: elements, attributes, text, CDATA, comments, numeric and named entities, and namespace prefixes matched by local name so that `w:p` and `ns0:p` behave identically. It is tested directly, and this page is a window onto it.
One consequence worth knowing: it is built for structured, machine-written XML rather than for prose-like documents with mixed content. XML where text and elements interleave inside the same element — closer to HTML than to a configuration file — is not what it is designed for, and DocBook-style markup is better served by a dedicated tool.
Why it matters that this runs locally
The XML people need to format is rarely neutral. It is a SOAP request with a session token in the header, a bank's payment instruction, an API response containing customer records, a configuration file with a connection string, a signed government form. Pasting any of those into a website means posting them to a server that will log the request, perhaps cache the payload, and certainly keep it long enough to matter.
Nothing here is transmitted. Parsing, formatting and conversion all happen in the tab, and the page keeps working with the network disconnected — which is the simplest way to verify the claim for yourself.
For the same reason, the sibling tools on this site work the same way: the JSON formatter, the JWT decoder, the CSV to JSON converter and the hash generator all run locally, and for exactly the same category of reason. A debugging tool that transmits what you are debugging is a debugging tool with a hole in it.
Frequently asked questions
Is my XML uploaded?
No. Parsing, formatting and conversion all happen in this browser tab. Nothing you paste is transmitted, which matters given how often XML payloads contain tokens, credentials or customer records.
Does it validate against a schema?
No. It checks that your document is well-formed XML — tags closed and nested correctly, one root element, valid entities. Validating against an XSD or DTD is a different and much larger job.
How are attributes represented in the JSON output?
As keys prefixed with @, so id="1" becomes "@id": "1". Text content sits under #text when the element also has attributes or children, and repeated elements become arrays.
Why does a single repeated element become an array?
Because consistency matters more than compactness. If one item produced an object and two produced an array, the shape of the JSON would depend on the data, and every consumer would need to handle both.
Can it handle very large files?
Documents of a few megabytes are fine. The whole document is parsed into memory, so a very large export may be slow in a browser tab; splitting it is usually quicker than waiting.
Does it preserve comments and the XML declaration?
The declaration is kept when formatting. Comments are dropped, since the parser skips them — if you need them preserved, format with an editor extension instead.