DataSwap Fast file & data format converters, no signup

XML to JSON Converter

Paste XML below and get JSON back instantly — parsed with your browser's own DOMParser, not a hand-rolled scanner, so nesting, quoting, and entities are handled exactly the way a real XML parser handles them. Nothing you paste ever leaves your browser.

Convert XML to JSON with the browser's real parser

DOMParser builds an actual DOM tree out of your XML — the same tree the browser would build for a real document — and this tool walks it recursively rather than scanning the raw text for tags. An element with only text content (no child elements) becomes a plain string. An element with child elements becomes an object keyed by child tag name. Attributes land under an "@attributes" key so they're never confused with child elements. And when multiple children share a tag name — <item> siblings, list entries, repeated rows — they collect into an array instead of silently overwriting each other, because repeated elements are the norm in real-world XML, not the exception.

Worked example

Input: <person id="42"><name>Ada Lovelace</name><tag>math</tag><tag>computing</tag></person> (85 characters: one attribute, and three child elements, two of which share the tag tag). Converting produces:

{
  "@attributes": {
    "id": "42"
  },
  "name": "Ada Lovelace",
  "tag": [
    "math",
    "computing"
  ]
}

— 111 characters. Notice tag became a two-item array, not just "computing" overwriting "math". Now try <a><b></a> — the unclosed <b> tag makes this invalid XML, and instead of a blank output or a confusing crash, this tool shows you a plain-language message telling you to check your tags, because DOMParser doesn't throw on bad XML — it returns a document containing a <parsererror> element instead, and this tool checks for exactly that. Building well-formed XML in the first place? The JSON to XML Converter handles the reverse direction.

Frequently asked questions

What happens when multiple elements share the same tag name?

They collect into a JSON array instead of overwriting each other. The first <item> becomes a value, and the moment a second sibling <item> shows up, that key is converted into an array and both values are pushed onto it — so three <item> siblings become an array of three, not just the last one. This is the single most common gotcha with hand-written XML-to-JSON conversion, and it's why we check for an existing key on every element rather than assuming each tag name appears once.

Where do XML attributes end up in the JSON?

Under an "@attributes" key on that element's object, so they're never confused with child elements — <price currency="USD">19.99</price> becomes {"@attributes":{"currency":"USD"},"#text":"19.99"}. An element with attributes but no children and no text just gets the "@attributes" key with nothing else.

What if my XML isn't valid?

DOMParser doesn't throw a JavaScript error on malformed XML — it silently returns a document containing a <parsererror> element instead, which is easy to miss if you don't check for it. This tool checks for exactly that and shows you a plain-language message instead of an empty box or a confusing crash.

Is my data uploaded anywhere?

No. Parsing happens with the browser's own DOMParser, and the JSON is built with JSON.stringify — both run entirely in your browser. Nothing you paste is sent to a server, stored, or logged. That's true for every tool on this site.

Does this handle XML namespaces or CDATA sections?

CDATA sections are handled correctly because DOMParser resolves them the same way any XML parser must: their content just becomes part of the element's text, indistinguishable from regular text, which is exactly what the XML spec says a CDATA section is. Namespaced elements keep their prefixed tag name (like ns:tag) as the JSON key, so nothing is silently dropped — this tool doesn't do separate namespace-aware key resolution beyond that.