JSON to XML Converter
Paste JSON and convert it to indented, well-formed XML. Objects become elements, arrays become repeated elements, and the result always has a single root.
What this JSON to XML converter does
The converter reads your input with the browser’s built-in JSON.parse and writes it out as an indented XML document that starts with <?xml version="1.0" encoding="UTF-8" ?>. Each object key becomes an element, each array item repeats its parent’s element name, keys that begin with a hyphen become attributes, and the whole result always sits inside a single root element, as XML 1.0 requires.
JSON (RFC 8259) and XML describe data in different ways, so there is no single “correct” conversion. The table below shows exactly what this tool does with each JSON construct.
| JSON | XML produced | What to know |
|---|---|---|
| Object key | Child element of the same name | Invalid names are repaired (see below). |
| Array | The element repeated once per item | No wrapper element is added. Arrays nested directly inside arrays are flattened. |
| String, number, boolean | Element text | XML text has no types, so 2, "2" and true all become plain text. |
null | Empty element, e.g. <manager /> | Indistinguishable from an empty object. |
Empty array [] | Nothing | The key disappears from the output. |
Key starting with - | Attribute on the parent element | {"-id": "7"} gives id="7". |
Key #text | Text content of the parent element | Lets an element have both attributes and text. |
Numbers are written as JSON.parse reads them: 1.50 becomes 1.5, 1e3 becomes 1000, and integers larger than 253 lose precision (12345678901234567890 comes out as 12345678901234567000). Keys that look like whole numbers, such as "123", are moved to the front of their object, because that is how JavaScript orders object keys.
How to use the converter
- Paste JSON into the JSON Input pane. File opens a local file; URL fetches one from a web address (the server must allow cross-origin requests).
- Pick an Indent of 2 spaces or 4 spaces.
- Click Convert. The XML appears in the XML Output pane.
- Use Copy (or the copy icon in the pane header), Download to save
converted.xml, or Clear to empty both panes.
Before you convert, the output pane shows a tree of your JSON input. Tree Viewer switches back to it at any time; clicking a node copies its path, which helps when you are mapping JSON fields to XML elements.
How the root element is chosen
- One top-level key whose value is not an array: that key becomes the root.
{"order": {...}}gives<order>. This is the way to name the root yourself. - Several top-level keys, or a single key holding an array: everything is wrapped in
<root>. Top-level-keys become attributes of<root>. - A top-level array: each item becomes an
<item>element inside<root>. - A bare string or number: the output is a single
<value>element.
How invalid element names are repaired
JSON keys can be any string, but XML names cannot contain spaces or most punctuation and cannot start with a digit. Runs of disallowed characters become an underscore, and an underscore is added in front of a leading digit:
| JSON key | Element name |
|---|---|
first name | first_name |
2fa | _2fa |
123 (a whole number) | element |
ns:tag | ns_tag — colons are replaced, so namespace prefixes are not kept |
@attributes | _attributes |
Attribute names get the same repair, except that a colon is kept so namespace declarations such as -xmlns:atom work: "-my attr" becomes my_attr, and a bare "-" becomes attr.
Example
{"user": {"-id": "42", "name": "Ada", "active": true,
"roles": ["admin", "dev"], "manager": null}}
converts to:
<?xml version="1.0" encoding="UTF-8" ?>
<user id="42">
<name>Ada</name>
<active>true</active>
<roles>admin</roles>
<roles>dev</roles>
<manager />
</user>
To give an element both an attribute and text, use #text: {"price": {"-currency": "GBP", "#text": "9.99"}} becomes <price currency="GBP">9.99</price>. Special characters in text and attribute values (& < > ") are escaped for you.
Common problems and fixes
| Problem | Cause | Fix |
|---|---|---|
Error starting Invalid JSON: | Trailing comma, single quotes, comments or an unquoted key. The rest of the message comes from your browser and is worded differently in Chrome, Firefox and Safari. | See JSON syntax errors explained, or validate in the JSON Formatter first. |
| A value appears as a child element, not an attribute | The key has no leading hyphen. | Rename "id" to "-id". |
Attribute value contains JSON such as {"a":1} | An attribute was given an object or array, which is written as JSON text. | Give attributes a single string, number or boolean, or make the value a child element. |
| The XML will not parse elsewhere | An attribute key contains a space or other character not allowed in XML names. | Rename the key in the JSON. |
| Nested arrays lose their grouping | {"m": [[1, 2], [3]]} becomes three <m> elements. | Wrap inner arrays in objects, e.g. [{"row": [1, 2]}]. |
| A long ID changes its last digits | JSON numbers above 253 cannot be stored exactly in JavaScript. | Store such IDs as strings in the JSON. |
Frequently asked questions
Are JSON data types preserved in the XML?
No. XML element text has no types, so numbers, booleans and strings all become text, and null becomes an empty element. If the receiving system needs types, they must come from an XML Schema (XSD) or from the code that reads the document.
Will converting the XML back give me the same JSON?
Not exactly. The XML to JSON converter uses a different convention: the id="42" attribute above comes back under "@attributes", true comes back as the string "true", and <manager /> comes back as an empty string.
How do I set the name of the root element?
Wrap your data in an object with one key, such as {"catalog": {...}}. That key becomes the root. Without it, the output uses <root>.
Can I add a namespace declaration?
Yes, as an attribute: {"feed": {"-xmlns": "http://www.w3.org/2005/Atom", "title": "News"}} produces <feed xmlns="http://www.w3.org/2005/Atom">; prefixed declarations such as -xmlns:atom work the same way. Prefixed element names such as atom:title cannot be produced, because colons in keys are replaced with underscores.
Does it create an XML Schema or DTD?
No. The output is a well-formed document only. Validation rules have to be written separately for the system that will consume it.
Is my JSON uploaded anywhere?
No. Parsing and conversion run in your browser, so API responses containing customer or internal data stay on your device. The URL button fetches a file directly from your browser, not through a server of ours.