What this tool does
Keys become elements, values become their contents:
{ "user": { "name": "Ada", "port": 8080, "active": true } }
<user>
<name>Ada</name>
<port>8080</port>
<active>true</active>
</user>
A document with several keys at the root is wrapped in <root>, because XML allows exactly one root element. An array at the root becomes repeated <item> elements inside it.
The types stop existing here
Look at that output again. 8080 and true are now text, and nothing in the document says they were ever anything else.
This is not a limitation of the conversion; it is what XML is. An XML document carries structure and text. Types come from a schema — XSD, DTD, RELAX NG — which lives outside the document and which this conversion has no way to invent.
The practical consequence is worth stating plainly: converting back will give you strings. {"port": 8080} returns as {"port": "8080"} unless whatever reads it decides otherwise — which means guessing, and guessing wrong on a version number like 1.10 or a ZIP code like 01234.
If you need the round trip to preserve types, XML is the wrong destination. If you need XML, plan for the return trip to be lossy.
Keys are repaired, not emitted broken
An XML element name cannot contain a space and cannot start with a digit:
| key | element |
|---|---|
user name | <user_name> |
2nd | <_2nd> |
And when two keys repair to the same name, the second becomes user_name_1. Merging them would drop a value silently, which is the failure this tool tries hardest to avoid.
Attributes, and the round trip
A key written "@_id" becomes an attribute, "#text" becomes the element’s text:
{ "user": { "@_id": "1", "#text": "Ada" } }
<user id="1">Ada</user>
That is the same convention the XML-to-JSON direction emits, so a document converted from XML converts back to the same shape — with the types now strings, as above.
Private by design
Everything runs locally in your browser with JavaScript. Your data is never uploaded, which makes the tool safe for sensitive content, and it keeps working offline.