XML to JSON Converter

Convert XML to JSON and back — attributes, namespaces, and SOAP envelopes handled. Runs 100% in your browser.

All computations run locally in your browser, no data uploaded to server.

How To Use

  1. Paste your XML or JSON into the input box.
  2. The Direction defaults to Auto — input starting with < converts to JSON, input starting with { or [ converts to XML. Pin XML → JSON or JSON → XML when you want the direction fixed regardless of input.
  3. Optional toggles: Infer types turns plain decimals and true/false into JSON types (leading-zero codes stay strings); Remove namespace prefixes strips soap:-style prefixes in the XML → JSON direction.
  4. Select the output Indent (2 or 4 spaces, or minified) for the JSON → XML direction.
  5. Click Convert — or press Ctrl+Enter (Cmd+Enter on a Mac) inside the input box. Conversion also runs live as you type or paste.
  6. Review the output and click Copy result; for JSON results, View as tree opens them in the JSON Viewer.

The Demo button fills a realistic SOAP-style sample so you can see the output format instantly.

Usage Example

Converting a small WebService-style XML payload to JSON. Notice how the attribute becomes an @id key, the repeated <item> elements become an array, and the values stay strings by default:

XML input

<order id="A-1024">
  <customer>Alice</customer>
  <items>
    <item>Widget</item>
    <item>Gear</item>
  </items>
  <total>42.50</total>
</order>

JSON output

{
  "order": {
    "@id": "A-1024",
    "customer": "Alice",
    "items": {
      "item": [
        "Widget",
        "Gear"
      ]
    },
    "total": "42.50"
  }
}

With Infer types enabled, 42.50 becomes the number 42.5 — while "A-1024" and any leading-zero code would stay strings. Converting the JSON back with JSON → XML rebuilds the same document, which makes round-trip checking between your XML service and JSON tests trivial.

Frequently Asked Questions

How does the Auto direction work?

The Direction control defaults to Auto: input starting with "<" is converted as XML → JSON, and input starting with "{" or "[" as JSON → XML — no selector flipping when you paste back and forth. The guess is deliberately conservative (shape of the first non-whitespace character only); when it cannot tell, the last direction stays active. Pick XML → JSON or JSON → XML explicitly to pin the direction regardless of input.

How are XML attributes and text content represented in the JSON output?

Attributes become keys prefixed with "@" (for example <User id="7"> becomes "@id": "7"), and when an element mixes text with child elements its text lands under a "#text" key. "#" and "@" can never collide with real XML names, so the mapping is unambiguous — and feeding that JSON back through the JSON → XML direction rebuilds the original attributes.

Will my long IDs and leading-zero codes survive the conversion?

Yes. By default every value stays a string, so order numbers like 00123 and 20-digit IDs are never turned into numbers. The optional "Infer types" toggle converts only plain decimals and true/false into JSON types — leading-zero codes, hex-like tokens, and values such as 0x1F still keep their string form, so enabling it cannot silently corrupt SOAP-style IDs.

Does it work with SOAP / WebService envelopes and namespaces?

Yes — that is the main use case. Namespace prefixes are preserved by default (soap:Envelope stays soap:Envelope), so the JSON mirrors the XML you actually send. The "Remove namespace prefixes" toggle strips them when you want cleaner JSON for a test harness. The XML declaration, processing instructions, and comments have no JSON equivalent and are dropped with a warning.

What happens to repeated elements, CDATA, and custom entities?

Repeated elements become JSON arrays. CDATA content is unwrapped into the element value. Custom DOCTYPE entities are expanded exactly one level deep — references inside entity values keep their literal text, which structurally breaks the classic "billion laughs" entity-expansion attack (an XML security hardening, surfaced as a warning when present).

Why does JSON → XML require a single top-level key?

XML allows exactly one root element, so the top level of your JSON must be an object with exactly one key. If it has more, the tool tells you how many keys it found and how to wrap them ({"root": {…}}) instead of emitting invalid XML. Empty arrays are also rejected — they would silently disappear from the XML.

Why did a single-item list (e.g. one <OrderItem>) convert to a JSON object instead of an array?

XML has no array concept: a "list with one item" and a "nested object" produce identical XML, so by occurrence count alone they are indistinguishable — with the default shape, one <OrderItem> becomes an object and two become an array. Typed deserializers such as Newtonsoft.Json into List<T> need the array shape at EVERY occurrence count and fail on the one-item case ("type requires a JSON array"). Auto-detect fixes this wherever the XML gives evidence (an element name appearing as repeated siblings becomes an array everywhere). For a LIST WRAPPER element in your data contract — a C# property like List<OrderItem> OrderItems, serialized as <OrderItems><OrderItem/>…</OrderItems> — switch "Arrays" to "Unwrap list wrappers…" and enter the wrapper name (e.g. OrderItems). The wrapper is then converted to a plain JSON array of its children — the intermediate child-name layer is dropped: 0 children → [], 1 → [{…}], n → [{…}, …] — exactly the shape a List<T> property needs, at every occurrence count.

Is this tool local? Is my XML or JSON uploaded?

Yes, it is 100% local. The conversion runs entirely in your browser using a bundled parser, with no network requests and no server upload. You can even disconnect from the internet and it still works. Your last input and settings stay on your device and can be cleared any time from the Privacy page.

Can I load an XML file instead of pasting text?

Yes. Use "Load file" (or drag a .xml / .txt file onto the input box) to read a file into the input. Files are read locally with the browser FileReader — nothing is uploaded — and are capped at 2 MB to keep the editor responsive; larger files are rejected with an explicit message telling you the exact limit.

How do I save or download the converted result?

Click "Download" and the current output is saved as a local file — result.json for XML → JSON, result.xml for JSON → XML. The download uses the same content as the Copy button (what you see is exactly what you get), generated in your browser without any server round-trip.

What is the difference between XML elements and attributes?

An element is a tagged node (<price>10</price>); an attribute is a name-value pair attached to a tag (<price currency="USD">10</price>). They carry the same fact in different shapes, so this tool maps attributes to distinct "@name" keys in JSON — never mixing them into element text — and the JSON → XML direction rebuilds attributes from "@name" keys. A common XML gotcha: attribute values must always be quoted, and unlike elements, an attribute cannot repeat on one tag.

Why is my XML invalid? (common causes)

The four most common causes, all of which this tool pinpoints with a line and column: (1) an unclosed tag — every <tag> needs its </tag> (or a self-closing <tag/>); (2) mismatched case — XML tags are case-sensitive, so <Name> cannot be closed by </name>; (3) unquoted attribute values — id=7 is invalid, id="7" is required; (4) more than one root element — a document must have exactly one top-level element wrapping everything else.