JSON and XML both store structured data as plain text, and either can describe the same record. The difference is in what they were built for. JSON maps directly onto the objects, arrays, numbers and booleans used in programming languages, which is why most web APIs use it. XML is a markup language: it treats data as a tree of named elements with attributes and text, which makes it better for documents and for formats that need namespaces and strict schemas. Below, the same data is written both ways, the sizes are measured, and the conversion traps are listed.
The same data in JSON and XML
Here are three employee records in JSON:
{
"employees": [
{
"id": 101,
"name": "Ana Lopez",
"email": "ana@example.com",
"active": true,
"skills": [
"SQL",
"Python"
]
},
{
"id": 102,
"name": "Ben Carter",
"email": "ben@example.com",
"active": false,
"skills": [
"Excel"
]
},
{
"id": 103,
"name": "Chloe Kim",
"email": "chloe@example.com",
"active": true,
"skills": []
}
]
}
And the same records as XML elements:
<employees>
<employee>
<id>101</id>
<name>Ana Lopez</name>
<email>ana@example.com</email>
<active>true</active>
<skills>
<skill>SQL</skill>
<skill>Python</skill>
</skills>
</employee>
<employee>
<id>102</id>
<name>Ben Carter</name>
<email>ben@example.com</email>
<active>false</active>
<skills>
<skill>Excel</skill>
</skills>
</employee>
<employee>
<id>103</id>
<name>Chloe Kim</name>
<email>chloe@example.com</email>
<active>true</active>
<skills/>
</employee>
</employees>
JSON says 101 is a number and true is a boolean. In the XML, both are just text: <id>101</id> carries no type unless a schema assigns one. XML also needs a wrapper element for the list (<skills>) and a repeated element for each item (<skill>), where JSON uses an array.
JSON vs XML at a glance
| JSON | XML | |
|---|---|---|
| Data types | String, number, boolean, null, object, array | Everything is text unless a schema assigns a type |
| Structure | Objects (name/value pairs) and arrays | Elements, attributes, text, and mixed content |
| Comments | None in the standard | <!-- like this --> |
| Root | Any value can be the top level | Exactly one root element |
| Schema language | JSON Schema (current version 2020-12) | XSD 1.1 (W3C Recommendation, 2012), also DTD |
| Namespaces | No | Yes |
| Encoding | UTF-8 required between open systems (RFC 8259) | Processors must accept UTF-8 and UTF-16 |
| Parsing in browsers | JSON.parse() | DOMParser |
Data types
RFC 8259 defines a JSON value as an object, array, number or string, or one of three literal names: true, false and null. That's the whole type system, and it's built into the syntax.
XML has no built-in data types. Element content and attribute values are character data, and an XML parser hands them to your code as strings. Types come from a schema: XSD's datatypes include xs:integer, xs:boolean and xs:date, and a schema-aware tool can check and convert values. Without a schema, your code has to decide that "101" is a number.
JSON's types have one well-known limit. RFC 8259 notes that integers between −(253)+1 and 253−1 are interoperable, because many implementations store JSON numbers as IEEE 754 double-precision values. Larger IDs, such as 64-bit database keys, can silently change when parsed in JavaScript. Send them as strings.
Attributes vs objects
XML gives you two places to put a value: a child element or an attribute. Here's the same data with the scalar fields moved into attributes:
<employees>
<employee id="101" name="Ana Lopez" email="ana@example.com" active="true">
<skill>SQL</skill>
<skill>Python</skill>
</employee>
<employee id="102" name="Ben Carter" email="ben@example.com" active="false">
<skill>Excel</skill>
</employee>
<employee id="103" name="Chloe Kim" email="chloe@example.com" active="true"/>
</employees>
Attributes are compact, but they can only hold text, can't repeat, and can't contain child elements, so lists such as skills still need elements. The XML 1.0 specification also forbids the same attribute name appearing twice in one start tag. JSON has no attributes at all; everything is a name/value pair inside an object.
Comments, order and duplicate keys
- Comments: XML supports
<!-- comments -->(the string--isn't allowed inside one). Standard JSON has no comment syntax, so tools that accept comments in config files are using a JSON extension, not JSON. - Order: ECMA-404 assigns no meaning to the order of name/value pairs in a JSON object. In XML, element order is part of the document, and schemas often require a specific order.
- Duplicate names: RFC 8259 says object names SHOULD be unique and warns that software behaves unpredictably when they aren't. XML has no such issue for elements: repeating an element is how you make a list.
Schemas: JSON Schema vs XSD
Both formats can be validated against a schema that lists required fields, types and allowed values.
- XSD (XML Schema Definition Language) is a W3C standard. Version 1.1 became a W3C Recommendation in April 2012. XML also has the older DTD format, defined in the XML 1.0 specification itself.
- JSON Schema is written in JSON. Its current version is 2020-12. It's widely used to describe API request and response bodies.
The practical difference is how much the schema matters. Because XML has no types of its own, an XSD is often what gives the data meaning. JSON already distinguishes numbers, strings and booleans, so JSON Schema is mainly about required fields and allowed values.
Size: JSON vs XML on a real example
Here are the byte counts for the three-record example above, measured in Python. The gzip column uses Python's gzip module at compression level 9.
| Format | Bytes | Bytes gzipped |
|---|---|---|
| JSON, minified | 286 | 174 |
| JSON, 2-space indent | 485 | 199 |
| XML elements, minified | 455 | 189 |
| XML elements, 2-space indent | 572 | 203 |
| XML with attributes, minified | 331 | 175 |
Minified XML with elements is 1.59 times the size of minified JSON, mostly because every value needs a closing tag that repeats its name. Using attributes narrows that to 1.16 times. Compression nearly erases the difference: repeated tag names are exactly what gzip is good at. Scaling the same structure to 1,000 generated records gave 100,379 bytes of JSON and 160,137 bytes of XML (1.6 times larger), but only 9,023 versus 9,116 bytes once gzipped. If your server compresses responses, size isn't a strong reason to choose one format over the other.
Turn JSON into XML, or pretty-print either format to find errors, in your browser.
JSON to XML Converter → JSON Formatter → XML Formatter →Conversion pitfalls
Converting between the two formats is easy for simple records and lossy for everything else. Watch for these:
- One root element. The XML specification requires exactly one root element. A JSON document whose top level is an array, or an object with several keys, needs a wrapper element added.
- Invalid names. JSON keys can be any string. XML names can't start with a digit or contain spaces, and names starting with "xml" in any case are reserved. A key like
"2024 total"must be renamed or encoded. - Types are lost.
101and"101"both become<id>101</id>. Converting back, a tool must guess or rely on a schema. - One-item arrays.
"skills": ["Excel"]becomes a single<skill>element, which looks identical to a non-array value. Converting back may produce a string instead of an array. - Empty arrays and null. Both often become an empty element, so they're indistinguishable on the way back. XSD offers
xsi:nil="true"for null, but only if both sides use it. - Attributes, comments and mixed content. JSON has nothing equivalent. Converters use conventions such as prefixing attribute names, and those conventions vary between tools.
- Escaping. In XML,
<and&in text must be written as<and&. In JSON, quotes and backslashes in strings are escaped with a backslash.
When a round trip matters, define the mapping once (ideally with a schema on each side) and test it with awkward data: empty lists, one-item lists, nulls and long numbers.
When to use each
Use JSON for web and mobile APIs, JavaScript apps, NoSQL documents, and config files that programs read and write. It's shorter, parses straight into native objects, and is what most developers expect. JSON formatting best practices covers how to keep it readable and avoid common syntax errors.
Use XML when the format is already XML (SVG, RSS and Atom feeds, sitemaps, Office Open XML files such as .docx, many enterprise and government systems), when you need namespaces to mix vocabularies, or when the content is a document with text and inline markup rather than a set of records. XML's mature schema and transformation tooling is also a reason to stay with it where it's established.
For more developer utilities that run in the browser, see 10 browser-based tools that save developers time.
Frequently asked questions
Is JSON better than XML?
For most web APIs and app data, JSON is simpler and smaller, and it parses straight into objects and arrays. XML is the better fit for documents with mixed text and markup, for namespaces, and for formats that are already defined in XML.
Can JSON have comments?
No. Neither RFC 8259 nor ECMA-404 includes comments in the JSON grammar, so a standard parser will reject them. XML supports comments natively.
Is JSON smaller than XML?
Usually. In this guide, three records took 286 bytes as minified JSON and 455 bytes as XML elements. After gzip compression the gap almost disappears, because repeated tag names compress very well.
What is the JSON equivalent of XML Schema (XSD)?
JSON Schema. Its current version is 2020-12. Like XSD, it describes required fields, data types, allowed values and nested structure, and validators use it to check documents.
Can every JSON document be converted to XML?
Yes, but not always cleanly. Keys that are not valid XML names, top-level arrays, nulls and empty arrays all need a convention, and converting back can turn numbers and booleans into strings or collapse one-item arrays.