JSON to XML Converter
Turn JSON into well-formed XML, with clear rules for the root element and for keys that are not legal element names.
Your JSON
XML output
Going from JSON to XML runs into two structural mismatches immediately, and both need a decision rather than a guess. First, XML permits exactly one root element, while a JSON document can be an object with a dozen top-level keys, a bare array, or even a single number. Second, JSON object keys can be any string at all — "shipping method", "2ndAttempt", "" — while XML element names must start with a letter or underscore and cannot contain spaces.
This converter resolves both explicitly and tells you when it has done so. Everything runs client-side in a Web Worker, which is the usual reason to reach for a browser tool when the payload is a real customer record rather than a toy example.
How to use the json to xml
- 1
Paste valid JSON
An object, an array, or a scalar. If the JSON does not parse you get the error and its position rather than partial output — fix it in the input pane, or run it through the JSON formatter first to find the problem.
- 2
Choose indentation for the XML
Two spaces, four spaces or tabs. Nested elements indent one unit per level; an XML declaration is always emitted at the top.
- 3
Check the root and any renamed elements
A note appears when the output had to be wrapped in a
<root>element. Scan for any element name containing underscores where your JSON key had a space or an awkward character.
How the root element is chosen
XML allows one and only one root. The converter applies a simple rule that produces the most natural output for the common case:
- An object with exactly one top-level key uses that key as the root element.
{ "order": { … } }becomes<order>…</order>with nothing artificial added. If you can shape your JSON this way before converting, do — it gives the cleanest result. - An object with several top-level keys is wrapped in a synthetic
<root>element, since each key would otherwise become a sibling at the top level and the document would not be well-formed. A note tells you this happened. - A top-level array is also wrapped, with each item becoming a repeated child element. JSON arrays are anonymous, XML elements are named, so the wrapper is what supplies the name.
- A top-level scalar — a bare string or number — is wrapped too. It is legal JSON but has no XML equivalent without a container.
If the synthetic name matters to you, restructure the JSON so it has a single top-level key with the name you want. That is a one-line change in most cases and beats post-processing the XML.
Key sanitisation and type flattening
XML element names follow the Name production from the XML specification: they begin with a letter or underscore and continue with letters, digits, hyphens, full stops, underscores or colons. Spaces are forbidden and a leading digit is forbidden.
Keys that break those rules are repaired rather than rejected. A key that would be invalid gets an underscore prefix, and any remaining illegal characters are each replaced with an underscore. So "shipping method" becomes <shipping_method> and "2ndAttempt" becomes <_2ndAttempt>. This is lossy in one specific way worth knowing: two distinct keys can sanitise to the same element name, and you will not be warned. If your JSON has both "a b" and "a-b", check the output.
JSON types do not survive either, because XML text content has no type. A number becomes the digits as text, true becomes the string true, and null becomes an empty self-closing element such as <phone/> — which a consumer will read as an empty string, not as an absent value. That distinction between null and empty is genuinely lost, and it is the most common source of surprise when the XML is fed into a strongly typed consumer.
Reserved characters in values are escaped correctly: &, < and > in text, plus " inside attribute values. You never need to pre-escape your JSON.
Producing attributes and mixed text
The converter reads the same convention that the XML to JSON tool writes, which makes the pair useful together. A key beginning with @ becomes an attribute rather than a child element, and a key named #text becomes the element's text content.
So { "price": { "@currency": "GBP", "#text": "129.00" } } produces <price currency="GBP">129.00</price>. Without those markers you would get <currency>GBP</currency> as a child element instead — perfectly valid, but not what a consumer expecting attributes will accept.
Arrays repeat the element name rather than creating a wrapper: { "tags": ["a", "b"] } produces two <tags> elements side by side. That matches how XML normally models collections and how the reverse conversion reads them back. If you want a <tags><tag>a</tag></tags> shape, nest the array one level deeper in your JSON: { "tags": { "tag": ["a", "b"] } }.
Namespaces are not synthesised. If the consuming system requires namespaced elements, add an "@xmlns" key to the object that becomes your root, and it will be emitted as a declaration.
JSON to XML FAQ
Why is my output wrapped in a <root> element?
Because your JSON had more than one top-level key, or was an array or a scalar, and XML permits exactly one root element. Restructure the JSON so it has a single top-level key if you want that key to be the root instead.
How do I get attributes instead of child elements?
Prefix the key with @. { "item": { "@id": "7", "#text": "kit" } } becomes <item id="7">kit</item>. This mirrors the convention the XML to JSON converter produces, so a round trip keeps attributes as attributes.
What happens to null values?
They become empty self-closing elements, such as <phone/>. XML has no null, so the distinction between "explicitly null" and "empty string" cannot be preserved. If it matters, encode it yourself with an attribute like xsi:nil="true" before converting.
Is the output valid against my XSD?
Almost certainly not without adjustment. This produces well-formed XML from your JSON structure; matching a schema requires the right element names, ordering, namespaces and cardinality, which only a mapping written against that schema can guarantee.
Does anything leave my browser?
No. Parsing and serialisation both run in a Web Worker on your device. There is no upload and no server-side component.
