XML Formatter
Reformat XML, flatten it to one line, or turn it into JSON, and be told where it breaks
The XML
What to do with it
There is no single right answer for XML to JSON. A tag that appears once looks different from the same tag appearing twice, because the second one has to become an array, and nothing can tell them apart from a single document. Check the shape before you write code against it.
Result
Paste XML and it gets laid out as you type, with anything broken listed underneath and the line it is on. It also squashes to one line, and converts to JSON. Nothing is uploaded, which matters when the document is an export from a system with real data in it.
Well-formed is not the same as valid
Well-formed: the brackets match, the tags nest,
the attributes are quoted.
Valid: it also obeys its own schema.
This checks the first. The second needs the
schema, and fetching the schema would mean
sending your document somewhere.Well-formed means the syntax holds up: every tag closes, they nest properly, attributes are quoted, and the special characters are escaped. Valid means it also matches a schema, which says which elements are allowed where and what they may contain.
This checks the first and reports each problem with a line number. It cannot check the second, because that needs the schema, and the schema usually lives at a URL. Fetching it would mean sending your document to a server, which is precisely what this avoids.
Broken documents still get formatted
A parser that refuses to work on malformed input is useless exactly when you need it, because you are usually here because something is wrong. So the parser carries on: a mismatched closing tag closes what it can, an unterminated comment runs to the end, and a stray < that is not the start of a tag is kept as text.
Every problem is listed with its line. The output is still laid out, and it is usually enough to see the shape of the mistake even when the details are wrong.
Why XML to JSON has no right answer
One item: Two items:
<list> <list>
<item>a</item> <item>a</item>
</list> <item>b</item>
</list>
{ "list": { { "list": {
"item": "a" "item": ["a", "b"]
} } } }
Same schema. Different JSON. Nothing in the
document says which one you will get.XML has no idea of a list. A repeated element and a single element look identical to a parser, so a converter must guess: make everything an array and the output is unpleasant, or make single elements plain and the shape of your JSON changes depending on how many rows came back that day.
This does the second, because it produces readable output, and says so here because it is the thing that breaks code written against a sample. If you are writing a parser against converted XML, test it with a document containing one item and one containing two.
Attributes are a related problem. They live in a different space from child elements, and JSON has only one, so they get a prefix. The @ is the convention most libraries use. You can change it, and you can turn it off entirely if you are certain no attribute shares a name with a child.
Whitespace
<name> Alice </name>
<p>Hello <b>there</b> friend</p>
In the first, the spaces are probably an
accident. In the second, removing them joins
three words into one. XML cannot tell you which
kind you have.XML treats whitespace inside an element as content. Sometimes it is real, and sometimes it is just how the file was indented. There is no rule that gets both right, so tidying it is a switch, on by default, because a document you are reformatting is usually one where the indenting was the problem.
Content inside CDATA is never touched, in any mode. That is what CDATA is for, and a minifier that collapses spaces inside one has broken the data, not tidied it.
The five entities
< > & " '
Those five, plus numeric ones like © and
©. Everything else, including , has
to be declared in the document before XML will
accept it, which is why an HTML fragment pasted
into an XML parser so often fails.On the way out, a bare ampersand gets escaped and one that already starts a valid entity is left alone, so running the formatter twice does not turn& into &amp;. On the way to JSON, entities are decoded back into the characters they stand for.
The quote style of each attribute is remembered, so an attribute written with single quotes because it contains a double quote comes back the same way instead of being rewritten and needing a new escape.
What is preserved
Self-closing tags stay self-closing and <a></a> stays as it is, unless you ask for them to be collapsed. Comments, processing instructions, the XML declaration and the doctype all survive, including a doctype with an internal subset in square brackets.
Namespace prefixes are part of the element name as far as this is concerned, so dc:title stays dc:title. Declared prefixes are listed in the summary, which is a quick way to see what vocabularies a document is mixing.