XML ⇄ JSON Converter
Convert both ways, with the mapping rules under your control
Input
Result
A successful parse does not make the content safe: XML from unknown sources must still be escaped before rendering.
Namespace prefixes are preserved as written (ns:root) rather than expanded to URIs.
Last updated: 2026-10-11
About this tool
XML and JSON express the same tree structure, but the mapping has many details: how should attributes be represented in JSON? Should an element with only text become a string or an object? When an element repeats, does it become an array? There is no single correct answer — it depends on what you are feeding — so this tool exposes these as configurable options and explains the consequence of each. When parsing fails you get a precise **line and column**, not a vague "invalid format". It also states plainly that a successful parse does not make the content safe: XML from an untrusted source converted to JSON and rendered on a page still needs escaping.
Features
Both directions
XML to JSON and JSON to XML are both supported, so you can verify a mapping by converting there and back.
Errors located to line and column
Syntax errors report exactly which line and column failed rather than just "parse failed", so debugging is immediately actionable.
Configurable attribute prefix
Attributes map to keys with an @ prefix (@id) by default; switch to -, a custom prefix, or discard attributes entirely.
Configurable text key
When an element has both attributes and children, you choose which key holds its text; the default is #text.
Forced arrays
Name the elements that should always become arrays even when they appear once — sparing downstream code the "sometimes an object, sometimes an array" dance.
Safe entity handling
Only the five built-in entities (amp/lt/gt/quot/apos) and numeric references are expanded; custom entities are preserved verbatim and listed, and DOCTYPE ENTITY declarations are never parsed — removing the entity-expansion attack surface at the root.
How to use
- 1
Pick a direction
XML → JSON, or JSON → XML.
- 2
Paste your content
Paste the XML or JSON; output updates live as you change options.
- 3
Tune the mapping
Set attribute prefix, text key, forced arrays and watch how the output changes.
- 4
Copy or download
Copy the result; the JSON direction can also be downloaded.
Options
- Direction
- XML to JSON, or JSON to XML.
- Attribute prefix
- Prefix applied when mapping XML attributes to JSON keys; @ by default.
- Text key
- Key used for text content in mixed elements; #text by default.
- Forced arrays
- Comma-separated element names that always output as arrays.
- Root name
- Root element name when producing XML. JSON has no root concept, so one must be supplied.
- Item name
- Tag name used for array entries; item by default.
Common use cases
- Turning an XML API response into JSON that is easier to process in code
- Inspecting an XML file to check its structure and depth
- Converting a JSON config into an XML format some system demands
- Verifying equivalence between the two representations with a round trip
- Tracking down which line of a malformed XML file is actually broken
FAQ
Questions you may have about this tool
Why do attributes get an @ prefix in JSON?
Because JSON object keys have no concept of an attribute, while XML attributes and child elements are genuinely different things that need distinguishing. Using @id for an attribute and id for a child element is the most widely used convention and requires no non-standard extensions. If the system you integrate with uses a different convention (a - prefix, say) you can change it here; and if the attributes are pure metadata you can discard them altogether.
Why does <中文> produce an error?
Because the NameStartChar character class in the XML specification does not include non-ASCII characters such as Chinese, so a Chinese tag name is genuinely invalid XML. This was confirmed against Python’s xml.etree, which reports "not well-formed (invalid token)". An early version of this tool let such names through and was changed to reject them — a parser more permissive than the reference implementation is the dangerous kind, because it makes you believe your XML is valid right up until you feed it to another system. If your data really does contain non-ASCII tag names it is probably not standard XML (some bespoke format, perhaps) and needs converting first.
Why do some elements become strings and others objects?
Because an element has two shapes that need different representations. An element with neither attributes nor children contains only text, so a bare string is cleanest (<name>Tom</name> → "Tom"). One with attributes or children needs an object to hold multiple keys. This is controlled by the "collapse text" option; turning it off makes every element an object so the structure is uniform.
What happens when a tag appears more than once?
By default it becomes an array, because that is the only lossless representation. But if an element is logically singular in your data and happens to appear twice once, automatic array conversion catches downstream code off guard. Hence the "forced arrays" option: list the element names and they are always arrays, so consumers never need a compatibility branch for "sometimes an object, sometimes an array".
Are XML comments preserved?
Comments are dropped during conversion. JSON has no comment syntax, so there is nowhere to put them; and comments are typically notes for humans, which would pollute the data structure if carried across. If you need to compare files including comments, that is a text comparison task rather than a format conversion.
Why are custom entities not expanded?
Because expanding a custom entity means parsing ENTITY declarations inside DOCTYPE, which is the classic entry point for XML External Entity (XXE) attacks — they can be used to read files from the server. This tool handles only the five language built-ins and numeric character references. Anything it cannot recognise is **preserved verbatim** and listed for you, rather than silently dropped or speculatively expanded. That is both safer and means you never lose data without knowing.
Does a round trip reproduce the original exactly?
Structurally, yes: XML converted to JSON and back restores the hierarchy, attributes and text. Two kinds of information are lost, however: comments, and insignificant indentation whitespace between elements (preserving it would add a pile of empty #text nodes to every formatted document). So a round trip is semantically equivalent but not byte-identical. For byte-level comparison use a text diff tool instead.
How are namespaces handled?
Prefixes are preserved as written: <ns:root xmlns:ns="urn:x"> yields the JSON key ns:root. This differs from Python’s etree, which expands it to {urn:x}root. The choice is deliberate — people using a toolbox generally want to see the shape of their XML, and long URI prefixes make that harder rather than easier. The difference is documented on the page; if you need rigorously expanded namespaces, use a dedicated programming library.