XML to JSON Converter
Convert XML into JSON using a documented, predictable convention for attributes, text and repeated elements.
Your XML
JSON output
There is no canonical mapping from XML to JSON, and anyone who tells you otherwise is hiding a decision. XML has attributes, namespaces, ordered mixed content, comments, processing instructions and a DOCTYPE. JSON has objects, arrays, strings, numbers, booleans and null. Several of those XML features have no JSON counterpart at all, so every converter must choose a convention — and the useful thing a converter can do is tell you exactly which one it chose.
This one uses the widely recognised badgerfish-style convention: attributes become "@name" keys, text content becomes "#text", and elements repeated within the same parent become an array. The full rules, including what is discarded, are set out below. Everything runs in your browser in a Web Worker, so a SOAP envelope full of customer records never leaves your machine.
How to use the xml to json
- 1
Paste your XML
A SOAP response, a config file, an RSS feed, an export from a legacy system. The document must be well-formed and must have exactly one root element — that is XML's own rule, not an extra restriction imposed here.
- 2
Choose the JSON indentation
Two spaces, four spaces or tabs for the output. The conversion itself is unaffected; this only controls how the resulting JSON is printed.
- 3
Review the shape before you rely on it
Check how attributes and repeated elements came through, especially any element that appears once in this sample but could appear many times in another document. Then copy or download the JSON.
The conversion rules, precisely
- The root element becomes the single top-level key.
<order>…</order>converts to{ "order": { … } }, which keeps the root name, since JSON has no separate notion of a document element. - Attributes are prefixed with
@.<order id="4821" status="paid">yields"@id": "4821"and"@status": "paid". The prefix keeps attributes from colliding with a child element of the same name, which is legal in XML and common in practice. - An element with text and no attributes becomes a plain string.
<city>Leeds</city>becomes"city": "Leeds"rather than a wrapper object, because the wrapper would double the size of a typical document for no benefit. - An element with both text and attributes uses
#text.<unitPrice currency="GBP">129.00</unitPrice>becomes{ "@currency": "GBP", "#text": "129.00" }, because the text needs somewhere to live alongside the attribute keys. - Repeated sibling elements become an array. Two
<line>elements under<lines>produce"line": [ … , … ]. A single occurrence produces an object, not a one-element array — see the warning below. - CDATA is merged into the surrounding text and unwrapped.
<![CDATA[USB-C cable]]>becomes the stringUSB-C cable; the CDATA markers themselves are a serialisation detail with no place in JSON. - Empty elements become an empty string.
<note/>and<note></note>both convert to"". - Every value is a string. No type inference is performed:
"qty": "1", not1, and"@captured": "true", nottrue. XML has no type information without a schema, and guessing wrong is worse than being consistently literal — it is what turns a product code such as0755into the number 755.
What is lost, honestly
Four things do not survive the trip, and you should know about all of them before you build anything on top of the output.
Comments and processing instructions are discarded. JSON has no comment syntax, so <!-- exported from OMS --> and any <?xml-stylesheet?> instruction simply disappear. If a comment in your source carries information — a provenance timestamp, a "do not edit" warning — copy it somewhere else first.
Namespaces are flattened to text. A prefixed element such as <pay:amount> becomes the literal key "pay:amount", and the xmlns and xmlns:pay declarations become ordinary "@xmlns" attributes. The prefix-to-URI binding that gives a namespace its meaning is gone: two documents that mean the same thing but use different prefixes for the same URI will produce different JSON. If your consumer cares about namespace identity, XML to JSON is the wrong step.
Mixed content loses its ordering. In <notes>Leave with <em>neighbour</em> if out.</notes>, the text fragments and the child element are interleaved. The converter joins the text nodes into a single #text value and lists the child separately, so you can no longer tell that "Leave with" came before the <em> and "if out." after it. Document-oriented XML — anything resembling prose markup — does not convert usefully. Data-oriented XML, which is what almost everyone is actually pasting, converts fine.
Sibling order across different element names is only as reliable as your consumer. Object keys are ordered in practice in every mainstream JSON implementation, but the JSON specification does not require it, whereas XML element order is guaranteed. Do not depend on it if the data crosses a language boundary.
The single-versus-array trap
This is the bug that catches nearly everyone, and it is inherent to the conversion rather than specific to this tool. Whether a key holds an object or an array of objects depends on how many times the element appeared in the document you converted, not on what the schema permits.
An order with two line items gives you "line": [ {...}, {...} ]. The very next order, with one line item, gives you "line": { … }. Code written against the first document crashes on the second with something like "map is not a function". Under a schema, both are maxOccurs="unbounded" and both are correct.
The defence is to normalise on the consuming side: after parsing, wrap any value you know is a collection in an array if it is not one already. Do that at the boundary, once, rather than defensively at every use. If you control both ends, converting XML to JSON is often better done with a generated, schema-aware mapping rather than a generic one.
XML to JSON FAQ
Why do attributes get an @ prefix instead of being merged in?
Because XML lets an element have an attribute and a child element with the same name, and merging them would silently lose one. The @ prefix is a long-standing convention understood by most XML-to-JSON tooling, so the output is recognisable to anyone who has done this before.
Can I convert the JSON back into the original XML?
Partly. Because the JSON to XML tool understands the same @name and #text convention, structure and attributes round-trip well. Comments, processing instructions, the exact namespace prefix bindings, CDATA wrapping and mixed-content ordering will not come back, because they were discarded on the way in.
Why are my numbers strings?
XML has no types without a schema. Inferring them would eventually corrupt an identifier — a part number such as 0755 becoming 755, or an ISBN losing precision as a float. Cast explicitly on the consuming side, where you know which fields are actually numeric.
Does it handle very large documents?
Documents up to about 10 MB convert comfortably. Parsing happens in a Web Worker so the page stays responsive, though a multi-megabyte file will still take a moment on a modest device. Nothing is uploaded regardless of size.
What if my XML has more than one root element?
Then it is not well-formed XML and the parser will reject it before conversion starts. Wrap the fragments in a single containing element first. This is a rule of XML itself, not of this converter.
