Skip to content
← Code Tools

XML to JSON Converter

Convert XML documents to nested JSON in the browser

XML to JSON Converter

XML is alive and well in legacy systems, configuration files, financial feeds (XBRL, ISO 20022), RSS, SOAP responses, and Office Open XML documents under the hood. JSON is the format every modern tool actually wants. Converting between them is straightforward in concept and full of small decisions in practice: do attributes get a prefix? Do repeating elements become arrays automatically? How is mixed content handled? This tool exposes those decisions as options and runs the conversion entirely in your browser.

How XML Maps to JSON

Elements become object properties. An element with only text content becomes a string value: <name>Derek</name>"name": "Derek". An element with attributes and text gets both, with attributes prefixed (@_ by default) and the text under a #text key: <link href="x">Click</link>{ "@_href": "x", "#text": "Click" }. An element with nested children becomes a nested object. Multiple elements with the same name at the same level become an array of objects — this is configurable, since not every repeated element should always be an array.

Attribute Prefixes and Text Keys

Without a prefix, XML attributes would collide with element child keys (an element named id nested inside one with an id attribute would lose data). The default prefix @_ follows the fast-xml-parser convention. Switch to no-prefix mode if your schema guarantees no collisions and you want cleaner output, or to any custom prefix (@, $, _) that matches downstream expectations. The text-content key for elements with both attributes and text is #text by default, also configurable.

Array Handling for Repeating Elements

By default, fast-xml-parser only creates arrays when it sees the same element name more than once at the same level. A list of one item stays as a single object, which causes problems downstream when consumers expect an array. The always-array option forces specified element names to always be arrays, even when there is only one occurrence. Common case: an RSS feed with one item should still emit items as an array of one, so the downstream loop is unconditional. The element-name list can be enumerated explicitly or set to a pattern (every element matching a regex).

Edge Cases the Parser Handles

CDATA sections (<![CDATA[...]]>) are unwrapped and their content becomes the element's text value. Namespaces are preserved on element names by default (soap:Envelope stays as the key) and can optionally be stripped. Comments and processing instructions are dropped by default. Self-closing tags become empty objects or null depending on the option. Mixed content (text interleaved with child elements at the same level) is the only case where JSON does not have a clean representation — the parser preserves it as best it can, with a warning, but consumers of mixed-content XML typically need a different tool.

Pair this with related tools: JSON ↔ CSV Converter if the next hop is CSV, YAML ↔ JSON Converter for the YAML side, JSON Formatter to pretty-print or minify the result, and XML Formatter to inspect the source XML first.

Frequently Asked Questions

Is the XML uploaded anywhere?+
No. The XML is parsed locally by fast-xml-parser bundled into the page, converted to JSON in memory, and offered as a download or copy-to-clipboard. Nothing is sent to any server.
How are XML attributes represented in the JSON?+
Attributes are prefixed (@_ by default) so they do not collide with element children. The element <a href="x">text</a> becomes { "@_href": "x", "#text": "text" }. The prefix and the text-content key (#text by default) are both configurable.
When does the parser emit an array versus a single object?+
By default, an element name that appears more than once at the same level becomes an array; a single occurrence stays as a single object. The always-array option forces specified element names to always be arrays even with a single occurrence — useful when downstream code expects an array regardless of count.
How are namespaces handled?+
By default, namespace prefixes are preserved on element names (soap:Envelope stays as soap:Envelope). You can enable namespace stripping in the options, which drops the prefix and uses just the local name (Envelope). For documents that mix namespaces, stripping is risky — keep prefixes on if you are not sure.
Does it preserve order of mixed content?+
Mixed content (text interleaved with child elements at the same level) is rare in well-designed XML but common in document-oriented XML like XHTML. The parser preserves it as best it can: text and elements appear in the resulting object in source order, with text fragments under #text keys. If you find yourself fighting mixed content often, consider whether a different output format (HTML or Markdown) might serve better.
What about CDATA sections?+
CDATA sections are unwrapped automatically. Their content becomes the element's text value, so consumers do not need to handle CDATA specially. The original CDATA wrapper is not preserved — if you need to round-trip back to XML with CDATA intact, you will need a dedicated XML library, not a JSON intermediate.
Can I convert very large XML files?+
fast-xml-parser is a tree-building parser, not a streaming parser, so the entire document is held in memory during conversion. Files up to tens of megabytes work fine in a browser tab. For multi-gigabyte XML feeds (financial filings, ETL exports), use a streaming parser server-side instead.
Why not just use a regex?+
Regex-based XML parsing is a long-running internet joke for a reason. XML allows nested elements, attribute quoting variations, namespaces, CDATA, comments, and processing instructions, and any regex that handles all of them is more code than just using a real parser. fast-xml-parser handles every standard case correctly and runs in tens of milliseconds for typical-sized documents.

Built by Derek Giordano · Part of Ultimate Design Tools

Privacy Policy · Terms of Service