How the conversion works
Click Convert (or press Ctrl + Enter) and the XML is parsed by your browser's DOMParser. If the document is not well-formed, the parser error is shown and nothing is converted. Otherwise the tool walks the element tree from the root down, applying a small set of fixed rules:
- The output is an object with one key, the root element's name.
- An element with only text becomes a string. An empty element becomes
"".
- An element with child elements becomes an object keyed by child tag name, in the order each name first appears.
- Two or more children with the same name become an array. A single child does not.
- With Keep attributes checked, attributes go into an
@attributes object, and any text on that element goes under #text.
- Text is trimmed, and entities like
& are decoded to the characters they stand for.
The result is printed with JSON.stringify using the indent you pick: 2 spaces, 4 spaces, or Minify for a single line.
Example: an order from a legacy API
<?xml version="1.0" encoding="UTF-8"?>
<order id="A-1042" currency="EUR">
<customer>
<name>Lena Fischer</name>
<email>[email protected]</email>
</customer>
<items>
<item sku="KB-01" qty="1">
<title>Mechanical keyboard</title>
<price>89.90</price>
</item>
<item sku="MS-07" qty="2">
<title>Wireless mouse</title>
<price>24.50</price>
</item>
</items>
<note/>
<paid>true</paid>
</order>
converts, with attributes kept and Indent: 2, to:
{
"order": {
"@attributes": { "id": "A-1042", "currency": "EUR" },
"customer": {
"name": "Lena Fischer",
"email": "[email protected]"
},
"items": {
"item": [
{
"@attributes": { "sku": "KB-01", "qty": "1" },
"title": "Mechanical keyboard",
"price": "89.90"
},
{
"@attributes": { "sku": "MS-07", "qty": "2" },
"title": "Wireless mouse",
"price": "24.50"
}
]
},
"note": "",
"paid": "true"
}
}
(The @attributes objects are shown on one line here to save space; the tool prints them expanded.) Notice that price, qty and paid are strings, and that the empty <note/> became an empty string. Your code can reach the first title with data.order.items.item[0].title.
Pitfalls when consuming the JSON
The single-item array problem
If the order above had only one <item>, items.item would be an object instead of an array, and item.map(...) would throw. This is the most common bug with any XML to JSON mapping, because XML itself cannot tell a list of one from a single value. Normalize with [].concat(items.item) before looping.
Element order between different names
Children are grouped by name, so <a>1</a><b>2</b><a>3</a> becomes {"a": ["1", "3"], "b": "2"}. The fact that b sat between the two a elements is gone. That is fine for records, but not for documents where sequence carries meaning, such as XHTML or DocBook.
Mixed content
For <p>Hello <b>big</b> world</p> the output is {"b": "big", "#text": "Hello world"}: all text pieces are joined into one #text value and the position of the bold word is lost. Rich text should be kept as XML or HTML.
Attributes turned off
Without attributes, <img src="a.png"/> becomes "". Keep attributes on for any format that stores data in them, such as SVG, Atom links, or Maven POM files.
What is not carried over
- Comments and processing instructions are removed.
- CDATA sections become ordinary strings, so
<![CDATA[if (a < b)]]> turns into "if (a < b)".
- Namespace prefixes stay in the key names (
"media:thumbnail") and xmlns declarations appear as normal attributes. Namespace URIs are not resolved.
- No type detection, no schema, and no option to rename
@attributes or #text.
When to use a different tool
- If conversion fails and the error is unclear, check the input in the XML Validator.
- To reformat the JSON output or sort its keys, use the JSON Formatter.
- To go the other way, use JSON to XML.
- If the records are flat and you need a spreadsheet, convert here and then use JSON to CSV.
Frequently asked questions
How are XML attributes represented in JSON?
With Keep attributes checked, an element's attributes are collected into an object under the "@attributes" key, so they cannot collide with child element names. If that element also has text, the text goes under "#text". Uncheck the option to drop attributes entirely.
Why is one element an object and another an array?
Sibling elements with the same tag name are grouped into an array only when there are two or more of them. A single child stays a plain object or string. If your code expects an array, wrap single values yourself, for example with Array.isArray(x) ? x : [x].
Why are numbers and booleans output as strings?
XML has no data types without a schema: 44.95 and true in element text are just characters. The converter does not guess types, so every value is a JSON string. Convert them in your code, where you know which fields are numeric.
What happens to comments, CDATA, and namespaces?
Comments and processing instructions are dropped. CDATA content is treated as ordinary text, so it appears as a plain string. Namespace prefixes stay in the key names (for example "media:thumbnail"), and xmlns declarations appear as attributes.
Can I convert the JSON back to the same XML?
Not exactly. The order of differently named siblings, comments, and the position of text around child elements are lost in conversion, so a round trip produces equivalent data but not identical XML.
Does the tool send my XML anywhere?
No. Parsing uses the DOMParser built into your browser and the conversion runs in the page. Import URL fetches the file directly from your browser.