JSON and XML are both human-readable data formats used for storing and exchanging structured data. While JSON has become the dominant format for web APIs over the past decade, XML remains widely used in enterprise systems, document management, and certain protocol-heavy domains. Understanding the differences helps you choose the right format for your project and decode data from legacy systems.
A Quick Side-by-Side Example
Before diving into the details, here is the same data represented in both formats:
JSON:
{
"person": {
"name": "Alice Johnson",
"age": 30,
"email": "alice@example.com",
"address": {
"street": "123 Main St",
"city": "New York"
},
"hobbies": ["reading", "coding", "cycling"]
}
}
XML:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<name>Alice Johnson</name>
<age>30</age>
<email>alice@example.com</email>
<address>
<street>123 Main St</street>
<city>New York</city>
</address>
<hobbies>
<hobby>reading</hobby>
<hobby>coding</hobby>
<hobby>cycling</hobby>
</hobbies>
</person>
Minified, the JSON is 166 bytes and the XML is 278 - about 40% smaller. That figure gets quoted a lot, and it is true of the text. It is much less true of what actually crosses the network, as the measurements below show.
Size, Measured - Before and After Compression
To get past a single toy example, I generated one dataset of 50,000 orders - each with an ID, a total, a paid flag, a nested customer, and one to three line items - and wrote it out three ways: minified JSON, XML with every field as a child element, and XML with scalar fields as attributes (<item sku="SKU-0042" qty="2"/>). Same data, byte for byte, in each.
| Format | Raw size | vs JSON | gzip -9 | vs JSON |
|---|---|---|---|---|
| JSON (minified) | 7.81 MB | - | 0.99 MB | - |
| XML, element style | 11.96 MB | +53% | 1.05 MB | +7% |
| XML, attribute style | 7.96 MB | +2% | 0.99 MB | +1% |
Two things fall out of this. First, the size gap is mostly closing tags, and closing tags are exactly the kind of repetition gzip removes: a 53% raw difference shrinks to 7% on the wire. Since almost every HTTP API serves compressed responses, bandwidth is a weak argument for JSON. Second, attribute-style XML is almost exactly the size of JSON even before compression. How the XML is designed matters as much as which format you pick.
Where size does still matter is in memory, and in parsing - both of which work on the uncompressed text.
Verbosity and Readability
XML requires both an opening and closing tag for every element (<name>Alice</name>), which leads to significant repetition. JSON uses punctuation (colons, commas, braces) instead of tags, which is more concise but may initially look unfamiliar to non-programmers.
XML does have one readability advantage: element names appear twice (opening and closing tag), which can make the structure clearer in very long documents. With JSON, deeply nested structures can be harder to visually trace without a code editor that highlights matching braces.
Data Types
This is one of the most significant functional differences between the two formats.
JSON supports native data types:
- Strings, Numbers, Booleans (
true/false), andnull - No quotes needed for numbers and booleans -
"age": 30is clearly a number - Arrays are first-class (
[1, 2, 3])
XML has no native data types:
- Everything is text by default -
<age>30</age>is a string containing "30" - No native boolean, number, or null type
- Arrays must be represented by repeating elements (no dedicated array syntax)
- Type information must come from XML Schema (XSD) definitions
For developers, JSON's native types mean less parsing work. You do not need to convert "30" to an integer manually - it is already a number in the JSON.
Attributes vs Elements (XML Only)
XML has a feature JSON lacks: element attributes. You can store data either as child elements or as attributes on an element:
<!-- Attribute style -->
<person id="42" active="true">
<name>Alice</name>
</person>
<!-- Element style -->
<person>
<id>42</id>
<active>true</active>
<name>Alice</name>
</person>
This flexibility can become a design burden: XML developers must constantly decide whether data belongs in an attribute or a child element, and different teams make different choices, leading to inconsistent schemas.
Comments
XML supports comments: <!-- This is a comment -->
JSON does not support comments at all. This was deliberate. Douglas Crockford has explained that he removed them because he saw people using comments to hold parsing directives, a practice that would have destroyed interoperability between parsers. If you need comments in configuration, formats like YAML or TOML are better choices.
Namespaces
XML has a powerful namespace system that allows combining elements from different vocabularies without naming conflicts:
<root xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:svg="http://www.w3.org/2000/svg">
<html:div>This is an HTML element</html:div>
<svg:circle cx="50" cy="50" r="25"/>
</root>
JSON has no namespace system. In practice, this is rarely a problem for modern REST APIs, but it is essential for XML-based formats like XHTML, SOAP, and RSS that must combine multiple specifications.
Schema and Validation
Both formats have schema systems for validating document structure:
- XML has XSD (XML Schema Definition) - mature, widely supported, allows very precise constraints on element types, ordering, and frequency
- JSON has JSON Schema - well-supported across languages, simpler to write than XSD, but less comprehensive for ordering constraints
XSD is considered more powerful and precise, but JSON Schema is much easier to write and read.
Parsing Performance, Measured
"JSON parses faster" is usually stated without numbers, so here are some. These parse the same three files from the size test. Python times are the median of five fresh processes (Python 3.12, standard-library json and xml.etree.ElementTree), with peak memory taken from ru_maxrss. Browser times are the median of nine runs of JSON.parse and DOMParser in Chromium 151. All on the same Linux machine.
| Task | Time | Peak memory |
|---|---|---|
Python: json.loads | 161 ms | 83 MB |
Python: ElementTree.fromstring, element-style XML | 395 ms | 126 MB |
Python: ElementTree.fromstring, attribute-style XML | 274 ms | 110 MB |
Python: element-style XML parsed and converted to the same dicts json.loads returns | 925 ms | 159 MB |
Chromium: JSON.parse | 39 ms | - |
Chromium: DOMParser, element-style XML | 452 ms | - |
Chromium: DOMParser, attribute-style XML | 317 ms | - |
The raw parse gap is real but moderate in Python - about 2.5 times. The number that matters more is the fourth row. ElementTree gives you a tree of elements whose text is all strings; before your code can use the data, it has to walk that tree, call float() on totals and int() on quantities, and turn "true" into a boolean. json.loads does all of that during parsing. Counting the conversion, the XML route took 5.7 times as long.
In the browser the gap is wider still: JSON.parse was about 12 times faster than DOMParser, which builds a full DOM with nodes for every element and text run. That is the practical reason JSON won in front-end work - not payload size, but the cost of turning bytes into objects your code can use.
Two caveats. This is one dataset shape, and record-oriented data like this plays to JSON's strengths; a document-shaped XML file with mixed text and markup has no natural JSON equivalent to compare against. And other XML parsers, such as lxml or a streaming SAX parser, have different speed and memory profiles from the ones measured here. The scripts that generated and parsed these files are in the site's GitHub repository, so you can run them against your own data before a format decision rests on it.
When to Use JSON
- REST APIs and web services
- Configuration files for web applications
- Browser-to-server data exchange (JavaScript-native)
- NoSQL databases (MongoDB, Firebase, DynamoDB)
- Mobile app data exchange
- Any scenario where payload size matters
When to Use XML
- SOAP web services (enterprise B2B integrations)
- Document-centric formats (RSS/Atom feeds, XHTML, SVG, DocBook)
- Configurations requiring comments (Maven's pom.xml, Spring beans)
- Data that needs namespaces to combine multiple schemas
- Legacy system integrations that require XML
- Complex document transformations using XSLT
Migrating from XML to JSON
When converting XML data to JSON, the main design decisions are:
- Attributes - convert to regular key-value pairs:
id="42"becomes"id": 42 - Repeated elements - convert to arrays: multiple
<hobby>elements become a single"hobbies": [...]array - Text content with attributes - a common pattern like
<price currency="USD">9.99</price>must become an object:{"price": {"currency": "USD", "amount": 9.99}} - Types - take the opportunity to use proper JSON types: numbers without quotes, booleans instead of "true"/"false" strings
Explore JSON Structure After Converting from XML
After converting your XML to JSON, use JSON Keyper to extract all key paths and verify the structure is exactly what you expected.
Open JSON Keyper