Chapter 10. Brackets

Since the early 2000s, the web community has executed the largest format migration in its history: XML to JSON. That migration rewrote APIs, retired toolchains, and retrained developers over two decades. And what changed?

1999 2019
<person><name>Ada</name></person> {"person":{"name":"Ada"}}

Twenty years of progress.

Activity of this shape is lateral churn, motion that looks like innovation but isn’t. Real innovation is vertical: new layers, new semantics, new abstractions on top of what already works. That is how the web was designed to grow. Parts II and III have shown, formally, that the vertical direction was open the entire time.

Angle brackets and curly brackets riding a closed loop of track, beside an unused ladder that leaves the top of the frame

That historical claim can now be tested: if XML→JSON was lateral churn — a change of syntax presented as a change of substance — the seven properties should score both formats the same.

Both formats share one data model. An XML document and a JSON document are ordered labeled trees; their differences (attributes versus members, elements versus arrays) decorate the same structure. Chapter 5’s requirements apply to the structure, so the scores transfer wherever a requirement sees only the tree. R3 is the exception, and the formats part ways there.

R2. Trees have no coordination-free merge. Two JSON documents have no defined composition at all. Concatenation is not valid JSON, and “deep merge” is a per-application policy (which key wins, whether arrays append or replace). And a policy shared between parties is coordination. In the terms of Appendix B, meaning lives in arrangement (position, nesting, order). That rejects B-2d (atomicity: a state says exactly what its atoms say). So the representation lemma (B.1), the proof behind the union law, never gets started. ✗

R3. JSON has no reference type. A URL in a JSON string is a string; the format’s specifications define grammar and leave interpretation to applications, so nothing distinguishes a link from a postcode. XML held fragments of the property. Namespaces gave vocabulary terms global names; xml:id and XLink offered standardized reference, largely unused. The migration shed the fragments too. AWWW §4.4 named three good practices in 2004 (link identification, Web-wide linking, hypertext links), and all three fail in the format the industry migrated to. The destination format, JSON, scores ✗; the origin, XML, keeps a ~ for its surviving fragments.

The tooling gap

capability XML stack JSON stack
schema XSD (XML Schema), 2001 JSON Schema — drafts since 2010, still a draft
query XPath, 1999 JSONPath — RFC 9535, 2024
transformation XSLT, 1999 —
intra-document addressing fragments + XPointer JSON Pointer — RFC 6901, 2013
vocabulary scoping Namespaces, 1999 —

The JSON stack’s query language was standardized in 2024, twenty-five years after XPath, and it has no transformation or vocabulary-scoping language at all. The transformation role is filled by whatever framework is current (the table’s empty cell), and most JavaScript frameworks of 2010 have already been retired. The browsers froze XSLT at its 1999 revision; it still runs in every one of them as of this writing.

XML stack

The R-rows carry over from the argument above: the tree encodes any domain, the merge is missing, and the reference fragments go unused. The S-rows come from the tooling table. XPath and XSLT give query and transformation specified semantics, so S2 holds. Each capability has one standardized language, so components substitute and S3 holds. S1 is partial: a schema separates the vocabulary, but the document still fuses arrangement and data. S4 is partial: fragments and XPointer address into a document, but they are largely unused.

XML stack
R1 ✓ — trees encode any domain
R2 ✗ — no coordination-free merge; meaning lives in arrangement
R3 ~ — namespaces, xml:id, XLink: standardized fragments, largely unused
S1 ~ — vocabulary separated by schema; arrangement and data still fuse
S2 ✓ — XPath and XSLT: query and transformation with specified semantics
S3 ✓ — one standardized language per capability; components substitute
S4 ~ — fragments and XPointer address into documents, largely unused

JSON/REST

The S-properties of the deployment style the industry calls REST. The style’s genuine inheritance from HTTP survives in the scores: resources carry URIs, so S4 holds for whole JSON documents. Inside the JSON it fails: a URL is a string like any other, so a generic client cannot follow it from one document’s data to the next. The style’s own definition requires hypermedia links (Fielding 2000, §5.1.5); the deployments that adopted the style’s name discarded the requirement. Query and transformation semantics are implementation-defined (S2 ✗). Substituting a component means renegotiating a bespoke contract per pair of parties (S3 ~). Every payload ships arrangement and data fused (S1 ~; the endpoint separates, the representation does not).

JSON/REST
R1 ✓ — trees encode any domain
R2 ✗ — no defined composition; merge is per-application policy
R3 ✗ — no reference type; links are strings
S1 ~ — endpoints separate; representations fuse arrangement and data
S2 ✗ — interpretation left to applications; query standardized 2024, transformation never
S3 ~ — substitution behind bespoke contracts
S4 ~ — resources have URIs; values do not link onward

The opening question (and what changed?) now has a measured answer: the migration changed brackets, dropped the tooling, and gained no property. Three cells changed (R3, S2, S3), and every one moved down. The numbers show lateral churn.