HandyTools Hub

XML to JSON Converter

Convert between XML and JSON formats instantly

Convert XML to clean JSON and back in the browser. Attributes, repeated elements, and mixed text are mapped with the widely used @ and #text conventions, so a round trip preserves your data. Paste an API response, a config file, or an RSS feed and get readable JSON, or turn JSON into an indented, valid XML document.

The Mapping Rules

XML can express things JSON cannot: one element may carry attributes, hold text, and contain children at the same time. This converter represents that with a small, symmetric set of rules.

XML constructJSON representation
Attribute id="42"Key "@id": "42"
Leaf text, no attributes or childrenPlain string value
Text alongside attributes or children"#text": "..."
Repeated sibling tagArray of values
CDATA sectionText content

The symmetry is the important part: keys starting with @ are written back as attributes, #text becomes the element’s text, and an array becomes repeated elements. That is what makes XML → JSON → XML a stable round trip.

Worked Example: A Users Document

Take this input:

<users>
  <user id="1">
    <name>Alice</name>
    <email>alice@example.com</email>
  </user>
  <user id="2">
    <name>Bob</name>
    <email>bob@example.com</email>
  </user>
</users>

The root element name becomes the outer key. Each user carries an @id attribute plus child elements, so each becomes an object with @id, name, and email. Because two user elements are siblings with the same tag, the user key becomes an array:

{
  "users": {
    "user": [
      { "@id": "1", "name": "Alice", "email": "alice@example.com" },
      { "@id": "2", "name": "Bob", "email": "bob@example.com" }
    ]
  }
}

The inner name and email elements have neither attributes nor children, so each collapses to a plain string rather than an object.

Mixed Content and CDATA

When text coexists with attributes, it moves under #text. <price currency="USD">9.99</price> becomes {"price": {"@currency": "USD", "#text": "9.99"}}. When text coexists with child elements, all text fragments are concatenated first and then stored once under #text, which means mixed content loses its exact interleaving. A CDATA block is treated like text, so <script><![CDATA[if (a < b) {...}]]></script> yields the raw contents as the element’s string value without entity decoding surprises.

JSON to XML: Roots, Indentation, Escaping

In the reverse direction, a single-key object becomes its own root element, while multiple keys, an array, or a primitive is wrapped in <root>. You can choose 2-space or 4-space indentation. The output always starts with <?xml version="1.0" encoding="UTF-8"?>. Text is escaped for &, <, and >, and attribute values are additionally escaped for double quotes. Key names are validated against XML name rules: they must start with a letter or underscore and may contain letters, digits, dot, underscore, colon, or hyphen. A name with a space or a leading digit is reported as an invalid name instead of producing broken markup.

Common Mistakes and Limits

  • Expecting typed values. Everything in XML is text, so numbers and booleans arrive as JSON strings. Cast them yourself when the type matters.
  • Relying on mixed-content order. The text is concatenated and trimmed, so the position of child elements relative to text is not recoverable.
  • Forgetting that arrays need repeated tags. A JSON array of objects becomes repeated elements with the same tag; there is no separate list wrapper.
  • Using invalid key names. Spaces, leading digits, and other illegal characters in a JSON key make the JSON → XML conversion fail with an invalid-name error.
  • Assuming attribute order survives arbitrarily. Attributes are emitted in JSON key order, and in XML → JSON the @ keys are inserted before child element keys, so ordering is stable but not necessarily the original document order.
  • Pasting a huge document into the copy button. Very large pretty-printed output is unwieldy on the clipboard; use the download button instead.

Where It Fits

  • Legacy and SOAP APIs. Many enterprise services still return XML. Convert a response once to inspect its shape in a JSON viewer, then code against the @ and #text keys.
  • Config migration. Files such as pom.xml, web.config, or an Android manifest convert to JSON that is easier to diff and transform with a script.
  • RSS and Atom feeds. A feed’s items become a JSON array under the channel key, ready for filtering and rendering without an XML library.
  • Data interchange. When a downstream system only accepts XML, build the object as JSON and let the tool emit a well-formed document with escaping handled.
  • Round-trip checks. Convert XML to JSON and back to confirm the two directions agree before wiring them into a pipeline.

One caveat applies to all of these: the mapping is a convention, not a universal standard. If another system expects attributes inline or wraps metadata under a key like _attributes, its XML-to-JSON output will not match this one even though both are valid JSON. Match the convention your consumer expects, and do not assume a round trip through another tool lines up.

For large feeds, prefer the download button over copy: pretty-printed JSON of a few thousand items is long, and the browser handles a file better than a selection. The converter does not stream, so a very large document is held in memory as text on both sides of the conversion. Split enormous files into per-item chunks if the page becomes sluggish.

Frequently Asked Questions

How are XML attributes represented in the JSON output?

Every attribute becomes a key prefixed with @ on the object for its element. <user id="42"> becomes {"user": {"@id": "42"}}. Going back the other way, any key beginning with @ is written as an attribute on that element.

When does text become a plain string instead of #text?

An element with no attributes and no child elements collapses to its trimmed text as a plain JSON string. As soon as the element also has attributes or child elements, its text is stored under the #text key instead, because there are other keys sharing the object.

How are repeated sibling elements handled?

A second sibling with the same tag name promotes that key to an array and appends to it. <users><user>Alice</user><user>Bob</user></users> becomes {"users": {"user": ["Alice", "Bob"]}}. In the reverse direction a JSON array is expanded back into repeated elements.

What happens to mixed content where text sits between child elements?

All text nodes inside an element are concatenated, trimmed, and stored once under #text. The interleaving order is lost, so <p>Hello <b>world</b> again</p> yields #text "Hello again" alongside the b child, not a positional reconstruction.

What root element is used when the JSON has multiple top-level keys?

A single-key object supplies its own root element name. Anything else — multiple keys, an array, or a primitive — is wrapped in an element named root. The document always begins with an XML declaration for version 1.0 and UTF-8.

Are entities decoded and are CDATA sections handled?

Named and numeric character entities in text and attribute values are decoded to their characters. A CDATA section is treated as text content, so it lands in #text or collapses to a plain string exactly like ordinary text.

Reviewed by the HandyTools Hub team · Last updated