XML ↔ JSON
FormatEverything runs locally in your browser — nothing is uploaded
⚠️ This conversion is inherently lossy, and it drops more than it appears to. XML and JSON have different data models; this is not two notations for the same thing: · Attributes vs child elements — `<a b="1"/>` and `<a><b>1</b></a>` are different things in XML (metadata versus content). The `@` prefix distinguishes them in JSON and converts back. · Mixed content — in `<p>before<b>bold</b>after</p>` the text and the elements are interleaved. A JSON object has no notion of order, so that structure must be lost. · Repeated tags — two become an array and one stays a scalar, so the JSON cannot show the difference between “there is one” and “there can only be one”; converting back turns a one-element array into a single element. · Comments, processing instructions, DOCTYPE — nothing corresponds in JSON. They are dropped and counted. · Namespaces — the prefix is kept as part of the tag name (`xs:element`), but namespaces are not resolved: two documents using different prefixes for the same namespace convert to different keys. So this tool converts with a fixed convention and reports each loss — how many comments, which elements had mixed content — rather than quietly producing JSON that looks complete. ⚠️ The root element is not unwrapped: `<a><b>1</b></a>` becomes `{"a":{"b":"1"}}`, not `{"b":"1"}`. Unwrapping looks cleaner but makes the reverse direction impossible — what would the root element be called when converting `{"b":"1"}` back? The name was discarded in that step. This tool goes both ways, so both directions share one convention. Everything runs in your browser.
Features
- Both directions: XML → JSON and JSON → XML, or pick one explicitly
- ⚠️ Reports what this conversion dropped: counts of comments, processing instructions and DOCTYPE
- ⚠️ Detects mixed content (text interleaved with elements) and says that structure is already gone
- ⚠️ A closing note on why the conversion is inherently lossy and what it is and is not good for
- Attributes become `@name`; text goes to `#text` when there is anything else in the element
- Repeated sibling elements become an array; a single one stays a scalar
- CDATA is merged with text (JSON cannot tell them apart)
- ⚠️ Tag and attribute names are case-sensitive — that is XML, unlike HTML
- ⚠️ Namespace prefixes are preserved verbatim and not resolved, with the reason stated
- ⚠️ Going the other way, illegal key names are skipped and reported, never quietly rewritten
- ⚠️ XML is stricter than HTML: tags must close, attribute values must be quoted, and an entity that XML does not define is an error — each with a position
- Runs entirely in your browser
How to use
- Paste XML or JSON; the direction is detected (anything starting with `<` is treated as XML)
- Tick “also list the conversion convention” if you want it spelled out
- Read the result first, then the “what this conversion lost” section
FAQ
- Why not unwrap the root element?
- Because then the reverse direction cannot work. Unwrapped, `<a><b>1</b></a>` becomes `{"b":"1"}` — the root name `a` is gone. What would the root element be called when converting back? You would have to invent a `<root>`, and that name is not in your data. This tool goes both ways, so both directions share one convention, which means the root stays wrapped. The round-trip test pins exactly this: XML to JSON and back must be semantically identical.
- What is “mixed content”, and why must it be lost?
- It means text and child elements interleaved inside one element: `<p>before<b>bold</b>after</p>`. That is perfectly legal XML and the order carries meaning — “after” must come after that `<b>`. A JSON object is an unordered set of keys and cannot express “text between the first and second child”. So the text is concatenated and its position is gone. Preserving it means not converting, or using a format that expresses order. At least this tool counts how many elements are affected, so you know where the damage is.
- Why does ` ` raise an error?
- Because XML predefines only five entities: `lt`, `gt`, `amp`, `quot` and `apos`. ` ` belongs to HTML and is not among them — a document using it is not well-formed. Decoding it leniently would make a broken document look entirely normal, and someone holding a result that “works” will not go looking for why other tools refuse it. Write ` ` if you want that character.
- Is parsing XML really so different from HTML?
- Very. HTML is designed to be forgiving: unclosed tags, unquoted attribute values, mixed case — a browser will do its best. XML is designed to be strict: tags must pair up, attribute values must be quoted, case matters (`<Element>` and `<element>` are two different things), and an entity XML does not define is an error. So the HTML parser in a browser cannot be used to read XML — it silently repairs the very problems in your document that you need to know about.
- When should I use this, and when not?
- Use it to move data between services — an API that only emits XML while your code prefers JSON, or a config that has to be fed to an older system that only reads XML. Do not use it to edit XML documents. If the document has mixed content, comments or namespaces, it will not be the same one after a round trip, and nothing will warn you. For editing XML, use a tool that preserves the original.
Related tools
JSON Formatter
FormatFormat, validate and minify JSON in a collapsible tree with syntax highlighting and line numbers. Search, edit, delete or convert to Python dicts.
YAML Converter
FormatConvert YAML to JSON and back: multi-document files, anchors and merge keys, exact big integers, parse errors with a line and column.
TOML Converter
FormatConvert TOML and JSON both ways: all four date/time kinds, arrays of tables and dotted keys, big integers and inf/nan kept, errors located by line.
JSON to Code
FormatTurn JSON into TypeScript interfaces, Go structs, Java classes or Rust structs, with missing keys marked optional. Runs locally in your browser.
SQL Formatter
FormatFormat SQL online: one clause per line, consistent keyword case, subqueries indented deeper. Minify strips comments and extra whitespace, all locally.
JSON5 Converter
FormatParse JSON5 into strict JSON: comments, unquoted keys, single quotes, trailing commas, hex and Infinity all work, with errors located by line.