Two data models that do not match
JSON has objects, arrays, strings, numbers, booleans and null. XML has elements, attributes and text, and everything is a string. A converter has to pick conventions, and this one uses two special key names: a key starting with @ becomes an attribute, and #text holds an element's text content. The same conventions apply in both directions.
JSON to XML
The Root element box names the outer tag, defaulting to root, and the output starts with an XML declaration. Object keys become child elements, array values repeat the element once per item, and null becomes a self-closing tag. When an object has both #text and child elements, the text is written first, on its own line, followed by the children. A JSON array at the top level is wrapped in the root element with one <item> per entry, so the result is always a single well-formed document. Text is escaped for &, < and >. A key that is not a legal XML name, for example bad key, is replaced by item.
Given the root name user and this JSON:
{"@id":"7","name":"Ada & Co","tags":["a","b"],"e":null,
"note":{"@lang":"en","#text":"hi"}}
the output is:
<user id="7">
<name>Ada & Co</name>
<tags>a</tags>
<tags>b</tags>
<e/>
<note lang="en">hi</note>
</user>
XML to JSON
The browser's DOMParser reads the document, so malformed XML is reported as "Invalid XML" with the parser's first message line. The result is wrapped in the root tag name. For example, <order id="42"><item sku="A1">Pen</item><item sku="B2">Ink</item><note>Rush</note></order> becomes:
{"order":{"@id":"42",
"item":[{"@sku":"A1","#text":"Pen"},{"@sku":"B2","#text":"Ink"}],
"note":"Rush"}}
Lossy spots and gotchas
- One-item lists. By default, repeated sibling tags become an array only from the second occurrence, so an order with a single
<item>yields an object, not a one-element array. Tick "Always use arrays for child elements" (shown in XML to JSON mode) and every child element is written as an array, even when it appears once, so your code can rely on one shape. The option applies to child elements only; attributes and an element's own text are not arrays. - Everything is text.
<qty>3</qty>becomes"3", a string, and an empty element becomes"", so a null does not survive a round trip. - Mixed content. Text next to child elements is kept under
#textin both directions, but its position is not. For<p>Hello <b>you</b> there</p>the pieces of loose text are joined with a space into"#text": "Hello there"and the<b>becomes a separate key, so prose with inline tags cannot be rebuilt exactly. - Namespaces. Prefixed tags keep their prefix as part of the key, for example
soap:Body.
For YAML or tabular targets, see JSON to YAML and JSON to CSV.