Cloud Parts

XML

The W3C’s markup language for trees of tagged text, still behind Office documents, SVG, feeds, SOAP and the S3 API.

What it is
File formats (text and markup)
Type
Open source
Made by
W3C (open standard)
License
Open standard, free to implement (W3C Recommendation)
Facts checked
6 October 2026

What it is

An XML document is a tree of elements. Each element has a start and end tag (<order id="42">…</order>, or <empty/>), and may hold attributes, text, other elements, comments (<!-- -->) and CDATA sections. A document must be well-formed: one root element, properly nested tags, quoted attribute values. When a parser finds a well-formedness error, the spec says it must stop passing data to the application. Everything is text: XML itself has no numbers or dates, and types come from a schema. An optional document type declaration (DTD) describes the allowed structure and defines entities, named pieces of replacement text, including external entities that point at a file or URL. Namespaces qualify element names with a URI, so vocabularies such as SVG can be mixed into other documents without name clashes.

The core spec is a W3C Recommendation, XML 1.0, now in its Fifth Edition (November 2008), and free to implement. Around it sit W3C XML Schema (XSD 1.1, 2012) for structure and data types, RELAX NG (ISO/IEC 19757-2) as a simpler schema language, and XPath 3.1 (2017) for selecting nodes. XML still defines Office Open XML documents (ECMA-376), SVG, RSS and Atom feeds and SOAP messages. Amazon S3’s REST API answers in XML, and Azure Blob Storage’s List Blobs returns XML unless a client asks for its newer Apache Arrow format.

Why teams pick it

  • Mature standards for validation (DTD, XSD, RELAX NG) and querying (XPath), so documents can be checked strictly
  • Mixed content (text with markup inside it) suits documents such as Office files and SVG
  • Namespaces let one document combine vocabularies from different owners without clashing names
  • Strict well-formedness: a broken document is rejected instead of being guessed at

Watch out for

  • Verbose by design: the spec says terseness “is of minimal importance”, and every end tag repeats its name
  • No data types without a schema; every value arrives as text and the application converts it
  • Unsafe parser defaults: resolving DTDs and external entities opens the door to XXE (reading local files, server-side request forgery) and “billion laughs” entity-expansion attacks; OWASP’s advice is to disable DTDs entirely
  • Namespaces trip up code: S3 puts every element of its responses in a default namespace, so unqualified lookups find nothing

Alternatives

What all text and markup have in common →

How it fits with other technologies

Parsing an S3 ListObjectsV2 response: mind the default namespace · python

import xml.etree.ElementTree as ET  # Expat underneath; doesn't fetch external entities by default

body = """<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Name>amzn-s3-demo-bucket</Name>
  <Prefix>logs/</Prefix>
  <KeyCount>2</KeyCount>
  <MaxKeys>1000</MaxKeys>
  <IsTruncated>false</IsTruncated>
  <Contents>
    <Key>logs/2026-10-05.jsonl.gz</Key>
    <Size>857</Size>
  </Contents>
  <Contents>
    <Key>logs/2026-10-06.jsonl.gz</Key>
    <Size>1204</Size>
  </Contents>
</ListBucketResult>"""

root = ET.fromstring(body)
print(root.findall("Contents"))  # [] : unqualified names match nothing

ns = {"s3": "http://s3.amazonaws.com/doc/2006-03-01/"}
for obj in root.findall("s3:Contents", ns):
    key = obj.findtext("s3:Key", namespaces=ns)
    size = int(obj.findtext("s3:Size", namespaces=ns))  # everything is text
    print(key, size)
# logs/2026-10-05.jsonl.gz 857
# logs/2026-10-06.jsonl.gz 1204

JSON, YAML, TOML and XML side by side#

Four text formats for structured data. They overlap, but each grew up around a different job, and that shows in what they leave out.

JSONYAMLTOMLXML
Current specRFC 8259 and ECMA-404 (both December 2017)YAML 1.2.2 (October 2021), a revision of 1.2 from 2009TOML 1.1.0 (December 2025)W3C XML 1.0, Fifth Edition (November 2008)
CommentsNone# to the end of the line# to the end of the line<!-- … -->
Built-in value typesString, number, boolean, nullNull, boolean, integer, float and string in the recommended core schema; others through tagsString, integer, float, boolean, offset and local date-times, dates and timesNone: content is text until a schema gives it types
NestingObjects and arraysMappings and sequences; anchors and aliases reuse a nodeTables, arrays, inline tables and arrays of tablesElements with attributes; namespaces mix vocabularies
Schema languageJSON Schema, a separate spec (latest 2020-12)None; the spec’s “schemas” only decide how unquoted values are typedNone in the specDTDs (part of XML 1.0), W3C XML Schema (XSD), RELAX NG
Typical useWeb API bodies; JSON Lines logs and eventsKubernetes manifests, GitHub Actions workflows, Compose filesCargo.toml, pyproject.toml, Telegraf configOffice documents, SVG, RSS and Atom feeds, SOAP, the S3 API
  • Each cell is taken from the format’s own specification, and typical uses from the documentation of the tools named. The same table appears on the JSON, YAML, TOML and XML pages.

See it in a real stack

No architecture uses XML yet. Drop it into the playground and wire it up yourself.Open playground →
Where it came from1996–2008

The Web of the mid-1990s served HTML, one fixed set of tags. SGML, the general markup standard, let anyone define their own tags, but its documents couldn’t be served on the Web the same way. In 1996 the W3C formed a working group, at first called the SGML Editorial Review Board and chaired by Jon Bosak of Sun Microsystems, to let “generic SGML” be served, received and processed on the Web the way HTML was. Its answer was a subset of SGML small enough to be described completely in one spec. Edited by Tim Bray, Jean Paoli and C. M. Sperberg-McQueen, XML 1.0 became a W3C Recommendation on 10 February 1998.

A family of standards grew around it: Namespaces in 1999, W3C XML Schema in 2001, and formats built on XML such as SOAP, RSS, Atom (2005) and Office Open XML (2006). In December 2006, Douglas Crockford pitched JSON to the XML 2006 conference as “the fat-free alternative to XML” for data exchange in browsers. The Fifth Edition of XML 1.0, published in November 2008, is still the current text.

Why it’s built this way

A subset of SGML
Compatibility with SGML was a design goal, so SGML tools could still process XML documents, while another goal kept XML easy to write programs for.
Errors are fatal
The goals asked for programs that are easy to write and for optional features to be kept to “the absolute minimum, ideally zero”. A processor that hits a well-formedness error must stop normal processing, so parsers don’t each invent their own recovery.
Terseness is of minimal importance
An explicit design goal. Clarity and easy processing beat compactness, which is why every end tag repeats its element’s name.
Namespaces as URIs, added a year later
Mixing vocabularies needed globally unique names. The 1999 Namespaces spec qualified names with URIs, often written as web addresses, without changing XML 1.0 itself.

Timeline

  1. 1996

    W3C forms the SGML Editorial Review Board, chaired by Jon Bosak

  2. 1998

    XML 1.0 becomes a W3C Recommendation (10 February)

  3. 1999

    Namespaces in XML (January)

  4. 2001

    W3C XML Schema 1.0 (May)

  5. 2005

    Atom syndication format published as RFC 4287

  6. 2006

    ECMA-376 standardises Office Open XML (December)

  7. 2008

    XML 1.0 Fifth Edition, the current text (November)

Sources29 · facts checked 6 October 2026

Improve this page on GitHub