DevToolsmith

JSON to XML Converter

Convert JSON to well-formed XML. Keys starting with @ become attributes, #text becomes the element text, arrays repeat the element, and keys that aren’t valid XML names are fixed and reported. Numbers are copied exactly, never rounded.

Runs 100% in your browser — nothing is uploaded

JSON
Tip: drop a file here256 chars · 256 bytes · 10 lines
XML
327 chars · 327 bytes · 15 lines

How JSON maps to XML

JSONXML
Object with one key
{"note": {"to": "Ana"}}
<note><to>Ana</to></note>
Key starting with @
{"book": {"@id": "b1", "title": "XML"}}
<book id="b1"><title>XML</title></book>
#text next to attributes
{"price": {"@currency": "EUR", "#text": "9.50"}}
<price currency="EUR">9.50</price>
Array
{"list": {"item": ["a", "b"]}}
<list><item>a</item><item>b</item></list>
null and empty string
{"user": {"middleName": null}}
<user><middleName/></user>
Key that isn’t a valid XML name
{"order": {"first name": "Ana", "2fa": true}}
<order><first_name>Ana</first_name><_2fa>true</_2fa></order>

JSON to XML in code

Python (xmltodict)
# pip install xmltodict  (same @attribute / #text convention)
import json, xmltodict

xml = xmltodict.unparse(json.loads(data), pretty=True)
JavaScript (fast-xml-parser)
import { XMLBuilder } from 'fast-xml-parser';

const builder = new XMLBuilder({ ignoreAttributes: false, attributeNamePrefix: '@', textNodeName: '#text', format: true });
const xml = builder.build(JSON.parse(data));

Going the other way? Use XML to JSON. To query the result, try the XPath tester, or tidy existing XML with the XML formatter.

Frequently asked questions

How do I make a value an XML attribute?

Start its key with @: {"book": {"@id": "b1"}} becomes <book id="b1"/>. Text that should sit next to attributes goes in a #text key. These are the same conventions the XML to JSON converter uses, so you can convert XML to JSON, edit it, and convert it back. Change or clear the prefix if your JSON uses another convention, such as _ or $.

How are JSON arrays converted?

XML has no arrays, so each item becomes a repeated element with the array’s key as its name: {"tag": ["a", "b"]} becomes <tag>a</tag><tag>b</tag>. A top-level array is wrapped in a root element, with each item in an <item> element; both names can be changed.

What happens to keys that aren’t valid XML names?

XML element names can’t contain spaces or most punctuation, can’t start with a digit, and can’t start with “xml”. Such keys are changed (spaces and invalid characters become _, and an _ is added in front where needed), and every renamed key is listed under the tool, so nothing changes silently.

Are numbers kept exactly?

Yes. Numbers are copied from your JSON as written, so 9007199254740993, 1.10 and 1e-7 appear in the XML unchanged. A converter that runs JSON.parse first would turn the first into 9007199254740992 and the second into 1.1.

Is the output valid XML?

Yes: &, < and > are escaped in text, quotes and line breaks are escaped in attributes, and control characters that XML 1.0 doesn’t allow at all are removed. With one root element and valid names, any XML parser can read the result.