Tooleux

Convert XML to JSON and JSON to XML. Attributes become @keys, text becomes #text, repeated elements become arrays.

Runs in your browser. Nothing leaves your device.
Convert XML to JSON and JSON to XML. Preserves attributes, repeated elements, and text. Type coercion optional. Runs in your browser. Read more Show less

What is this for?

XML and JSON are both ways to represent structured data. XML uses tags and attributes; JSON uses braces and keys. Conversion is not one-to-one, because each format has features the other lacks, but for the common cases - elements, attributes, nested objects, repeated siblings - the mapping is well defined.

This tool converts both directions. Paste XML and get JSON, or paste JSON and get XML. The direction is detected automatically from the first non-whitespace character, or you can pin it with the Direction dropdown.

How the mapping works

XML to JSON uses the convention shared by most libraries (xml2js, fast-xml-parser):

  • Elements become object keys. <person>...</person> becomes {"person": ...}
  • Attributes get an @ prefix. <a href="x"> becomes {"a": {"@href": "x"}}
  • Text content becomes #text when the element also has attributes or children. A simple element with only text collapses to a plain string.
  • Repeated siblings become an array. <b/><b/> becomes {"b": [null, null]}. A single occurrence stays a scalar.
  • Empty elements become empty strings. <a/> becomes {"a": ""}

JSON to XML inverts the same rules. A key starting with @ becomes an attribute; the key #text becomes text content; an array becomes repeated sibling elements.

About type coercion

XML has no types. Everything inside a tag is text. <port>8080</port> is the string "8080", not the number 8080. JSON does have types, so at some point you have to decide whether to coerce.

Coercion is off by default, and that is deliberate. If the tool coerced automatically, <zip>01234</zip> would become 1234 and lose the leading zero - a silent corruption for postal codes, phone numbers, and account IDs. Leave it off for any XML where strings matter. Turn it on if your XML is known to contain only numbers and booleans in known positions.

Coercion rules: a string that parses as a JSON number becomes a number; "true" and "false" (case-insensitive) become booleans; everything else stays a string. Whitespace is trimmed first.

What is not preserved

XML and JSON have different expressive power. These cannot survive a round trip:

  • Comments - JSON has no comment syntax. XML comments are dropped.
  • Processing instructions and DOCTYPE - dropped.
  • CDATA markers - the content is kept, but the CDATA wrapper is lost.
  • Namespace prefixes - <ns:a> is stored as the literal key "ns:a", not as a bound namespace. The prefix survives in JSON but loses its binding.
  • Attribute order - JSON objects are unordered. If you convert back, attribute order may differ.

FAQ

Why does my simple element become a string in one case and an object in another?

An element is collapsed to a plain string only when it has no attributes and no child elements. If it has either, the result is an object so the attributes or children have a place to go. <a>1</a> becomes {"a": "1"}, but <a id="1">x</a> becomes {"a": {"@id": "1", "#text": "x"}}.

Why is a repeated element sometimes an array and sometimes not?

If a name appears once in the parent, its value is a scalar. If it appears twice or more, the value is an array of each occurrence. This matches how xml2js and fast-xml-parser behave. It means the same JSON key can be a string in one document and an array in another, depending on the XML.

My JSON keys have spaces in them. What happens?

XML element names cannot contain spaces or most punctuation. Invalid characters are replaced with _ in the generated tag name. The original key is not preserved. Keep JSON keys alphanumeric if you plan to convert to XML.

Does this validate the input?

XML is validated as well-formed by the browser parser - malformed XML produces a clear error. JSON is validated by the browser JSON parser. Neither validates against a schema. Use the XML Validator for well-formedness only, or a schema tool for schema validation.

Is my data sent anywhere?

No. Parsing and conversion run entirely in your browser. Nothing is uploaded.

Command line equivalent
# Python (xmltodict)
pip install xmltodict
python3 -c "import xmltodict,json,sys; print(json.dumps(xmltodict.parse(sys.stdin.read()), indent=2))" < input.xml

# Python (json to xml, dicttoxml)
pip install dicttoxml
python3 -c "import json,dicttoxml,sys; print(dicttoxml.dicttoxml(json.load(sys.stdin)).decode())" < input.json

# Node (fast-xml-parser)
npm i fast-xml-parser
node -e "const {XMLParser}=require('fast-xml-parser');const fs=require('fs');const p=new XMLParser();console.log(JSON.stringify(p.parse(fs.readFileSync('input.xml','utf8')),null,2))"

# xmllint (well-formedness only)
xmllint --noout input.xml
Loads a test value into the form
XML or JSON
Converted output