XML Formatter, Validator & JSON Converter
An XML formatter and validator that also converts XML to JSON and back, with errors pinned to the line.
Formatted
The converted document lands here.
Indented and ready to copy.
Invalid XML
Operation
What the document lost
How to use
- Paste the document into the left well. The right one fills as you type.
- Leave Operation on Format for a first look, and pick an Indent if two spaces is not your house style.
- Choose Minify to see the same document on one line, or To JSON to get it as an object. Attributes arrive as keys with an @_ prefix, so an id attribute lands as @_id and cannot collide with a child element also called id.
- Going the other way, choose From JSON and paste JSON into the same well.
- Press Copy output for the whole result, or Download for a .xml or .json file.
About this tool
Paste the markup on the left and the formatted document builds itself on the right as you type. As an XML formatter it does the careful thing: an element that holds only other elements gets one child to a line, indented by the two spaces, four spaces or tab you choose, while an element holding text beside its tags, and anything under xml:space="preserve", is written back exactly as it was, because the spaces in The <b>quick</b> brown fox are part of the sentence. The XML declaration, a DOCTYPE, processing instructions, comments and CDATA sections all come back where you put them. Minify hands the whole document back on one line, self-closing empty elements as it goes, and never runs words together.
The four chips across the top are Format, Minify, To JSON and From JSON. The XML operations run a well-formedness check first, and a failure keeps the last good result on screen, dimmed, with the position named, along the lines of Invalid XML (line 3): Expected closing tag 'from' (opened in line 3, col 3) instead of closing tag 'to'. On the JSON side every element below the root comes back as an array, so one book and two books have the same shape, and text stays a string. Going the other way, JSON that cannot be XML, a top-level array, two roots or a key that is not an XML name, is refused with the key that caused it. Under the panes the page counts the text nodes it moved, which is how you know none were.
Rough edges
- Mixed content does not travel well into JSON: a paragraph reading Hello <b>world</b> and goodbye comes back with b set to world beside a #text key, and the order of the text runs around the tag is gone. The strip under the panes says so when your document has any.
- Well-formedness is the whole of the validation. No XSD or DTD is applied, so a document can parse cleanly here and still be wrong for the schema it claims to follow. The check is looser than a real parser in one specific place too: two sibling root elements with nothing wrapping them are accepted, and no conforming XML parser would take that.
Frequently asked questions
How do I convert XML to JSON and back again?
Two of the four operation chips do it. To JSON parses the document and prints the object at the indent you chose; From JSON takes an object out of the same well and builds indented markup from it, checked as XML before it is shown. Attributes survive the trip both ways because they are stored under @_-prefixed keys. Comments do not: Format and Minify keep them, but they are dropped on the way into JSON.
Why did <count>42</count> come out as a string in the JSON?
Deliberately. Number parsing is switched off, so every text value arrives as a string and nothing gets rewritten under you on the way through. That is the safe default for values XML treats as text and JavaScript would quietly reinterpret: a part number like 007 keeps its leading zeros, a version like 1.10 does not collapse to 1.1, and a long identifier does not lose precision. Cast the handful of fields you actually need as numbers on your side.
Will it wreck my namespace prefixes?
They come through untouched. Format and Minify only move whitespace between elements, so soap:Envelope stays soap:Envelope and an xmlns declaration stays on the element that carried it. Convert to JSON and the prefix just becomes part of the key: soap:Body is the key, and xmlns:soap turns into @_xmlns:soap. Nothing resolves a prefix to its URI, though. It is treated as text.
How big a file can I paste in?
No size cap is written into the tool, but the parsing happens on the page's own thread rather than in a worker, so a document large enough to take a while will lock the tab up for exactly that long. Config files, API responses and SOAP envelopes are not going to trouble it. A multi-megabyte data export might, and there is no progress indicator to tell you it is still working.
Missing something in XML Formatter, Validator & JSON Converter? Suggest a feature →
Tell someone who needs this.