JSON ↔ XML Converter

Both directions. Client-side. Configurable root, attribute lifting, single-array collapse.

JSON ↔ XML, both directions. Client-side. Nothing sent to a server. How to use ↓·Shortcuts ↓
JSON input, XML output.
Indent:Root:
Samples:
JSON Input
XML Output
Output will appear here.
Input: 0 chars · 0 bytesOutput: 0 chars · 0 bytes

How to use

Pick a direction with the tabs — JSON → XML or XML → JSON. Paste your input on the left. The converted output appears on the right as you type.

For JSON→XML, set the root element name and whether to include the <?xml ... ?> declaration. For XML→JSON, choose whether to collapse single-element arrays and whether to merge attributes with sibling children.

Keyboard shortcuts

Three shortcuts:

Cmd / Ctrl + KFocus the input pane
Cmd / Ctrl + EnterCopy output to clipboard
Cmd / Ctrl + /Toggle direction

When to use it

XML is still everywhere in legacy and enterprise systems: SOAP APIs, RSS/Atom feeds, sitemaps, Office and DOCX innards, Android manifests, SVG.

  • Consuming a SOAP or SAML response and needing JSON to feed a JS front-end.
  • Generating an RSS feed from a JSON data source.
  • Comparing shape between an XML config and its JSON port.
  • Sanity-checking that a converter you wrote produces the same result on both directions.

Options

Indent — 2 spaces, 4 spaces, or tab.

Root (JSON→XML only) — the wrapping root element name. Default root. XML must have exactly one root; JSON doesn't need one, so this fills the gap.

XML declaration (JSON→XML only) — include the <?xml version="1.0" encoding="UTF-8"?> prolog. Turn off for XML fragments meant to be embedded.

Collapse single arrays (XML→JSON only) — XML has no array type; xml2js normally wraps every child in an array in case it repeats. This flag returns single-child values as plain values instead. Cleaner but you lose the "might have siblings" hint.

Merge attributes (XML→JSON only) — XML attributes get lifted alongside child elements instead of nested under a $ key. Reads more naturally in JSON.

Format-specific gotchas

JSON and XML aren't 1:1. XML has attributes, mixed content (text and elements interleaved), namespaces, and CDATA. JSON has arrays, booleans, and null. Round-tripping between them can lose fidelity — expect some structural drift.

XML has no array type. Repeated elements become arrays in JSON; single elements without repetition may or may not become arrays depending on the Collapse single arrays option.

All XML text is strings. The XML→JSON pass reads every text node as a string — <age>30</age> becomes "age": "30", not "age": 30. Post-process if you need typed values.

Root element required for XML. If your JSON is [1, 2, 3], it gets wrapped as <root><0>1</0>...</root> — probably not what you want. Wrap arrays in a named property first.

Privacy

Everything runs in your browser. Your JSON and XML never leave the page — no server, no logging, no analytics on the content.

Frequently asked questions

How do you convert between JSON and XML when they have different data models?
Object keys become element names; primitive values become text nodes; arrays become repeated elements. XML attributes, when going XML → JSON, are lifted next to sibling elements. Some structural drift is unavoidable — round-tripping may not be identical.
What is the Root option for?
XML documents must have exactly one root element. JSON does not. When converting JSON → XML, the tool wraps your JSON in a root element with the name you provide (default: "root").
Why is my number a string in the JSON output?
XML text nodes are always strings — <age>30</age> reads as the string "30". If you need typed values, post-process the JSON to coerce.
What does "Collapse single arrays" do?
xml2js wraps every child element in an array by default, in case it repeats later. With this option on, single children become plain values instead. Cleaner JSON, but you lose the "might have siblings" affordance.
What if my XML has attributes?
By default, attributes are nested under a $ key. With Merge attributes on, they lift up alongside child elements — reads more naturally in JSON.
Does the tool send my data anywhere?
No. All conversion happens in your browser using xml2js. The input never leaves the page.