XML to JSON Converter
Convert XML to JSON and JSON back to XML in one place. Free, fast, and everything runs on your device.
@ (e.g. @id);
element text becomes #text when the element also has attributes or child elements, otherwise the value is a plain string;
repeated child elements with the same name become a JSON array.
The same rules apply in reverse for JSON → XML.
XML Input
JSON Output
The mapping rules, in plain English
XML and JSON do not line up neatly, so any converter has to pick a convention. This one uses three rules and applies them in both directions, which is what makes a round trip come back the way it went in.
- Attributes get an @ prefix.
<item id="7">becomes a key"@id": "7"sitting alongside the element's children. - Text becomes #text only when it has company. An element with nothing but text and no attributes collapses to a plain string, so
<to>Ada</to>is simply"to": "Ada". If the element also carries attributes or child elements, its text is parked under a"#text"key instead. - Repeats become arrays. The first time a child name appears it is stored directly. The second time, the existing value is wrapped in an array and both are pushed into it, in document order.
Parsing uses the browser's built-in DOMParser in XML mode and the native JSON parser for the other direction, so you get standards-compliant behaviour and real error messages rather than a regex guessing at your markup. An empty or null value is written back out as a self-closing tag.
A round trip you can try
Paste this into the XML side:
<note id="1" priority="high"><to>Ada</to><to>Grace</to><body>Hello</body></note>
The output is { "note": { "@id": "1", "@priority": "high", "to": ["Ada", "Grace"], "body": "Hello" } }, pretty-printed with two-space indentation. Both attributes arrive as @ keys, the duplicated to elements collapse into an array with Ada first, and body stays a plain string because it has no attributes of its own. Switch to the JSON to XML tab, paste that object back, and you get the same document with an <?xml version="1.0" encoding="UTF-8"?> declaration on top and two-space indenting.
What people bring here
Most of the traffic is legacy data meeting modern code. Typical jobs include reading a SOAP response from an older enterprise API; pulling items out of an RSS or Atom feed; inspecting an Android strings.xml or a Maven pom.xml; checking a sitemap.xml before submitting it; converting a GPX track exported from a GPS watch; and turning a hand-written JSON config into the XML shape a tool insists on. It doubles as a viewer, since JSON output from a deeply nested document often reads better than the original angle brackets.
What does not survive the trip
Comments and processing instructions are dropped, since neither has a JSON equivalent. Text inside a CDATA block is read as ordinary text, which means the CDATA wrapper is gone and any special characters are escaped normally when converted back. Every value is a string: <qty>7</qty> gives you "7", not 7, and no attempt is made to guess types. Whitespace is trimmed, so indentation in your source does not become data. Mixed content is the real limitation to watch. In <p>Hello <b>world</b>!</p> the two loose text runs are joined into a single #text value and their position either side of the <b> element is lost, so prose markup such as XHTML fragments will not round trip cleanly. Namespace prefixes are kept as part of the element name and xmlns declarations come through as ordinary @ attributes, but a root element name containing a colon is not recognised as a valid tag name on the way back and ends up wrapped in an extra <root> element. Going from JSON to XML also expects a single top-level key; an array or several sibling keys at the top get wrapped in <root> so the result is still well-formed.
Errors, and how big an input can be
If your XML is malformed, the parser error is shown in full under the boxes, usually naming the line and the offending token. If your JSON is malformed, the browser's message is shown with a line and column worked out from the character position, so "Unexpected token } in JSON at position 214" arrives with "(line 12, column 9)" attached. Both documents are held entirely in memory, so a multi-megabyte feed will pause the tab while it parses, and something in the tens of megabytes may exhaust it on a phone. There is no file picker: this is a paste-in tool, and the Download button saves the result as converted.json or converted.xml. Everything happens in your browser and nothing is uploaded to a server, so API keys and customer records in a payload stay on your machine. Use is free.
When to use a different tool
If your JSON is valid and you only want it indented, sorted or minified, the JSON Formatter is the quicker stop. Spreadsheet exports belong in CSV to JSON. For payloads wrapped in base64, decode them first with Base64 Encode and Decode. To compare two versions of a config file, use Text Diff, and to build realistic sample records for testing a schema, try the Fake Data Generator or verify a payload checksum with the Hash Generator.
Frequently asked
How are XML attributes represented in the JSON?
Every attribute becomes a key with an @ prefix on the same object as the element's children, so an item carrying id="7" produces a key of "@id" with the value "7". The prefix is what lets the reverse conversion tell attributes apart from child elements.
What happens when the same element appears more than once?
The repeated elements are gathered into a JSON array under one key, in the order they appear in the document. An element that appears only once is stored directly rather than as a single-item array.
Are numbers converted to JSON numbers?
No. XML has no type information, so every value comes out as a string and a quantity of 7 becomes "7". If you need real numbers, cast them in your own code after conversion.
Why did my document lose its comments?
JSON has no way to express an XML comment or a processing instruction, so both are discarded during conversion. CDATA sections are kept but their wrapper is not, because the content is read as ordinary text.
Does my data leave the browser?
No. Parsing and conversion both run locally using the browser's own XML and JSON engines, and nothing you paste is sent anywhere.