Convert JSON to XML
JSON has no root element and XML has no types. Both gaps are choices someone has to make, and this converter hands them to you instead of guessing.
- SECURE
- NO UPLOADS
- NO SIGNUP
- BROWSER BASED
- FREE
- FOREVER.
Support us with a link or a share
- Size
- —
- Root
- —
- Elements
- —
- Changed
- —
Nothing at the counter yet. Paste JSON, drop a .json file on the JSON panel, or press Use an example.
Used when the top level is an array or has more than one key. Empty means root.
Names entries of a top-level array or an array inside an array. Empty means item.
Keys starting with this become attributes. Empty keeps every key an element.
A key with this name becomes the element’s own text.
JSON to XML has to invent two names before it can start
Going this direction looks easier than the other one, and in one sense it is: JSON is the smaller language, so nothing in it lacks an XML shape. What it lacks instead are two things XML requires, and a converter has to invent both. The first is a root element. XML documents have exactly one outermost element; a JSON document whose top level is an array, or an object with three keys, has no candidate for it. The second is a name for the entries of an array, because XML expresses a list as a repeated element and a bare array has no key to repeat.
Most converters answer both questions silently, usually with the words root and
item, and you find out what they chose when the system receiving the document
rejects it. Here both are fields you can edit, prefilled with the conventional answers. When
the top level is an object with exactly one key, that key becomes the root and the setting
stays out of the way — in that case the document did tell us, and inventing a name over the
top of it would be worse than useless.
Every value becomes text, and the receipt says so
XML has no types. Without a schema, everything between two tags is characters, so
true becomes four letters and 42 becomes two digits. This is not a
shortcoming of the conversion, it is what the target format is, but it is a real consequence
for whoever reads the XML afterwards and it is counted rather than glossed over. So is
null, which has no XML equivalent at all: it becomes an empty element, and an
empty element is indistinguishable from an empty string when it comes back.
Long integers get particular care. The JSON is read with a scanner that keeps the digit
sequence from your source rather than with JSON.parse, which converts to a
floating point number first. The difference is not theoretical: an identifier of nineteen
digits has already lost its tail before an ordinary converter ever sees the value, and it
then writes those changed digits into XML where nothing downstream can tell. Any value where
that would have happened is listed on the receipt with what it would have become.
A renamed key is how a field disappears
XML element names have rules. They cannot contain a space or a slash, and they cannot begin with a digit. JSON keys have no rules at all. So some keys cannot become elements as written, and every converter rewrites them — the question is only whether it tells you. This one lists each rename by name, because a field that quietly changes name is a field that quietly disappears from the report at the other end.
The rewriting itself is careful about a distinction that is easy to get wrong. A space is
invalid anywhere in an XML name, so two words becomes two_words. A
digit is a perfectly valid name character that merely may not come first, so
1book becomes _1book and not _book. Replacing the digit
would be shorter and would also let two different keys collapse into one element name, which
is precisely the kind of silent damage the rename list exists to prevent.
The same mapping in both directions
This tool and the XML to JSON converter are two addresses over one shared mapping, written once in one file. That matters more than it sounds: two separately written converters drift apart, and the day they disagree about what an attribute is called is the day a round trip stops closing. A round-trip test over a fixture with namespaces, attributes, repeated siblings and mixed content runs on every build. What does not round-trip is stated on the receipt rather than left for you to discover.
Where to go when this is the wrong tool
Should the source refuse to parse at all, the JSON validator identifies which dialect you really have: JSONC and JSON5 pass for JSON right up until a strict reader throws them out. To re-indent or shrink the source first, use the JSON formatter; to tidy what comes out of here, use the XML formatter. Rows and columns belong in JSON to CSV, and configuration files that arrive as YAML have their own entrance.
Nothing leaves the tab
Everything happens inside the page you are looking at. No endpoint receives your data, no request carries it off the machine, and neither a log nor the address bar records a character of it. Nor will size get you turned away: a large document converts like a small one, with a note about its likely memory cost shown ahead of the work instead of after the browser has begun to suffer, and anything beyond 64 KB handed to a worker thread.
Questions
Why do I have to name the root element?
Because JSON does not have one and XML requires exactly one. A JSON document whose top level is an array, or an object with three keys, has no single thing that could become the outermost element, so a name has to come from somewhere. Most converters pick one silently — usually the word root — and you find out when the receiving system rejects the document. Here it is a field you can edit, prefilled with root. When the top level is an object with exactly one key, that key becomes the root and the setting is not used, because in that case the document did tell us.
What happens to a key that is not a valid XML name?
It is renamed, and the rename is listed by name on the receipt. XML names cannot contain a space or a slash and cannot begin with a digit, so a key like "two words" becomes two_words and "1book" becomes _1book. Note the difference between those two: the space is invalid anywhere in a name and is replaced, while the digit is a valid name character that simply may not come first, so it is kept and an underscore is added in front. Dropping the digit would let two different keys collapse into the same element name, which is exactly the kind of quiet damage this tool exists to prevent.
Are numbers and booleans preserved?
Their characters are; their types are not, because XML has no types to preserve them in. Without a schema, everything between two tags is text, so true becomes the four characters t-r-u-e and 42 becomes two digits. That is counted and named on the receipt rather than passed off as a faithful conversion. Long integers are handled with particular care: the JSON is read with a scanner that keeps the digit sequence from your source, so a nineteen-digit identifier is written to XML exactly as you typed it rather than as the nearest floating point number. Any value where that mattered is listed separately.
How do arrays become elements?
A key whose value is an array becomes that key repeated once per entry, which is the ordinary XML idiom. An array at the top level has no key to repeat, so each entry is wrapped in the array item name — item by default, and editable. Nested arrays are the one shape with no clean XML form at all: a list of lists has no name for the inner level, so the inner entries are wrapped in the same item name and the nesting is flagged on the receipt rather than silently flattened.
Does the output come back through the other direction unchanged?
For everything except the shapes listed on the receipt, yes — the two directions share one mapping in the same source file, so they cannot drift apart the way two separately written converters do, and a round-trip test over a namespaced fixture is part of the build. What does not round-trip is stated: a null becomes an empty element and comes back as an empty string rather than null, an array of one entry comes back as a plain value unless the other direction is set to always produce lists, and a renamed key comes back with its new name.
Is anything uploaded, and is there a size limit?
Nothing is uploaded. The conversion runs in your browser, there is no endpoint, nothing about your input is logged, and nothing is put in the address bar. No file is rejected for being large. Above 64 KB the work moves to a worker so the page keeps responding, and you are given advice about what the document will cost in memory before the work starts rather than after your tab has already struggled.