XML to JSON Converter

at element what was decided what came out
1:7 id="1" attribute of <user> · the declared prefix @ · kept as text "@id":"1"
1:14 <name>Ada</name> text-only element · kept as text "name":"Ada"
1:14 <name> one child of <user> · a value, not a one-element array "name"
  • <name> appears once inside <user>, so it became a value rather than a one-element array. DFCF14: a single child element gives no way to tell one value from a one-element array — the choice is this converter's, not the file's.

Going the other way? Convert JSON back to XML

How do you convert XML to JSON?

XML to JSON turns a tree into an object: an element becomes a key, an attribute and a text node take declared key prefixes, and a repeated element becomes an array.

  1. Paste the XML above. It has to be well formed: one root element, every end tag matching its start tag, and no attribute name used twice on one tag.
  2. Read each element into a member named after it, and each attribute into a member whose name carries the declared prefix.
  3. Group sibling elements that share a name into an array, in document order, because that order carries meaning in XML.
  4. Write the members out as one JSON object, reporting every element that appeared once so you can decide whether it should have been an array.

This page writes a JSON object with attributes and text nodes under declared key prefixes and repeated elements as arrays; a single child element is reported so you can choose.

XML to JSON Conversion Table

XML separates attributes from children and JSON has one kind of container for both, so this conversion has to choose, and the choice is a convention rather than a rule. JSON has one kind of container for both, so an XML to JSON conversion has to choose. Attributes and child elements collapse into the same kind of member, a single child element gives no way to tell one value from a one-element array, and mixed content - text interleaved with child elements - has no JSON shape at all.

XML to JSON Conversion Table
XML formJSON formNote
<name>Ada</name>"name": "Ada"an element holding only text becomes the text
id="1""@id": "1"the declared prefix @ marks an attribute
text beside attributes"#text": "..."the declared key #text marks character data
<tag>a</tag><tag>b</tag>"tag": ["a", "b"]repeated siblings become an array, in document order
<tag>a</tag>"tag": "a"reported, because it could equally have been a one-element array
<tag/>"tag": nullXML has no null and no empty-string marker
text between child elementsone #text memberwhere the text stood among the children is gone

A format is defined by what it can say. The rows below put the two halves of this conversion side by side, so the gap the conversion has to cross is a thing you can read rather than a thing you find out later. Every value in the table is the wording the defining document uses, not a summary of it, and a dash means the format has no answer to that row at all.

What XML and JSON Can Say
What it saysXMLJSON
SpecificationW3C Recommendation, Extensible Markup Language (XML) 1.0RFC 8259, Standards Track, December 2017; also ECMA-404
Media typeapplication/xml and text/xmlapplication/json
Structurea tree of elements, each carrying attributes and contentobjects and arrays, nested to any depth
Delimitera comma (%x2C) between two members of an object and between two elements of an array
Quotingdouble quotes; a quotation mark, a reverse solidus and the control characters U+0000 to U+001F must be escaped with a reverse solidus
Type setnone in XML 1.0 itself - every attribute value and text node is character datastring, number, boolean, null, object, array
Nestingunlimitedunlimited by the grammar; a parser may set its own depth limit
Orderingan object is unordered; an array is ordered
Child ordersignificant - element content is an ordered production
Attribute ordernot significant
Attribute namesan attribute name must not appear more than once in the same start tag or empty-element tag
Mixed contentcharacter data may be interleaved with child elements
Comment<!-- ... -->none - the grammar has no comment production
EncodingUTF-8

Worked Example: XML to JSON

One element with an attribute and one child, converted here at build time by the same code the box above runs. The working under it names each part of the tree and the member it became.

XML in
<user id="1"><name>Ada</name></user>
JSON out
{"user":{"@id":"1","name":"Ada"}}
at element what was decided what came out
1:7 id="1" attribute of <user> · the declared prefix @ · kept as text "@id":"1"
1:14 <name>Ada</name> text-only element · kept as text "name":"Ada"
1:14 <name> one child of <user> · a value, not a one-element array "name"

Result: the XML above is the JSON beside it, and every decision that made it is listed below.

The attribute and the child element came out as members of the same object, and nothing in the JSON records that one was an attribute except the prefix this converter declared. An XML attribute may appear at most once per element and the order of attributes in a start tag carries no meaning; a child element may repeat any number of times and its order does carry meaning. An attribute value is always text, while an element can hold text, other elements, or both.

The values arrived as strings because XML has none of its own. RFC 8259 gives JSON four primitive types - string, number, boolean and null - and two structured types, object and array. There is no date type and no separate integer type, so a date arrives as a string and every number is read the same way. An XML document carries none in XML 1.0 itself - every attribute value and text node is character data.

Check it in reverse

Writing the object back out as XML does not return the document you started from, and the reason is the choice above rather than a defect. A member named with the declared prefix becomes an attribute again, and a plain member becomes an element, so the shape survives. What does not survive is anything the first pass had to decide: a single child that became a value, and any text that stood between child elements.

To prove nothing was lost, convert the JSON result back to XML and compare it with the file you started from.

What This Conversion Cannot Carry

This is the pair where the round trip is not free, and every gap has the same cause. JSON has no comments and no trailing commas because RFC 8259's grammar has no production for either. A comma may appear only between two members of an object or two elements of an array, so a comma before the closing brace or bracket makes the text invalid.

A child element that appears once
<name> appears once inside <user>, so it became a value rather than a one-element array. DFCF14: a single child element gives no way to tell one value from a one-element array — the choice is this converter's, not the file's.
An empty element
<n> is empty and became null. XML has no null and no empty-string marker (FMT-xml-types), so an empty element and an element holding "" are the same document.
Text interleaved with child elements
<m> holds text interleaved with child elements. DFCF14: mixed content has no JSON shape at all, so the text runs were joined into one #text member and where they stood among the children is gone.
A document type declaration
A document type declaration was skipped. JSON has nothing to carry it and no entity it declares is expanded.
A byte order mark
A byte order mark stood at the front of the file. It was removed rather than read as part of the document.

Each line above is written by the converter itself, and it appears under your own result whenever your document raises it. Nothing is dropped without one.

The sample above reverses exactly - write the same data back out as XML elements .

What Does XML Say That JSON Cannot?

Whether a child element appears once or many times

One appearance becomes a value and two become an array, so a document that happens to carry one item this time reads differently from the same document with two. significant - element content is an ordered production, which is why the array keeps the document order.

Whether the same name is used twice in the output object

It is not, because sibling elements of one name are collected into an array first. RFC 8259 says the names in an object should be unique and records that software receiving a repeated name behaves unpredictably: some implementations keep the last pair, some fail, some keep all of them. An object is unordered, and parsers differ over whether they expose member order at all.

Whether an attribute could have been an element

The prefix keeps them apart on the way out and on the way back. an attribute name must not appear more than once in the same start tag or empty-element tag, while not significant — so an attribute is a set and a child list is a sequence.

XML to JSON in Code

The same conversion in two lines, one per language. Neither line makes the attribute choice for you; this page states it instead. Neither line reports what the conversion could not carry; the converter above does.

Python: json.dumps({e.tag: e.text for e in ElementTree.parse("in.xml").getroot()})
JavaScript: JSON.stringify(toObject(new DOMParser().parseFromString(xml, "text/xml")))

Common Mistakes

Frequently Asked Questions

Why is XML to JSON not reversible?

Because the conversion has to make choices XML does not record. A single child becomes a value, mixed content becomes one member, and neither can be put back exactly as it was.

How are XML attributes represented in the JSON?

As members whose names carry the declared prefix, so id="1" becomes "@id": "1". The prefix is what keeps an attribute apart from a child element of the same name.

Does a single child element become an array?

No, it becomes a value, and the converter reports every place it happened. XML gives no way to tell one value from a one-element list, so the choice is the converter’s.

What happens to mixed content - text next to child elements?

The text runs are joined into one member under the declared key, and where they stood among the children is gone. JSON has no shape for text interleaved with children.

What happens when two child elements have the same name?

They become an array, in document order. Child order carries meaning in XML, so the array keeps it rather than collecting the elements into a set.

Yes. The same file converts straight back in the JSON to XML direction .

The rest of the family sits on the data format converters.