Convert JSON to XML
Build XML from JSON: prefixed keys become attributes, arrays repeat their element, and illegal key names are renamed with the changes listed.
- Runs in your browser
- Files are never uploaded
- Free, no account
Marks which JSON keys came from XML attributes. Common choices: @, $, _.
Holds an element's text when it also has attributes or children.
Spaces of indentation per level. Enter 0 to indent with tabs.
Used only when the JSON does not already have a single top-level key.
Your document never leaves this tab — check it yourself—
Starting the network probe…
The counter above wraps fetch, XMLHttpRequest and navigator.sendBeacon in this tab and counts every call. It does not block anything — it just reports.
Two ways to verify independently
- Turn off Wi-Fi or enable airplane mode, then use the tool. It keeps working, because the page is already fully loaded.
- Open your browser devtools, switch to the Network tab, clear it, and run the tool. No new row appears.
Why this matters
In 2025 researchers found that popular online formatters had retained tens of thousands of user-submitted snippets — JSONFormatter.org and CodeBeautify together exposed roughly 80,000 saved documents, many containing live cloud credentials, private keys and internal database connection strings, because “format this” quietly meant “upload this”. A separate incident exposed roughly 3.5 million user PDFs on a document-conversion service. The only structural fix is not sending the data in the first place: this site is served under a Content-Security-Policy whose connect-src contains no third-party origin, so a request off this device cannot be made even by accident.
How JSON structures become XML
| JSON | XML |
|---|---|
{"a": "x"} | <a>x</a> |
{"@id": "1"} on an object | id="1" as an attribute of that element |
{"#text": "x"} alongside other keys | The element’s text content |
{"a": [1, 2]} | <a>1</a><a>2</a> — the element repeats |
{"a": null} | <a/> — an empty element |
true, 42, 1.5 | Their text form; XML has no types |
| A bare top-level array | Wrapped in the root element, one <item> per entry |
The single-root rule
Every XML document must have exactly one root element. JSON has no such constraint, so a conversion has to invent one whenever the input is an array or an object with several top-level keys. When your JSON already has exactly one top-level key — which is the shape you get back from the XML to JSON converter — that key is used as the root and no extra wrapper is added. Otherwise the root name field is used.
Why some keys get renamed
XML element names are far more restricted than JSON keys. A name must start with a letter, underscore or colon; it may contain letters, digits, hyphens, underscores, colons and full stops and nothing else; and it may not begin with the letters “xml” in any combination of cases, which is reserved. JSON keys have no restrictions at all — spaces, emoji, empty strings and leading digits are all legal.
Illegal characters are replaced with underscores and a leading digit is prefixed. Every rename is listed under the output, because a silent rename is how a downstream XPath quietly stops matching.
Escaping is handled for you
Values containing &, < or > are escaped as they
are written into element text, and attribute values additionally have their double quotes escaped.
That is the correct place to escape — at insertion, on the value alone. You do not need to
pre-escape your JSON, and doing so produces &amp; in the output.
When JSON to XML is the right move
- Legacy integrations. A modern service produces JSON; a SOAP endpoint, an EDI gateway or a mainframe interface wants XML.
- Feeds. RSS, Atom and sitemaps are XML formats with fixed element names — generate the structure here and adjust the names.
- Config formats. Maven, Android, .NET and Spring all consume XML; a generator that works in JSON needs to emit it.
- XSLT. If you need to transform data with XSLT, it has to be XML first.
What the output is not
It is well-formed XML, not schema-valid XML. Element names, ordering and cardinality come from your JSON, not from an XSD, so a service expecting a specific grammar will very likely reject the first attempt. Use this to get the shape and the escaping right, then adjust the names to match the schema you are targeting, and validate with the XML validator before sending.
Questions
How do I make a JSON key become an attribute?
Prefix it with the attribute marker — `"@id": "1"` produces `id="1"` on the element rather than a child element. Change the marker in the options if your data uses `$` or `_`.
What happens to an array?
It repeats the element. `{"items": {"item": [1, 2]}}` becomes two `<item>` elements inside `<items>`. A bare top-level array is wrapped in the root element and each entry becomes an `<item>`, since XML must have exactly one root.
Why was one of my keys renamed?
XML element names cannot start with a digit, cannot contain spaces or most punctuation, and cannot start with the letters "xml" in any case. Illegal characters are replaced with underscores and every rename is listed under the output so nothing changes silently.
Does it produce a declaration and an encoding?
Yes, `<?xml version="1.0" encoding="UTF-8"?>` by default, and you can switch it off if you are generating a fragment to embed in a larger document. The output is UTF-8 in practice because that is what your browser produces.