Skip to content

The more RDF mappings, the better March 15, 2026

6.5 For an answer which cannot be expressed the question too cannot be expressed.

β€” Ludwig Wittgenstein Tractatus Logico-Philosophicus

Motivation

From time to time, I encounter discussions about which data formats are better to map to RDF:

  • TOML vs YAML?
  • BSON vs CBOR?
  • …and so on

This post argues that such discussions may not be entirely productive.

RDF

RDF (Resource Description Framework) is a very simple data model. Indeed, RDF 1.1 introduces very few notions β€” a node, a property, URI, Blank Node, and Literal. Datatype is not required for understanding; Named Graph and Dataset are a bonus. With this toolset, RDF aims to convey knowledge about this Multiverse.

RDF is not a silver bullet β€” it cannot be the best data model for every use case. Arguably, RDF can be described as a lingua franca β€” the intermediary model which facilitates communication among people and machines even if they speak many different data models, formats, and languages.

To that end, there are mappings of RDF to various data formats, through which it becomes straightforward to convey RDF semantics using native languages of systems which do not necessarily speak RDF.

Here is a small RDF graph in Turtle:

@prefix ex: <https://example.org/> .
@prefix schema: <https://schema.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:alice
  a schema:Person ;
  schema:name "Alice"@en ;
  schema:birthDate "1990-05-14"^^xsd:date ;
  schema:knows ex:bob ;
  schema:affiliation ex:acme .

ex:bob
  a schema:Person ;
  schema:name "Bob"@en .

ex:acme
  a schema:Organization ;
  schema:name "ACME Corp"@en .

Pro

  • Well-suited for authoring RDF by hand or with an LLM
  • Comments supported
  • Widely supported across RDF tooling
  • Concise, reduces repetition in objects and properties

Contra

  • Less familiar to developers outside the RDF community

The graph looks like this:

graph LR
  https___example_org_bob("Bob")
  click https___example_org_bob "https://example.org/bob"
  https___schema_org_Person("Person")
  click https___schema_org_Person "https://schema.org/Person"
  https___example_org_alice("Alice")
  click https___example_org_alice "https://example.org/alice"
  Literal-58cc6d78674efd8c82808811df4ceb0e[["πŸ“… 1990-05-14"]]
  https___example_org_acme("ACME Corp")
  click https___example_org_acme "https://example.org/acme"
  https___schema_org_Organization("Organization")
  click https___schema_org_Organization "https://schema.org/Organization"
  https___example_org_alice("Alice")
  click https___example_org_alice "https://example.org/alice"
  https___example_org_bob("Bob")
  click https___example_org_bob "https://example.org/bob"
  https___example_org_alice("Alice")
  click https___example_org_alice "https://example.org/alice"
  https___example_org_acme("ACME Corp")
  click https___example_org_acme "https://example.org/acme"
  https___example_org_alice("Alice")
  click https___example_org_alice "https://example.org/alice"
  https___schema_org_Person("Person")
  click https___schema_org_Person "https://schema.org/Person"
  https___example_org_bob --- 682794cd0cb5644813c3d85aae51823a(["type"])--> https___schema_org_Person
  click 682794cd0cb5644813c3d85aae51823a "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
  class 682794cd0cb5644813c3d85aae51823a predicate
  https___example_org_alice --- 3818b6860c769e13a276071ca633c8db(["birthDate"])--> Literal-58cc6d78674efd8c82808811df4ceb0e
  click 3818b6860c769e13a276071ca633c8db "https://schema.org/birthDate"
  class 3818b6860c769e13a276071ca633c8db predicate
  https___example_org_acme --- bc1686593bb7a726e3eb0e481c8353e8(["type"])--> https___schema_org_Organization
  click bc1686593bb7a726e3eb0e481c8353e8 "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
  class bc1686593bb7a726e3eb0e481c8353e8 predicate
  https___example_org_alice --- 2155f99084c4b0b6a75a5389e0a7e5c6(["knows"])--> https___example_org_bob
  click 2155f99084c4b0b6a75a5389e0a7e5c6 "https://schema.org/knows"
  class 2155f99084c4b0b6a75a5389e0a7e5c6 predicate
  https___example_org_alice --- da20e920e903efd69cb04b8202036091(["affiliation"])--> https___example_org_acme
  click da20e920e903efd69cb04b8202036091 "https://schema.org/affiliation"
  class da20e920e903efd69cb04b8202036091 predicate
  https___example_org_alice --- 2e806a3c86517dfd116832a4edfcf5ce(["type"])--> https___schema_org_Person
  click 2e806a3c86517dfd116832a4edfcf5ce "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
  class 2e806a3c86517dfd116832a4edfcf5ce predicate
  classDef predicate fill:transparent,stroke:transparent,stroke-width:0px;

Turtle is the default format of examples in RDF specifications, but it is not the only one.

JSON-LD based on JSON

JSON-LD is useful when a system already speaks JSON and you want Linked Data semantics without leaving that ecosystem.

{
  "@context": {
    "ex": "https://example.org/",
    "schema": "https://schema.org/",
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "birthDate": {
      "@id": "schema:birthDate",
      "@type": "xsd:date"
    },
    "knows": {
      "@id": "schema:knows",
      "@type": "@id"
    },
    "affiliation": {
      "@id": "schema:affiliation",
      "@type": "@id"
    }
  },
  "@graph": [
    {
      "@id": "ex:alice",
      "@type": "schema:Person",
      "schema:name": {
        "@value": "Alice",
        "@language": "en"
      },
      "birthDate": "1990-05-14",
      "knows": "ex:bob",
      "affiliation": "ex:acme"
    },
    {
      "@id": "ex:bob",
      "@type": "schema:Person",
      "schema:name": {
        "@value": "Bob",
        "@language": "en"
      }
    },
    {
      "@id": "ex:acme",
      "@type": "schema:Organization",
      "schema:name": {
        "@value": "ACME Corp",
        "@language": "en"
      }
    }
  ]
}

Pro

  • Native to web browsers and APIs; embeddable in <script> tags
  • Widely supported by search engines for structured data
  • JSON supported by every language & ecosystem

Contra

  • Comments not supported
  • Harder to write by hand or with an LLM

YAML-LD based on YAML

YAML-LD is useful when the same semantics should be carried in a format that is friendlier for manual authoring and configuration-oriented workflows.

"@context":
  "@import": https://json-ld.org/contexts/dollar-convenience.jsonld
  ex: https://example.org/
  schema: https://schema.org/
  xsd: http://www.w3.org/2001/XMLSchema#
  birthDate:
    "@id": schema:birthDate
    "@type": xsd:date
  schema:name:
    "@language": en

$id: ex:alice
$type: schema:Person
schema:name: Alice
birthDate: 1990-05-14
schema:knows:
  $id: ex:bob
  $type: schema:Person
  schema:name: Bob
schema:affiliation:
  $id: ex:acme
  $type: schema:Organization
  schema:name: ACME Corp

Pro

  • Supports the full JSON-LD data model
  • Well-suited for authoring RDF by hand or with an LLM
  • Supports comments
  • YAML supported by every language & ecosystem

Contra

  • YAML 1.1 has implicit type coercions that surprise developers, such as the Norway problem
    • Fixed by YAML 1.2

RDF/XML based on XML

RDF/XML remains useful wherever XML tooling, storage, or institutional constraints are already present.

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:schema="https://schema.org/"
    xmlns:ex="https://example.org/">

  <schema:Person rdf:about="https://example.org/alice">
    <schema:name xml:lang="en">Alice</schema:name>
    <schema:birthDate rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1990-05-14</schema:birthDate>
    <schema:knows rdf:resource="https://example.org/bob"/>
    <schema:affiliation rdf:resource="https://example.org/acme"/>
  </schema:Person>

  <schema:Person rdf:about="https://example.org/bob">
    <schema:name xml:lang="en">Bob</schema:name>
  </schema:Person>

  <schema:Organization rdf:about="https://example.org/acme">
    <schema:name xml:lang="en">ACME Corp</schema:name>
  </schema:Organization>
</rdf:RDF>

Pro

  • Over two decades of institutional adoption and tooling
  • XSLT, XQuery, XPath and other XML-specific tools available

Contra

  • Notoriously hard to read and write by hand or LLM
  • Multiple valid serialisations of the same graph make diffing hard

CBOR-LD based on CBOR

CBOR-LD is a binary format useful when bandwidth or storage is the constraint.

d9 05 01 a2 00 a6 62 65 78 74 68 74 74 70 73 3a
2f 2f 65 78 61 6d 70 6c 65 2e 6f 72 67 2f 63 78
73 64 78 21 68 74 74 70 3a 2f 2f 77 77 77 2e 77
33 2e 6f 72 67 2f 32 30 30 31 2f 58 4d 4c 53 63
68 65 6d 61 23 65 6b 6e 6f 77 73 a2 63 40 69 64
6c 73 63 68 65 6d 61 3a 6b 6e 6f 77 73 65 40 74
79 70 65 63 40 69 64 66 73 63 68 65 6d 61 73 68
74 74 70 73 3a 2f 2f 73 63 68 65 6d 61 2e 6f 72
67 2f 69 62 69 72 74 68 44 61 74 65 a2 63 40 69
64 70 73 63 68 65 6d 61 3a 62 69 72 74 68 44 61
74 65 65 40 74 79 70 65 68 78 73 64 3a 64 61 74
65 6b 61 66 66 69 6c 69 61 74 69 6f 6e a2 63 40
69 64 72 73 63 68 65 6d 61 3a 61 66 66 69 6c 69
61 74 69 6f 6e 65 40 74 79 70 65 63 40 69 64 0b
83 a6 02 6d 73 63 68 65 6d 61 3a 50 65 72 73 6f
6e 04 68 65 78 3a 61 6c 69 63 65 18 64 67 65 78
3a 61 63 6d 65 18 66 1a 26 4d f5 00 18 6a 66 65
78 3a 62 6f 62 6b 73 63 68 65 6d 61 3a 6e 61 6d
65 a2 06 65 41 6c 69 63 65 12 62 65 6e a3 02 6d
73 63 68 65 6d 61 3a 50 65 72 73 6f 6e 04 66 65
78 3a 62 6f 62 6b 73 63 68 65 6d 61 3a 6e 61 6d
65 a2 06 63 42 6f 62 12 62 65 6e a3 02 73 73 63
68 65 6d 61 3a 4f 72 67 61 6e 69 7a 61 74 69 6f
6e 04 67 65 78 3a 61 63 6d 65 6b 73 63 68 65 6d
61 3a 6e 61 6d 65 a2 06 69 41 43 4d 45 20 43 6f
72 70 12 62 65 6e 

406 bytes β€” 36% smaller than JSON-LD, using the reference JS implementation. With a registered context, compression would exceed 60%.

Pro

  • Dramatically smaller than any text format β€” fits RDF into QR codes, barcodes, and constrained devices
  • Builds on the JSON-LD ecosystem: any JSON-LD document can be encoded
  • Payload is self-describing via the 0xcb1d CBOR tag; no out-of-band schema needed

Contra

  • Binary β€” not human-readable or diffable
  • Full semantic compression requires contexts registered in the CBOR-LD registry

The point

RDF mappings do not compete with each other β€” they extend the reach of RDF as a lingua franca. Ideally, for every widely-used data format, a well-specified RDF mapping should exist.

The JSON-LD Working Group is working on making that happen. You are welcome to join.