Convert XML to JSON — Free, Private, In-Browser
XML to JSON here is a structural flattening, not a general document transform. dataeng.tools locates the repeating element in your file — the shallowest set of same-tag siblings, like <row> inside <rows>, or <item> inside an RSS <channel> — and treats each occurrence as one record. The output is a single JSON array of objects, one per repeating element. That is exactly the shape you want for record-oriented XML: SOAP response bodies, RSS/Atom feeds, database exports, and config files that carry many uniform entries. When two candidate levels tie on depth, the larger group wins; if nothing in the document repeats at all, the whole thing collapses to a single-element array so you still get valid JSON back.
Inside each record the mapping follows a few consistent rules. Attributes become keys prefixed with @, so <row id="7"> yields {"@id": "7"}. A child element that holds only text becomes that text as a string; repeated child tags collapse into an array; a single child element nests as an object. Mixed content — an element carrying both attributes and text — is emitted as {"@attr": ..., "#text": ...} so nothing is silently dropped. The one thing to internalize is that XML carries no type information, so every value arrives as a string. Numeric IDs, booleans, and dates all land as JSON strings; if you need real numbers or timestamps downstream, cast them in whatever consumes the JSON.
The limitation worth stating plainly: only the repeating-record shape is captured, not arbitrary document structure. Feed-level metadata that sits beside the records but does not itself repeat — an RSS <channel> title, a SOAP envelope header, a top-level <generated_at> — is not folded into the output, because the converter is hunting for the record list, not serializing the entire tree. That is a deliberate tradeoff: it makes tabular, record-heavy XML trivially usable as JSON, but it will not losslessly round-trip a deeply nested, one-of-a-kind document. If your XML is genuinely a list of like records, it fits cleanly. Everything runs locally in your browser via DuckDB-WASM — the file is parsed and converted on your machine and is never uploaded.
Drop a file or click to browse
Drop a XML file — processed locally, never uploaded
Frequently asked questions
- How does it decide what counts as a row?
- It scans for the shallowest set of repeated same-tag sibling elements and treats each as a record — <row> under <rows>, or <item> under an RSS <channel>. Ties at the same depth go to the larger group. If nothing repeats, the whole document becomes a single record so you always get valid JSON.
- What happens to attributes versus element text?
- Attributes are kept as @-prefixed keys (<row id="7"> becomes {"@id": "7"}), a text-only element becomes its trimmed string value, and an element with both attributes and text is emitted as {"@attr": ..., "#text": ...}. Nothing inside a captured record is dropped.
- Why didn't my feed's header or metadata make it into the JSON?
- Only the repeating record list is captured, not the surrounding document. Non-repeating siblings like an RSS <channel> title or a SOAP envelope header sit outside the record set, so they aren't included. The output is the array of records, not a full-tree transform.
- Is my file uploaded anywhere?
- No. The XML→JSON conversion runs entirely in your browser via DuckDB-WASM. Your file never leaves your device.
- How large a file can I convert?
- It's bounded by your browser's available memory rather than any server limit — files in the hundreds of MB are routine. DuckDB runs single-threaded here, so very large files just take a little longer.
- Do I need an account?
- No — it's free and requires no sign-up.