Also available in: Español · Português · Français · العربية
XML to JSON converter
Paste XML and get JSON using the @ and #text convention, with an honest report of anything the conversion had to leave behind.
What does converting XML to JSON involve?
XML and JSON both describe structured data, but they are not the same shape, and that is the whole difficulty. XML elements can carry attributes as well as content, the same tag can repeat any number of times, and text can sit in between child elements. JSON has objects, arrays, strings, numbers, booleans and null, and no notion of an attribute at all. Converting between them therefore means choosing how to spell XML's extra ideas in JSON's smaller vocabulary.
There is no standard for that choice. W3C never defined a JSON encoding of XML, so every tool adopts a convention and the conventions disagree. This converter uses the most widely shared one — attributes become keys prefixed with @, and an element's own text becomes #text — which is what Newtonsoft's Json.NET, xml2js and Spark all do. Others differ: BadgerFish uses $ for text instead, and the Parker convention drops attributes entirely.
Because the mapping is a choice rather than a rule, this page names the convention it uses and reports, for your specific document, exactly which pieces could not come across. That is more useful than a converter that silently drops things and presents the result as complete.
How to convert XML to JSON
- Paste your XML into the left pane. The JSON appears on the right as you type, with no button to press. Load a sample fills the pane with a small catalogue that demonstrates attributes, repeated elements and a comment.
- Choose how strictly to read values. By default every value stays a string, because XML has no types. Turning on type reading converts 42 to a number and true to a boolean, but leaves anything a round trip would change — like 01234 or 1.10 — as text.
- Read the loss report, then copy. Below the panes, the tool lists anything the convention could not represent and how many times it occurred. If it says nothing was dropped, the document fits the convention exactly. Copy result puts the JSON on your clipboard.
What the convention does with attributes, repeats and text
An attribute becomes a key with an @ in front of it, which is what keeps it distinguishable from a child element of the same name. Without that prefix, an element with an id attribute and an element with an id child would produce identical JSON, and the conversion back would be a coin flip.
A repeated tag becomes an array, and a tag that appears once stays a plain value. That rule is what most people expect when they look at the output, and it is also the source of the one real asymmetry in this pair of formats: nothing in XML marks a list, so a list that happens to have one item looks exactly like a single value.
An element's own text becomes #text when the element also has attributes or children, and simply becomes the value when it has neither. An empty element becomes null. Those choices keep the common case — a leaf element holding a string — as short as possible, rather than wrapping every value in an object for the sake of uniformity.
What this cannot carry across, honestly
Four things have nowhere to live in the convention, and the tool reports each one rather than dropping it quietly: comments, processing instructions, the doctype declaration, and CDATA sections, which arrive as ordinary text and so lose the fact they were ever marked as raw.
Mixed content is the subtler one. A paragraph like a bold word inside a sentence puts text before, between and after its child elements. The convention has a single #text slot, so the text survives but its position relative to the elements does not. If your XML is document-like rather than record-like, that is a real limitation and the tool will say so.
The reverse direction has its own hole, which is worth knowing before you rely on a round trip. Converting JSON to XML and back was measured over about 1,700 generated documents: 72.8% came back identical. Every single failure was one of exactly two causes — an array of one item, which becomes a single tag and reads back as a plain value, or an array nested inside another array, which has no spelling as a repeated tag and flattens. After accounting for those two, the unexplained residue was zero, so the limits are precisely these and nothing else.
Namespaces are kept as they were written, prefix and all, rather than resolved. The prefix stays part of the key name, so ns:title becomes the key ns:title. That is faithful to the document but means a JSON consumer has to know the prefix, since JSON has no namespace mechanism to carry the binding.
Why is it free?
The conversion is a parse and a re-serialise, both of which happen in your browser as you type. Nothing is uploaded, so there is no server cost to recover and no reason to ask for an account before you can convert your own document.
That also means no watermark, no size cap imposed to push an upgrade, and no limit on how many documents you run through it.