JSON ⇄ XML Converter
Convert JSON to XML and XML back to JSON.
This tool runs entirely in your browser. Your data is never uploaded, never stored, and never leaves your device.
Conversion runs in both directions here: a JSON document becomes an XML tree wrapped in a <root> element, and an XML document becomes JSON keyed by tag name, with repeated siblings gathered into an array.
How to use it
- 1Choose the direction with the JSON → XML or XML → JSON button.
- 2Paste the document into the input box.
- 3Press Convert, then copy the result.
Example
- Input
- {"name":"Ada","age":36}
- Output
- <root> <name>Ada</name> <age>36</age> </root>
Arrays lose their key on the way out: a "tags" array of two strings becomes two sibling <item> elements, not a <tags> wrapper.
What happens to your data
Going out to XML, the builder escapes exactly three characters — &, < and > — and writes values as element text, so nothing is interpreted and no attribute is ever emitted. Coming back the other way, DOMParser reads the document as application/xml and the walker looks only at element children and textContent, which is why attributes are silently dropped. Both paths are functions called on the string already sitting in the textarea; there is no request behind the Convert button and no copy of either document afterwards.
Last updated August 2026
Something at the other end wants XML and everything you have is JSON — or the reverse, and a supplier feed or an old SOAP endpoint has arrived in angle brackets when your code expects objects. Converting between the two is a five-second job right up to the moment the data has an array in it.
Decide first whether you need to read the data or to interchange it. Reading it — checking a field name, seeing what a response actually contains — is what a straight structural conversion is for. Interchange, where a document has to survive the trip out and back unchanged, needs a convention both sides have agreed: something like BadgerFish, or a mapper told in advance how to write arrays, types and attributes. A generic converter cannot invent that agreement.
The reason is that the two formats do not describe the same universe. JSON has arrays, numbers, booleans and null; XML has none of those, and everything between two tags is text. XML has attributes, namespaces, comments and an order that carries meaning; JSON has nowhere to put any of it. Every converter picks a lossy answer to those mismatches, and the useful question is which losses it chose.
The common mistake follows: assuming a round trip hands back what you started with. It does not. Run a small sample both ways and look at what changed before building on top of it.
How it works
Toolvore walks the structure in the page itself rather than sending it anywhere. Going out to XML, JSON.parse builds an object and a recursive builder writes it out, using each key as a tag name and wrapping everything in a root element; null becomes an empty self-closing tag, and numbers and booleans are written as element text, so the type is gone. Arrays are the lossy part: the key is discarded and each entry is written under a generic item tag, so nothing in the output records what the list was called. Keys become tag names unchecked, and no XML declaration is written above the root. Coming back the other way, a walker over the parsed document keeps only element children and their text — attributes and comments are dropped, text sitting alongside child elements is discarded, every leaf returns as a string, and repeated sibling tags become an array only when there are two or more of them.
Common use cases
- Checking what a legacy SOAP response actually contains
- Sketching a sample XML payload from the JSON in a ticket
- Turning an XML config fragment into JSON for a test fixture
- Reading a supplier feed that arrives in angle brackets
- Spotting which fields a partner's XML document carries
Frequently asked questions
How do you represent a JSON array in XML?+
XML has no array type, so every convention fakes one with repeated sibling elements. One style writes a plural container holding singular children — a tags element with three tag elements inside. Another writes them bare with no container at all, which is the approach taken in the JSON to XML direction here. Both are valid XML and neither is recoverable on its own, because nothing in the document says whether a lone element is a list of one or an ordinary field. Agree the convention with whoever consumes the file before either side writes code against it.
What happens to XML attributes when you convert to JSON?+
They have to go somewhere, and JSON has no separate slot, so conventions invent one — usually a prefix such as an at sign on the key, with the element's own text under a reserved name. The alternative is to drop them, which is what the XML to JSON direction does here: the walker looks at element children and their text only, so an id or a lang written as an attribute disappears with no warning. Anything carrying real information in attributes — most configuration formats, and a lot of older enterprise XML — needs a mapper you have configured, not a generic pass.
Why did my numbers and booleans come back as strings?+
Because XML has no types. Everything between two tags is text, and a document only knows that 42 is a number if a schema says so — which is what XSD is for, and a bare document does not carry it. Going out to XML here, a number is written as its text; coming back, every leaf is read as a string, so 42 returns as characters and true returns as a word. The case that bites is a reference with leading zeros, which survives fine as text and gets quietly mangled by anything eager to make it a number.
Is my data sent to a server when I convert it here?+
No. Both directions are ordinary functions called on the text already sitting in the box: JSON.parse and a recursive builder one way, the browser's built-in DOMParser and a walker the other. Nothing leaves the tab — no upload step, no server round trip, and nothing kept once you close it, since the input and result are component state and nothing else. That matters given what tends to get converted: API responses with customer records in them, payment feeds, config files listing internal hostnames. Switching direction empties both boxes on the spot as well.
Why does my XML fail to parse?+
Four causes cover nearly all of it. XML allows exactly one root element, so a fragment with two top-level tags is not a document and gets rejected. Tags are case-sensitive, so a closing tag capitalised differently closes nothing. A bare ampersand is illegal and has to be written as an entity, and the same goes for a less-than sign. And an entity HTML defines but XML does not — a non-breaking space is the usual culprit — fails unless the document declares it first. The message here is a flat invalid notice with no line number, so scanning for those four is quicker.
Why is the XML I generated rejected by another tool?+
Most likely the tag names. XML element names cannot contain spaces, cannot begin with a digit or with punctuation other than an underscore, and cannot begin with the letters xml in any casing. JSON keys have none of those restrictions, so a key such as first name, or one starting with a year, produces a document no parser will accept — and nothing here checks a key before writing it out as a tag. Rename the offenders in the JSON first. The other complaint is a missing declaration line: none is written, so add it above the root yourself if the consumer insists.
Should a new API use JSON or XML?+
JSON, in most cases where the choice is genuinely free — it is smaller on the wire, it maps onto the data structures of every mainstream language, and browsers parse it natively. XML earns its place where documents rather than objects are the point: mixed content where text and markup interleave, validation in XSD, signatures over part of a document, and namespaces that let two vocabularies share a file without collision. In practice the choice is rarely free. Finance, government, healthcare, publishing and anything speaking SOAP settled on XML long ago.
What happens to XML namespaces in the conversion?+
Nothing good, in a generic conversion. A namespace binds a prefix to a URI so that two vocabularies can use the same local name without ambiguity, and it is the URI that carries the meaning, not the prefix. JSON has no equivalent. Here the prefix survives as part of the key while the declaration that gave it meaning does not, leaving you a key with a colon in it and no record of what it pointed at. If namespaces matter to your document, keep the original beside whatever you convert and map it with something told which URIs to expect.
Used in these workflows
Related tools
JSON Formatter & Validator
Format, validate, and minify JSON documents.
Cron Expression Parser & Builder
Build cron expressions and see their next run times explained.
QR Code Generator
Generate a downloadable QR code from any text or URL.
URL Parser
Break a URL into protocol, host, path, and query parameters.