-
Notifications
You must be signed in to change notification settings - Fork 5
RDF 1.2
The new version of RDF, version 1.2, has been a W3C working draft for several years now and is shortly expected to become a candidate recommendation, indicating that the RDF working group it believes the spec works as intended. This represents a step towards RDF 1.2 becoming a full W3C recommendation, as well as a huge leap forwards for the capabilities of RDF based systems.
This article offers a deep dive on the main issues with RDF 1.1 that the RDF 1.2 specification seeks to address, as well as an exploration of some RDF 1.2-adjacent topics.
The Short Version For anyone who already has a good understanding of RDF 1.1, we’ll provide a briefer summary here that skips most of the explanation. For everyone else, the remainder of the document will provide a more robust explanation.
The very short version is that RDF1.2 introduces a new pattern for reification in the form of a “Triple Term”, which is a new type of value that can appear in the object portion of a triple. A triple term is just a triple-inside-a-triple, and when serialized they are often represented with double-angle brackets like this:
:foo :bar <<:foo :bar :baz>>.Triple Terms serve two major use cases:
- They allow for triples to be annotated with new or qualifying information.
- They allow for a distinction to be drawn between asserted data and claimed data.
Whilst triple terms can appear as the object of any triple, there are a few special effects that occur when a triple term appears alongside a particular predicate from the RDF controlled vocabulary, or when a triple term also appears as a triple in its own right – we will cover these later in the article but they both relate to the two use cases above.
Although there are also many more changes in the RDF1.2 specification, triple terms are the only addition that can be described as a "major" new feature.
RDF 1.2 marks the second occasion that RDF and its ecosystem has been given a version update in the 25 years since it was first conceived.
The first RDF specification was published in 1999 and consisted of a single document covering the model itself which, at the time, was closely coupled to the XML and HTML exchange formats. By 2004, the original specification, having grown in complexity, was split out into six separate documents published as RDF 1.0. Whilst the core RDF concepts were all present in the 1.0 spec, much of the terminology that we use today was absent.
In 2014, the RDF 1.1 specification(s) were published, now having grown to over ten documents. RDF 1.1 represents the specification we use today and introduced many new features, including:
- Changes to the definition of RDF identifiers, including the introduction of the term IRI (Internationalised Resource Identifier) which allowed the inclusion of characters from non-English languages.
- The idea of a “Dataset” is introduced – this being a collection of named RDF graphs. As an aside, the idea to include these started life in the SPARQL query language specification.
- Multiple new serialisation recommendations are introduced on top of the original XML format – these include Turtle, Trig, N-Quads and JSON-LD.
- Various smaller changes are made to the way that literals are handled, chiefly that any un-qualified literals are now assumed to be strings.
Today, RDF is accompanied by a healthy set of adjacent specifications that make up the semantic web ecosystem, such as SPARQL (2008), SKOS (2009), SHACL (2015) and OWL (2004). Despite healthy growth and adoption, RDF users have noted various shortcomings in the 1.1 specification, and at the start of 2023 a new version of RDF entered the draft phase of becoming a W3C recommendation. We will likely see this progress to becoming a candidate recommendation at some point in 2026.
The foundations of what would become the RDF 1.2 specification were first established in the 2014 paper Foundations of an Alternative Approach to Reification in RDF (Hartig, Thompson) which proposed an extension to RDF called “RDF-star”. This would provide an easier method of making “statements about statements” within RDF data, and a W3C working group was stood up whose charter was centred around the proposed extension.
The issue this proposal addresses is more easily explained with an example - consider the following RDF statement:
:bob :knows :alice.Statements like this are easy to make in RDF and are the bread-and-butter of all RDF graphs. In isolation they are easy to interpret for both humans and computers, but they do also carry a limitation: Imagine we wanted to further qualify this statement in various ways.
- We might want to explain where this statement came from.
- We might want to express our confidence about how true this statement is.
- We might want to provide more information about the nature of this relationship, such as how long they’ve known each other or the location where they met.
We cannot annotate the statement directly because RDF only allows the creation of binary relations between two terms, so there’s no way of making additional statements about an existing statement. To accommodate this kind of annotation, we will need to do some clever data remodelling. Fortunately, there are already some established RDF modelling patterns that cater to this exact scenario which we will cover over the next few sections. None of these patterns are ideal, as they all force us increase the complexity of our data model in order to accommodate the limitations of RDF. Annotating data is a major use case in modern information systems, and RDF as it stands does not make this simple.
The following sections cover off some established patterns for dealing with the issue described above. After we’ve covered these, we will demonstrate how RDF1.2 introduces a new approach to qualifying triples – one that provides the same benefits but with none of the downsides.
The RDF 1.1 specification includes a standard method of qualifying any statement in an abstract, reproducible manner by remodelling statements as resources. This is known as reifying (ray·uh·fai·ing) and once you have performed the transformation, the statement can be referred to as a reified statement. The following example demonstrates the result of transforming the statement above (“bob knows alice”) into a reified statement:
_:n a rdf:Statement;
rdf:subject :bob;
rdf:predicate :knows;
rdf:object :alice.All the knowledge is still there, but now the data is in a shape such that we can say additional things about it…
_:n :knownSince “01-01-1999”.We’ve had to introduce several new triples to accommodate this pattern, which means our data is going to be larger (generally not a good thing, particularly in matters relating to data exchange and processing). The data has also become more difficult to query directly as we now need to accommodate for this additional complexity in the querying payload. The fact that this uses a standard vocabulary opens the door to generalising our interactions over the data, although it should be noted that the spec itself does not formally define these generalisations, it only mentions informally that the intended use case for these terms is to act as metadata describing other RDF triples: we should therefore not expect to see any formal support for this pattern inside of any RDF tooling and we should not assume that the presence of a reified statement formally implies the existence of a concrete triple (although this may be a local convention that we adopt).
In RDF 1.2, this pattern is referred to as “old style reification”.
RDF 1.1 introduced the concept of a named graph – a fourth component within a triple that can be used to group statements together under a single resource. This new resource can then be used to make statements that cover everything in the group. Typical use cases for named graphs include data provenance and access control.
There’s no restriction on the number of triples that can belong to a named graph, so we could include a unique named graph for each triple we want to qualify and then make additional statements against that named graph.
:bob :knows :alice :g1.
:g1 :knownSince “01-01-1999”.This captures all the knowledge we want to model but carries with it many of the same disadvantages we saw in the first pattern. It will introduce an explosion of named graphs within our dataset (one for every triple we want to qualify) which will bloat the size of our data if we were to serialise it. Even though technically this pattern would work, it feels like an anti-pattern as it isn't really in the spirit of what named graphs were designed for: this means most triple stores are unlikely to be optimised for the presence of many tiny named graphs. Users querying this data will also have a harder time because they now need to accommodate for named graphs in their queries (these queries are also more expensive than basic graph pattern matching).
Qualified relation is another example of a pattern that involves re-modelling a triple statement into a resource. Unlike the reified statement pattern we saw earlier, here we use a vocabulary of our own choosing as opposed to a standard one. For the relationship between Bob and Alice, a qualified relation might look like this:
:relationship1 a :KnowsRelationship;
:personA :bob;
:personB :alice.This captures both the nature of the relationship (implied by the class “KnowsRelationship”) and the directionality of the relationship (:personA knows :personB). Now that the relationship is a resource, we can make additional statements about it as normal:
:relationship1 :began “01-01-1999”.This approach feels much more expressive than what we’ve seen so far, but it does contrast with the standards-focussed principles at the heart of Linked Data. To counter this, qualified resources can be implemented as an abstraction of the reified statement pattern seen above, as demonstrated by the following metadata:
# Abstraction
:QualifiedRelationship rdfs:subclassOf rdf:Statement.
:lhs rdfs:subclassOf rdf:subject.
:rhs rdfs:subclassOf rdf:object.
:relationshipType rdfs:subclassOf rdf:predicate.
# Usage
:personA rdfs:subclassOf :lhs.
:personB rdfs:subclassOf :rhs.
:KnowsRelationship rdfs:subclassOf :QualifiedRelationship;
:relationshipType :knows.
With this, we have captured all the semantics we need in order to automate our data back to not only the original triple, but also to a reified statement of that same triple (it should be noted though that none of this is defined by the RDF specification itself, this is just a local convention of our own devising). This abstraction carries the advantage of us having expressed the knowledge using slightly less data than we would have if we’d just used the standard vocabulary directly.
This pattern has still increased the size of our data and the complexity of our queries (which now need to be much more specific about what they're asking for) - it therefore carries the same disadvantages we’ve seen in the other patterns albeit to a slightly lesser degree. In addition, it has required us to create a new “mini ontology” which, while arguably more expressive, does come with a maintenance cost and a design overhead.
This final pattern is only peripherally related to the topic we’re discussing in this article but it’s worth mentioning briefly to draw contrast with the qualified relation pattern seen above. Let’s remove the directionality from a qualified relationship by replacing “personA” and “personB” with “involves”, and then adding a few more people into the mix:
:friendsGroup a :KnowsRelationship;
:involves :bob;
:involves :alice;
:involves :carlos;
:involves :david.By assuming that these people all know each other, we’ve captured twelve separate relationships between four people (although we have lost all of the pairwise directionality of qualified relations). This pattern is known as an n-ary relation and we can say things about such relations just as we have done in the other examples;
:friendsGroup :began “01-01-1999”.When we group like this, we are limited to only making statements about everyone in the group at once. This pattern makes our data significantly more expensive to query too, as a query engine will need to consider many more triples to figure out if bob and alice know each other.
The problems with the patterns we’ve seen so far can broadly be categorised as follows:
- They all make our data bigger – obviously adding additional information will always increase the size of our data, the complaint here is that these are changes that are required simply to accommodate making qualifying statements in the first place.
- They all make our data more complex to query and work with.
- They all make our data less conventional and therefore less efficient due to the fact that RDF tooling can’t be optimised for local conventions.
There is another problem that none of the patterns we’ve seen address, one that relates to the nature of metadata itself. Consider the following statement...
“According to Data Source A, Bob knows Alice”
Does this statement represent the truth? Well… partly. It is, at best, a version of the truth according to a particular data source. Whilst the statement as a whole might be true, it does not necessarily follow that Bob really does know Alice – that’s just a claim that’s being made (possibly even a disputed one). This distinction between a “Truth” and a “Claim” is important when it comes to certain entailment regimes (such as OWL) and for certain types of data analysis.
Up to now, RDF has provided no formal way of indicating this distinction - this blocks us from creating general-purpose automations around our data because we are required to interpret what is and isn't asserted on a case-by-case basis.
RDF 1.2 introduces many smaller changes to the RDF specification, most of which are around the clarification of edge cases and the definitions of what is and isn’t permitted under certain scenarios. The big change, and the one that addresses the problems we’ve been discussing in this article, is the introduction of Triple Terms.
The specification stipulates that there are two versions of RDF 1.2:
- Basic: Everything in 1.2 except triple terms (these are instead handled as normal triples with vocabulary conventions to identify them).
- Full Conformance: Everything in 1.2 including triple terms.
Splitting these out allows for more compatibility with existing tooling, as it allows the basic version of RDF 1.2 to exist in an RDF 1.1 store. An interoperability document was created in January 2026 that formally explains how to convert from Basic to Full and vice versa, including how to represent RDF 1.2 triple-terms as standard RDF1.1 formatted triples.
Triple Terms were formerly known as Quoted Triples, which implied that they would always refer to some kind of concrete triple somewhere else in the graph. As various other use cases emerged, the broader name "triple term" was adopted, even though the functionality has largely remained the same. Take our example from before;
“According to Data Source A, Bob knows Alice”
We can begin representing this using a “triple term” as follows;
:my_reifier rdf:reifies << :bob :knows :alice >>.A triple term is defined as a triple that appears in the object portion of another triple – something that was not possible in RDF 1.1. These triples are not considered to have been asserted, rather they are referred to in the spec as propositions – mere “claims” that may or may not be true. When a triple term appears alongside the rdf:reifies predicate, as in the statement above, several formal definitions come into play:
- The whole statement becomes known as a reifying triple.
- The resource in the subject portion of the reifying triple (
:my_reifierin the above example) becomes formally known as a reifier.
Reifiers can be used to make additional statements their associated triple term.
:my_reifier :accordingTo :dataSourceA.Sometimes, a statement can exist both within a reifiying triple and as an asserted triple, such as in the following example:
:my_reifier rdf:reifies << :bob :knows :alice >>. #reifying triple
:bob :knows :alice. # asserted tripleThe specification attributes special significance to this combination: under these conditions, additional statements made using the reifier become known as triple annotations.
:b1 :knownSince “01/01/1999”. # triple annotationWith these changes, RDF 1.2 covers off both the issues we talked about earlier: we now have a formal way of making statements about statements as well as a formal way of indicating whether such statements are assertions or propositions. All of this has been achieved without significantly increasing the complexity or size of our data, and as these patterns are now formally part of the specification we can expect to see RDF tooling begin to optimize for them.
RDF itself is part of a wider ecosystem of specifications that collectively are referred to as the “semantic web” - many of these other specs are seeing an upgrade in step with 1.2, this section covers off some of these.
The same working group responsible for delivering RDF 1.2 is also upgrading the SPARQL specification. Users can query for asserted triples as normal, but there’s also a new syntax that allows for triple-terms to also be queried on their own:
PREFIX : <http://www.example.org/>
SELECT ?datasource WHERE {
<< :bob :knows :alice >> :accordingTo ?datasource .
}In addition, several new functions are provided for working with triple terms (for example, functions for binding values to them in a query in much the same way that you already can with resources).
It’s worth noting that despite including the triple term here at the start of the graph pattern, this is purely a SPARQL abstraction over the underlying model which still expects triple terms to exist in the object portion of a statement. The above query will also not return any results unless the underlying data follows the “reifying triple” pattern described earlier.
As well as the query syntax itself, all of the other accompanying SPARQL documentation has been updated, such as the SPARQL Protocol document that describes SPARQL endpoint APIs.
The serialization languages associated with RDF have also been upgraded to accommodate the new syntax – we won’t cover them all here but let’s take a quick look at Turtle (it being the most human readable syntax). We can represent the statements we saw above using the same double angle-bracket syntax we saw in the new SPARQL syntax:
PREFIX : <http://www.example.org/>
<< :bob :knows :alice >> :accordingTo :datasource1 .As with the SPARQL syntax covered above, we get some syntactic sugar here that makes it appear as though we’ve got a triple term in the “subject” portion of a statement, but when this is deserialized back to raw data it will be rewritten as a reifier, making it look more like this:
_:b0 rdf:reifies <<:bob :knows :alice>>; :accordingTo :datasource1.The RDFS document remains largely unchanged, except for the addition of the vocabulary used to talk about triple terms such as rdf:reifies (seen earlier in this document) and various other tweaks to align it to RDF 1.2.
This document has also moved some vocabulary terms into a “legacy” status, indicating that whilst they may still be supported by some systems, they are no longer recommended. The main two items included in this section are RDF containers (such as Bag and Sequence) and terms relating to the “old style reification” we saw earlier.
The SHACL specification is being updated by a different working group, the Data Shapes working group, but their charter is built around the same motivation which is to keep SHACL aligned with RDF 1.2.
This working group also appears to have taken the opportunity to expand the corpus of documents with some interesting looking new additions, seemingly taking advantage of the version bump to put some additional effort towards some previously undocumented use cases, including a spec that defines SHACL’s use as a UI generation tool. The addition of these documents suggests the working group is keen to see SHACL recognized as more than just “validation for RDF” and to expand its applicability into other use-cases where having a “closed world” view over a data model can provide further methods of data automation.
© Crown Copyright GCHQ 2026 - This content is licensed under the Open Government License 3.0