JSON → XML Converter
Convert JSON to XML online
Paste JSON on the left and get clean, well-formed XML on the right — instantly, with attributes and arrays handled correctly and the result validated. All in your browser.
🔒 100% private — conversion happens entirely in your browser. Nothing is uploaded or stored.
From JSON to well-formed XML in one step
Indentio turns JSON into XML as you type, guaranteeing a single valid root and preserving structure. Attributes, nested objects, and arrays are all mapped predictably, and the output is checked so you always know it’s well-formed.
Most people arrive here for one of three reasons: a modern service speaks JSON and a legacy SOAP or enterprise endpoint expects XML; a tool needs its configuration in XML and the data exists as JSON; or an RSS, sitemap, or feed document has to be generated from JSON records. All three are the same operation, and all three run into the same handful of mismatches between the two formats — which are worth understanding before you trust the output.
The mapping rules
- Objects → nested elements, one per key.
- Arrays → repeated elements with the same tag name.
- Keys starting with
@_→ attributes (e.g."@_id": "1"becomesid="1"). - Scalars → the text content of their element.
#text→ the text of an element that also carries attributes.null→ an empty element,<key/>.
A worked example
Everything above in one document — attributes, nesting, an array, and a null:
{
"order": {
"@_id": "A-417",
"@_currency": "EUR",
"customer": "Ada Lovelace",
"note": null,
"item": [
{ "@_sku": "X1", "qty": 2, "price": 9.95 },
{ "@_sku": "X2", "qty": 1, "price": 24.00 }
]
}
}becomes:
<order id="A-417" currency="EUR">
<customer>Ada Lovelace</customer>
<note/>
<item sku="X1">
<qty>2</qty>
<price>9.95</price>
</item>
<item sku="X2">
<qty>1</qty>
<price>24</price>
</item>
</order>Note two things in the output. The array of two items became two sibling<item> elements with no wrapper — XML represents repetition by repeating the tag, so the array itself has no separate existence. And 24.00 came out as24, because JSON normalises the number before XML ever sees it.
Legal XML element names
This is the one thing that reliably breaks a conversion. Any string can be a JSON key; only some strings can be an XML element name. A name must start with a letter or underscore and may then contain letters, digits, hyphens, underscores, and periods — no spaces, no#, $, /, or %, and it may not start with a digit or with the letters xml in any casing.
| JSON key | Result | Fix |
|---|---|---|
"first name" | Invalid — space | "first_name" or "firstName" |
"123" | Invalid — starts with a digit | "n123" or "_123" |
"price($)" | Invalid — parentheses and $ | "priceUsd" |
"a:b" | Reads as a namespace prefix | "a_b" |
"" | Invalid — empty | Give the key a name |
"order-id" | Valid | — |
The converter still shows you the output when a key is illegal, and flags the result as not well-formed so you can see exactly which key caused it. Renaming keys in the source is the only correct fix — silently rewriting them would produce XML that no longer matches the schema anyone downstream expects.
What JSON can express that XML cannot
The two formats have genuinely different data models, so some information has nowhere to go:
- Types disappear. XML text content is always text.
"qty": 2and"qty": "2"both become<qty>2</qty>, and only a schema can say which one it was. - Null and empty string collapse. Both produce an empty element. So does an absent key handled carelessly, giving three distinct JSON states one XML representation.
- An empty array vanishes entirely.
"tags": []produces no elements at all, which is indistinguishable from the key having been absent. - A single-element array is indistinguishable from a scalar. One
<item>in the output could have come from an array of one or from a plain object — the ambiguity that makes round-tripping lossy in the other direction. - Arrays of arrays have no direct form. Nesting repetition inside repetition requires an artificial wrapper element that XML consumers will not expect.
- Key order is preserved but not guaranteed meaningful. XML schemas frequently mandate a specific element order; JSON objects carry no such contract, so a technically correct conversion can still be rejected by a strict XSD.
Tips for clean output
- Wrap your data in a single top-level object so you control the root element name rather than getting the generated
<root>. - Rename keys to valid XML names before converting, not after — it is far easier in JSON.
- Use the
@_prefix deliberately. Identifiers, units, and language codes are conventionally attributes in XML; the actual data belongs in elements. - If the XML is destined for a system with a published XSD, check element order against it — a well-formed document can still fail schema validation.
- Need the reverse? Use the XML to JSON converter, which uses the same
@_convention so a round trip is stable.
Go deeper
Frequently asked questions
How do I convert JSON to XML?
Paste your JSON on the left. Valid JSON is converted to well-formed XML on the right automatically — no button needed. Then click Copy result or Download.
How are JSON keys and values mapped to XML?
Each key becomes an element and its value becomes the element’s content. Keys prefixed with @_ become XML attributes, and arrays become repeated elements. This mirrors the convention used by our XML → JSON converter, so a round-trip is stable.
What if my JSON has no single root?
XML needs exactly one root element. If your JSON is an array, a scalar, or an object with several top-level keys, the converter automatically wraps it in a <root> element so the output is always well-formed.
Why does it warn about invalid XML?
Some JSON keys aren’t legal XML element names — for example "first name" (has a space) or "123" (starts with a digit). The converter shows the result and flags it so you can rename those keys.
How is null converted?
As an empty element — "note": null becomes <note/>. XML has no null, so this is a convention rather than a faithful translation: an empty string produces exactly the same output, and the distinction between the two is lost.
Is my data uploaded?
No. Conversion runs entirely in your browser. Your JSON is never uploaded, logged, or stored.