FreeToolsBox

Developers · 8 min read

XML to JSON Conversion: Rules, Examples and Common Errors

Published 2026-10-23 · Updated 2026-10-23

By FreeToolsBox Editorial Team · Editorial disclaimer

A developer works at a desk with several monitors showing code and data, the environment where structured data gets converted.
Photo: conceptseating.com

Converting XML to JSON means reshaping a tree of elements into nested objects, and there is no single official mapping, so every converter follows conventions. The widely used rules are: elements become object properties, attributes are stored under a prefixed key such as @_, repeated elements become arrays, an element's text goes under a #text key when it sits alongside attributes or child elements, and text that is plainly a number or boolean may be converted to one. The XML to JSON converter on this site applies exactly those rules in your browser. This guide walks through each rule with a complete worked example.

Why convert at all? XML still powers invoices, product feeds, configuration files, SOAP services and decades of archived data, while modern JavaScript applications, REST APIs and most NoSQL stores speak JSON natively. A developer receiving an XML feed usually wants to load it into objects they can query, filter and re-serialize without writing a parser from scratch. Conversion is therefore a daily utility task, but it is a translation between two data models with different strengths, not a lossless re-encoding. Knowing what the converter is doing, and what it quietly discards, prevents subtle bugs downstream. The same format-shuffling instinct runs through developer work generally, from configuration files to the color codes covered in hex to RGB explained.

The Conversion Rules

Rule one: elements become structure. A child element becomes a property of its parent's object, named after the tag. An element with only text inside becomes that text as a string (or a coerced number, covered below). An element with children becomes a nested object. Rule two: attributes cannot be properties directly, because an attribute and a child element could share a name and collide. Converters separate them with a prefix; this site's converter uses @_, so id becomes @_id. Other tools use different conventions, which is why JSON produced by one converter may have @id, -id or an attributes object instead. Always check which convention your tool uses before writing code against its output.

Rule three: repetition creates arrays. If a tag appears once inside its parent, it maps to a single object. If it appears two or more times, the property becomes an array of objects, in document order. This is sensible but has a sharp edge: the type of the property depends on how many siblings happen to exist. A feed with one product gives you an object; the same feed with two products gives you an array, and code that expects one shape breaks on the other. Robust pipelines force known repeatable tags into arrays always, or normalize after conversion. Rule four: mixed content, where text and child elements share a parent, pushes the text into a #text key, described next. That rule matters most in prose-like XML such as documentation and article feeds, where text and markup genuinely mix; in pure data XML it rarely appears, and spotting a #text key in output usually means an element was carrying attributes you had overlooked.

Rule five: types are a judgment call. XML has no numbers or booleans; everything is text. A converter may coerce text that is unambiguously numeric, so <price>79.99</price> becomes 79.99 and <stock>14</stock> becomes 14, and the canonical literals true and false may become booleans. The trap is values that merely look numeric: a SKU or ZIP code of 00123 must stay the string "00123", because as a number it would collapse to 123 and corrupt the data. Good converters only coerce canonical forms and preserve leading-zero strings untouched. The same care applies to values like 1e5, dates such as 2026-10-23, and empty elements, which different tools map to an empty string, null or an empty object. Test your converter with these cases before trusting it in production. Dates deserve special suspicion: 2026-10-23 looks structured, but a naive converter either leaves it a string or mangles it into arithmetic, so if dates matter, parse them deliberately after conversion rather than hoping the converter guessed your format.

Worked Example: A Product Catalog

Here is a complete example. The XML input is a small product catalog: <catalog> <product id="p1"> <name>Trail Shoes</name> <price>79.99</price> <stock>14</stock> <tags> <tag>outdoor</tag> <tag>sale</tag> </tags> </product> <product id="p2"> <name>Rain Jacket</name> <price>120</price> <stock>0</stock> </product> </catalog>. Note the details the converter must handle: each product carries an id attribute, product repeats twice, tag repeats twice inside tags, prices are numeric text, and stock of 0 is a real value that must survive conversion rather than being dropped as empty.

Applying the rules produces this JSON: { "catalog": { "product": [ { "@_id": "p1", "name": "Trail Shoes", "price": 79.99, "stock": 14, "tags": { "tag": ["outdoor", "sale"] } }, { "@_id": "p2", "name": "Rain Jacket", "price": 120, "stock": 0 } ] } }. Read it against the rules: the root element catalog becomes the top property; because product appears twice, it is an array; each id attribute sits under @_id as a string (attributes are never coerced, so "p1" stays text, and even a numeric attribute would stay a string); price and stock coerced to numbers because they are canonical; the repeated tag values became an array of plain strings because tag has no attributes or children; and p2 has no tags property at all, since JSON omits what the XML never stated. Two details in that output reward a second look. The tags object wraps the array because the XML nested <tag> inside <tags>; converters preserve structure faithfully rather than flattening it into what you probably meant. And JSON has no way to say that tags existed but were empty unless the XML stated so explicitly, an absence-versus-empty distinction that data pipelines trip over regularly.

The #text Rule for Mixed Content

The #text rule deserves its own example because it surprises people. Consider <note priority="high">Call before Friday</note>. The element holds an attribute and text, but no child elements. There is nowhere obvious for the sentence to live, since the object for note is busy holding the attribute. If your XML is full of such note-style elements, expect #text keys throughout the output and write your access code accordingly, rather than treating the first one as a converter bug. The convention resolves it as { "note": { "@_priority": "high", "#text": "Call before Friday" } }. The same pattern handles elements that mix text and children, though true mixed content, like paragraphs with inline bold tags, converts awkwardly in every tool because JSON objects cannot preserve the interleaving order of text and elements. Comments are simply dropped during conversion, CDATA sections are unwrapped and treated as ordinary text, and processing instructions are ignored.

What JSON Cannot Keep

Some things XML expresses have no JSON equivalent and are lost or mangled. Attribute order disappears, because JSON object keys are unordered; if order mattered semantically, and it rarely should, that information is gone. Namespaces flatten into literal tag names with colons in them, or get stripped, which can merge distinct elements or produce keys that are awkward to access with dot notation. Document-level declarations, entity definitions and DTD information vanish entirely. None of this makes conversion unsafe for the common jobs of feeds, configs and data exchange, but it means XML to JSON is a one-way street: do not plan to round-trip the JSON back into identical XML. The ordering of sibling elements does survive, because it lives in arrays and property order, but the order of attributes within an element does not, and neither does the attribute-versus-element distinction once a later processing step strips the prefixes away.

Common XML Errors That Break Conversion

Converters can only work with valid XML, and the same few errors cause most failures. Multiple root elements are the classic one: XML demands exactly one root, so two sibling documents pasted together will be rejected until you wrap them in a single parent. Unclosed or mismatched tags, like <name>Trail Shoes</product>, break the tree structure and the parser will point at the line where nesting went wrong. Unquoted attribute values, attributes repeated on one element, and raw ampersands or angle brackets inside text (which must be written as &amp; and &lt;) complete the usual list. A descriptive error message naming the position is a sign of a real parser; a tool that silently returns an empty result is hiding the problem from you. Two quieter culprits are a byte-order mark or XML declaration confusing a pasted snippet, and smart quotes picked up from a word processor, which are not valid quote characters in XML at all. Convert from the raw file whenever you can.

Conversion Mistakes to Avoid

The mistakes to avoid are mostly assumptions. Assuming every converter uses the same attribute prefix leads to code hunting for @_id in output that used a different key. Assuming a tag is always an array, or never an array, breaks feeds whose item count changes. Assuming leading-zero codes survive numeric coercion corrupts SKUs and ZIP codes silently, the worst kind of bug, because the output still looks plausible. And assuming conversion is total can strand comments, mixed content or namespace distinctions you actually needed. Convert a small sample by hand, compare it with the tool's output rule by rule, and only then run the full file. If your source is YAML instead, the sibling YAML to JSON converter covers that direction.

Conversion is mechanical once the rules are clear: elements become properties, attributes take the @_ prefix, repetition becomes arrays, text lands under #text when it shares an element with anything else, and only unambiguous values change type. Keep the sample-first habit and the coercion traps in mind, and XML feeds stop being intimidating. When you are ready, paste your file into the XML to JSON converter and compare the output against the catalog example above; if the shapes match your expectations, the rest of the document will follow the same rules.

Frequently asked questions

How are XML attributes converted to JSON?

Attributes cannot sit alongside child elements as plain keys, so converters give them a prefix. On this site the prefix is @_, so id="p1" becomes "@_id": "p1". Other tools use different conventions, so always check a sample of the output before coding against it.

When does an XML element become a JSON array?

When the same tag repeats inside one parent. Two <product> elements become a "product" array with two objects. A tag that appears once stays a single object, which is why robust code normalizes repeatable tags into arrays.

What is the #text key in converted JSON?

It holds an element's text when the element also has attributes or child elements, leaving nowhere else for the text to go. <note priority="high">Call before Friday</note> becomes { "@_priority": "high", "#text": "Call before Friday" }.

Why did my code "00123" lose its leading zeros after conversion?

The converter treated the text as a number, and numbers cannot carry leading zeros. Well-behaved converters only coerce canonical numeric forms and keep values like "00123" as strings. If yours does not, disable type coercion or fix the values after conversion.

Can JSON be converted back into the original XML?

Not exactly. Conversion drops comments, processing instructions and attribute order, flattens namespaces, and may change text into numbers. You can generate valid XML from the JSON, but it will not be identical to the source document.

Why does my XML fail to convert at all?

The usual causes are multiple root elements, unclosed or mismatched tags, and unquoted attribute values. XML requires exactly one root and perfectly nested tags, so wrap sibling fragments in a single parent and check that every opening tag has its matching close.

Primary sources and further reading

These links are included so important claims can be checked against standards bodies, government guidance or first-party documentation.

Try these tools next

Related tools for checking the numbers, comparing scenarios or completing the next step.

Related guides

← All journal guides