JSON vs XML: how they differ and when each makes sense
A fair comparison of JSON and XML covering data types, attributes, namespaces, schemas, comments, mixed content, and verbosity, with side-by-side examples.
JSON is the default for new web APIs, but XML has not gone anywhere. It carries SOAP services, RSS and Atom feeds, SVG images, Office documents, Android layouts, and a great deal of enterprise integration. Choosing between them is rarely about which is better in the abstract. It depends on what you are modeling and which systems you must talk to. Here is how they compare in practice.
The same record in both formats
Seeing one record written both ways makes most of the differences concrete. Here is a book with two authors. In JSON the authors are an array of strings. In XML each author is a repeated element, and the ISBN is carried as an attribute rather than a child.
JSON:
{
"title": "Practical Data Formats",
"isbn": "978-0-00-000000-0",
"year": 2021,
"inStock": true,
"authors": ["Ana Ruiz", "Tom Lee"]
}
XML:
<book isbn="978-0-00-000000-0">
<title>Practical Data Formats</title>
<year>2021</year>
<inStock>true</inStock>
<authors>
<author>Ana Ruiz</author>
<author>Tom Lee</author>
</authors>
</book>Data model and types
JSON has a small built-in type system: objects, arrays, strings, numbers, booleans, and null. That maps directly onto the dictionaries, lists, and scalars of most programming languages, so parsing usually yields something you can use immediately. XML, by itself, has only elements, attributes, and text. Everything in text is a string until a schema or your code says otherwise. In the XML above, 2021 and true are just characters.
That difference cuts both ways. JSON's types make simple data easy, but it has no native date, no distinction between integer and decimal, and no way to say a number is a currency amount. XML Schema (XSD) offers a much richer set of types, including dates, durations, and decimals with constraints, which is one reason regulated or contract-heavy domains stayed with XML.
There is also a practical wrinkle with numbers. JSON leaves the precision of numbers to the parser, so a decimal such as 0.1 read into a binary float is not exact, and money should usually travel as a string or as an integer count of the smallest unit. XML does not fix that on its own, but an XSD can declare a field as xs:decimal with a given number of fraction digits, which at least documents the intent and lets a validator enforce it before the data reaches your code.
Features XML has and JSON does not
XML supports attributes, namespaces, comments, processing instructions, and mixed content. Mixed content is text interleaved with elements, like a paragraph with an inline bold tag, and it is the reason XML is a natural fit for documents (XHTML, DocBook, word processor files). JSON has no good equivalent; you would have to invent a convention for arrays of text and tagged runs.
Namespaces let one document combine vocabularies from different sources without name clashes, as SVG embedded in XHTML does. JSON has no namespace mechanism, and people usually fake it with prefixes in key names. XML also has mature tooling for querying and transformation, notably XPath, XQuery, and XSLT, as well as standard schema languages and a built-in way to comment a file. JSON lacks comments by design, which is a recurring annoyance in configuration.
Where JSON is stronger
For data exchange between programs, JSON is simpler. It is shorter, because there are no closing tags, and it is less ambiguous to read: there is no judgment call about whether a value should be an attribute or a child element, which has been argued over for decades in XML design. Browsers parse it natively with JSON.parse, and most languages convert it straight into native structures without an intermediate document tree.
The size difference is real but often overstated. After gzip compression, the gap between equivalent JSON and XML shrinks considerably because the repeated tag names compress well. Parsing speed varies by library and payload, so benchmark your own data if it matters instead of trusting a general claim.
Readability depends on the data. A list of records with simple fields reads well in JSON. A document with headings, paragraphs, and inline emphasis reads far better in XML, because the markup says what each run of text is. People sometimes force the second kind of content into JSON and end up with deeply nested arrays of objects with type and children keys, which is really XML reinvented with more punctuation. Matching the format to the shape of the content avoids that.
Schemas, validation, and tooling
Both formats can be validated. XML has DTD, XSD, and RELAX NG, and the tooling has been stable for a long time. JSON has JSON Schema, which is widely implemented and used by OpenAPI to describe request and response bodies, although it is a separate specification and several drafts exist, so check which draft your validator supports.
For everyday reading, tooling matters too. Formatted XML and JSON are both readable, but deeply nested JSON arrays of objects are often easier to scan as a table or a tree, and View My JSON offers those views for JSON documents. For XML you would use an XML-aware editor, an XPath tester, or convert to JSON first when the structure allows it.
Choosing between them
If you are building a new REST or GraphQL API, a front-end data feed, or a configuration format for developers, JSON is the usual choice because everything in the ecosystem expects it. If you are integrating with a SOAP service, publishing a feed that readers consume as RSS or Atom, working with documents that mix prose and markup, or required to validate against a published XSD, use XML.
Converting between them is not always lossless. An XML document with attributes, repeated elements, and mixed content has no single obvious JSON equivalent, and tools use different conventions, such as prefixing attribute names with @. A single element and a repeated element can also turn into an object in one case and an array in the other, which surprises consumers. When you must convert, define the mapping explicitly and test it with real samples, including the edge cases like empty elements and a lone child.