Copyright © 2020-2026 the Contributors to the JSON-LD-star Specification, published by the JSON for Linked Data Community Group under the W3C Community Contributor License Agreement (CLA). A human-readable summary is available.
This NOTE describes an extension to [JSON-LD11], [JSON-LD11-API], and [JSON-LD11-FRAMING] to allow arcs in a Linked Data Graph to be annotated using the [RDFStar] model.
This specification was published by the JSON for Linked Data Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.
This is an unofficial proposal.
GitHub Issues are preferred for discussion of this specification. Alternatively, you can send comments to our mailing list. Please send them to public-linked-json@w3.org (subscribe, archives).
RDF-star and SPARQL-star [RDFStar] addresses the problem of annotating arcs in a Linked Data Graph by extending the RDF data model [RDF11-CONCEPTS] to allow for triples to be used as the subject or object of another RDF triple. This note describes an update to the JSON-LD data model to allow limited form of a node object to use another node object as its node identifier.
The two popular graph-based data models have been RDF [RDF11-CONCEPTS] and Labeled-property Graphs, which are roughly similar, with the RDF model being more formal in identifying nodes, datatypes and relationships, while Property Graphs use a less formal relationship model somewhat similar to JSON. In both models, nodes are related via edges (AKA arcs), but in Property Graphs, those edges may themselves be annotated with properties. This is useful in providing additional metadata and semantics to relationships of the nodes.
Historically, in RDF, this can be simulated through Reification, where a triple is represented by another resource with properties for the subject, predicate, and object, which allows additional properties to be asserted on that reification node.
@base <http://example.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix : <#> .
:bob :age 42 .
# Reification of previous triple
[
a rdf:Statement;
rdf:subject :bob;
rdf:predicate :age;
rdf:object 42
] .
In [RDFStar], a triple may act as the subject or object in another triple, for example, we can modify how certain we are about a relationship as follows:
@base <http://example.org/> .
@prefix : <#> .
:bob :age 42.
<< :bob :age 42 >> :source <http://example.org/~bob/>.
This NOTE explores an extension of JSON-LD which can allow
the value of an @id property to be an embedded node,
and the description of an annotation object which serves as
a short-hand when the annotated value also is described
directly in the graph.
Terms imported from ECMAScript Language Specification [ECMASCRIPT], The JavaScript Object Notation (JSON) Data Interchange Format [RFC8259], Infra Standard [INFRA], XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition) [XPATH-FUNCTIONS], and Web IDL Standard [WEBIDL]
true and false that are used
to express one of two possible states.In the internal representation a JSON object is described as a map (see [INFRA]), composed of entries with key/value pairs.
In the Application Programming Interface, a map is described using a [WEBIDL] record.
@context where the value,
or the @id of the value, is null,
explicitly decouples a term's association with an IRI.
A map entry in the body of a JSON-LD document
whose value is null
has the same meaning as if the map entry was not defined.
If @value, @list, or @set is set to null in expanded form,
then the entire JSON object is ignored.true, or false.A and B),
using Unicode Codepoint Collation,
as defined in XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition) [XPATH-FUNCTIONS],
which defines a
total ordering
of strings comparing code points.
Note that for UTF-8 encoded strings, comparing the byte sequences gives the same result as code point order.
Terms imported from Internationalized Resource Identifiers (IRIs) [RFC3987]
@type,
and values of terms defined to be vocabulary relative
are resolved relative to the vocabulary mapping,
not the base IRI.Terms imported from RDF 1.1 Concepts and Abstract Syntax [RDF11-CONCEPTS], RDF Schema 1.1 [RDF-SCHEMA], and Linked Data Design Issues [LINKED-DATA]
_:._:.rdf:langString, an optional language tag.@direction key
whose value must be one of the strings "ltr", "rtl", or null.
See the Context Definitions section of JSON-LD 1.1 for a normative description.
@language key
whose value must be a string representing a [BCP47] language code or null.
See the Context Definitions section of JSON-LD 1.1 for a normative description.
@default key.@context entry of one of the following:
a node object, a value object, a graph object, a list object,
a set object, the value of a nested property,
or the value of an expanded term definition.
Its value may be a map for a context definition,
as an IRI, or as an array combining either of the above.
@graph entry,
and may also have @id, and @index entries.
A simple graph object
is a graph object which does not have an @id entry.
Note that node objects may have a @graph entry,
but are not considered graph objects if they include any other entries.
A top-level object consisting of @graph is also not a graph object.
Note that a node object may also represent a named graph if it includes other properties.
See the Graph Objects section of JSON-LD 1.1 for a normative description.
@container set to @id.
The values of the id map must be node objects,
and its keys are interpreted as IRIs representing
the @id of the associated node object.
If a value in the id map contains a key expanding to @id,
its value must be equivalent to the referencing key in the id map.
See the Id Maps section of JSON-LD 1.1 for a normative description.
@container is set to @graph.@included or an alias of @included
and the value is one or more node objects.
See the Included Blocks section of JSON-LD 1.1 for a normative description.
@container set to @index,
whose values must be any of the following types:
string,
number,
true,
false,
null,
node object,
value object,
list object,
set object, or
an array of zero or more of the above possibilities.
See the Index Maps section in JSON-LD 1.1 for a formal description.
rdf:JSON.
In the value object representation, the value of @type is @json.
JSON literals represent values which are valid JSON [RFC8259].
See the The rdf:JSON Datatype section in JSON-LD 1.1 for a normative description.
true or false,
a typed value,
or a language-tagged string.
It represents an RDF literal.
@container set to @language,
whose keys must be strings representing [BCP47] language codes
and the values must be any of the following types:
null,
string, or
an array of zero or more of the above possibilities.
See the Language Maps section of JSON-LD 1.1 for a normative description.
@list key.
It may also have an @index key, but no other entries.
See the Lists and Sets section of JSON-LD 1.1 for a normative description.
@context keyword.@value, @list, or @set keywords, or@graph and @context.@id key.@version entry in a context,
publishers can ensure that processors conformant with JSON-LD 1.0 [JSON-LD10]
will not accidentally process JSON-LD 1.1 documents, possibly creating a different output.
The API provides an option for setting the processing mode to json-ld-1.0,
which will prevent JSON-LD 1.1 features from being activated,
or error if @version entry in a context is explicitly set to 1.1.
This specification extends JSON-LD 1.0
via the json-ld-1.1 processing mode.@context entry. It has the same form as an embedded context.
When the term is used as a type, it defines a type-scoped context,
when used as a property it defines a property-scoped context.
@set entry.
It may also have an @index key, but no other entries.
See the Lists and Sets section of JSON-LD 1.1 for a normative description.
@container set to @type,
whose keys are interpreted as IRIs
representing the @type of the associated node object;
the value must be a node object, or array of node objects.
If the value contains a term expanding to @type,
its values are merged with the map value when expanding.
See the Type Maps section of JSON-LD 1.1 for a normative description.
@value entry.
See the Value Objects section of JSON-LD 1.1 for a normative description.@vocab key
whose value must be an IRI, a compact IRI, a term, or null.
See the Context Definitions section of JSON-LD 1.1 for a normative description.false.
true,
and the reverse flag defaults to false.
false,
and the vocab flag defaults to true.
@graph entry,
or only if required to represent multiple node objects.As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, and MUST NOT in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
A JSON-LD-star document complies with this specification if it follows the normative statements in 7. Grammar Extensions. For convenience, normative statements for documents are often phrased as statements on the properties of the document.
This specification makes use of the following namespace prefixes:
| Prefix | IRI |
|---|---|
| ex | http://example.org/ |
| rdf | http://www.w3.org/1999/02/22-rdf-syntax-ns# |
| xsd | http://www.w3.org/2001/XMLSchema# |
These are used within this document as part of a compact IRI
as a shorthand for the resulting IRI, such as dcterms:title
used to represent http://purl.org/dc/terms/title.
This section is non-normative.
The Following terms are used within specific algorithms.
@annotation (or an alias). It describes [RDFStar] annotations
made on the triple between by its parent node object or value object, and the parent's closest ancestor node object.
@type or an IRI.
The property value MUST be either an IRI, blank node, literal or an embedded node.
An embedded node MAY contain other entries that do not, themselves, create directed-arcs, such
as @context or @index.
An embedded triples is the representation of an embedded triple.
This section is non-normative.
This specification adds the concepts of an embedded node and annotation object to JSON-LD in order to add the ability to make statements about individual triples in an RDF-star Graph.
An embedded node supports the ability to make one or more statements about a triple, represented by an embedded node, without that triple being necessarily considered to be part of the Linked Data Graph.
The following example shows how the value of @id can be an
of embedded node, which expresses a single triple:
An annotation object supports the ability to make one or more statements (annotations) about a triple, where the triple is considered to be part of the Linked Data Graph.
This section is non-normative.
JSON-LD allows many more sophisticated ways of describing data and both embedded nodes and annotation objects work along with these other features, to the extent that they are used in describing a single relationship.
This section is non-normative.
JSON-LD allows the description of JSON-LD 1.1
within node objects, either by defining a term using @reverse, or using
@reverse directly within a node object.
An embedded node MUST NOT, itself, use a reverse property.
The relationships between nodes can be reversed even when those nodes use embedded objects:
Annotations may themselves use reverse properties, in which case the annotated triple will be the object (instead of the subject) of the annotation:
This section is non-normative.
[RDFstar] allows embedded triples to contain other embedded triples, recursively. Similarly, an embedded node may be made up of other embedded nodes, and annotations may be made upon embedded nodes.
This section is non-normative.
Annotation objects and embedded nodes can be used together. As well, annotation objects can be used to annotate embedded nodes (see 5.2 Deep Embedding), embedded nodes may be used within annotation objects, and annotation objects may be used to annotate annotations. However, the grammar prevents embedded nodes from including annotation objects.
While it is beyond the scope of this document to discuss use cases for these scenarios, it is an important notion of regularity of expression, which is shared by formats such as Turtle-star.
Consider the following examples:
More examples can be found in the JSON-LD-star Test Suite.
The JSON-LD Data Model is extended consistent with [RDFStar]:
@id of a node object may be an embedded node.@id of an embedded node may also be another embedded node.Embedded Nodes can be considered as reified triples.
Align with [RDFStar].
The JSON-LD 1.1 is extended as follows:
@id within a node object MUST be an IRI reference,
a compact IRI (including blank node identifiers) or an embedded node.@id are identical to those of a node object.@included, or @graph.@type (or an alias), it MUST have a single value
and the node MUST NOT contain any other non-keyword entries.@type (or an alias),
it MUST have another entry (aside from @id) which describes a relationship,
such as an IRI, @reverse having a single value, or @nest which ultimately
resolves to a single property/value relationship.@annotation property (or an alias) referencing
zero or more annotation objects.@annotation property.@id (or an alias) entry.This specification extends the algorithms from JSON-LD 1.1 Processing Algorithms and API [JSON-LD11-API] to support the addition of embedded nodes and annotation objects.
The following algorithm extensions require that the rdfstar flag be set.
The algorithm has minor updates to allow for an embedded node to be used as the value of @id,
and to allow and validate the special requirements for annotation objects.
Expansion does not change annotations into embedded nodes, neither does it reverse node relationships. This is performed by other algorithms.
Before step 13.4.3.1, and changing 13.4.3.1 to be an "Otherwise, if", add the following steps:
@annotation,
an invalid annotation error has been detected and processing is aborted.null for active property,
value for element, base URL,
and the frameExpansion and ordered flags.
The resulting expanded value MUST BE a valid embedded node, otherwise,
an invalid embedded node error has been detected and processing is aborted.After step 13.4.14 add the following step:
@annotation for active property,
value for element, base URL,
and the frameExpansion and ordered flags,
ensuring that the result is in an array.Step 15.1 extends the set of allowed entries to include @annotation.
Before step 18 add the following step:
@annotation
all associated values MUST BE annotation objects, otherwise,
an invalid annotation error has been detected and processing is aborted.
Additionally, if there is no active property,
or active property is @graph or @included,
the annotation appears in an inappropriate location and
an invalid annotation error has been detected and processing is aborted.
The Compaction Algorithm has minor updates to allow for an embedded node to be used as the value of @id,
and to allow embedded nodes and annotation objects.
Values that might otherwise be serialized as a string must stay
as a map if they contain an annotation object.
Step 7 is updated to exclude elements haveing an @annotation entry.
After step 12.1.1, add the following steps:
null for active property,
expanded value for element,
and the compactArrays and ordered flags.
The flattening algorithms are updated to allow the use of embedded nodes, and to turn annotation objects into embedded nodes.
There is a new Create Annotations Algorithm optionally invoked using the createAnnotations API flag, which will re-create most annotation objects within a node map.
The main changes to the Flattening Algorithm is to move the blank node regeneration to a single recursive step run prior to running the Node Map Generation algorithm. This is required to consistently regenerate blank node identifiers used within embedded nodes, which are otherwise untouched by the algorithm.
Before step 2 add the following step:
Before step 3 add the following step:
Node Map Generation Algorithm has significant updates due to the requirements of unfolding annotation objects into embedded nodes and representing embedded nodes as keys in the node map. Also, some assumptions are made in the original algorithm that the active subject being a map implies a reverse relationship, which is no longer the case when an embedded node may be the active subject.
Principle changes include the following:
@id,
and where a blank node is used as a property.@reverse map.@annotation key is encountered, it creates an
embedded node based on the active subject and
the map containing the @annotation key which is used
in a recursive invokation of this algorithm on the
contents of the annotation object.A new optional parameter reverse is added defaulting to false.
In step 2, when referencing the active subject entry
of graph, if active subject is a map,
index using the canonical lexical form of active subject.
Additionally, do use null if reverse is false.
Before step 4.1.1, ad the following steps:
@annotation entry:
@id taken from active subject.
If active subject is a node reference,
use value of @id from active subject.@annotation value from element.@annotation entry in element adding
an @id entry to each with the value annotation subject.Replace 6.3 and 6.4 with the following steps:
@id whose
value is id.Change the condition for step 6.5 to check the reverse
parameter for true rather than if active subject is a map.
Before step 6.8, ad the following steps:
@annotation entry:
true:
@id with the value id.@id from active subject.@id taken from active subject.
If active subject is a node reference,
use value of @id from active subject.@annotation entry in element adding
an @id entry to each with the value annotation subject.Update step 6.9.3.1.1 to include a reverse
parameter with the value true.
This algorithm use used to comprehensively rename the blank node identifiers used within a map by recursively visiting each element of the map.
This will change the naming of renamed blank nodes used in existing tests. As indicated in the JSON-LD Test Suite:
When comparing documents after flattening, framing or generating RDF, blank node identifiers may not be predictable.
One way to do this is to transform both the generated results and the expected results into an RDF Dataset and perform a blank node bijection (as described for RDF Dataset Isomorphsim) and then use the resulting bijection to rename the blank nodes in the result based on those that are expected.
The algorithm takes a single input variable element and returns a representation of that element with blank node identifiers remapped.
@id and value if a blank node identifier,
add an entry to result for @id with the value from the result of the
Generate Blank Node Identifier algorithm
passing value for identifier.@id
with the value from the result of calling this algorithm recursively
using value for element.Return result.
This algorithm is used to find entries in a node map where the key is a canonicalized embedded node and that embedded node exists in non-embedded form in the node map and move them to be annotation objects under that node. This effectively reverses the process of unfolding annotation objects performed in 8.3.2 Node Map Generation. It is also used in 8.4.3 Serialize RDF as JSON-LD Algorithm.
The algorithm takes a single input variable node map and updates it in place.
OPEN BRACE ({), ordered by decreasing length:
@id entry of annotation.@id
entry from embedded, using the
canonical lexical form
if it is a map.@id, embedded will have exactly one entry.
Initialize property and value
to the key and the first value
from that entry.The RDF transformation algorithms have minimal changes to allow emit and consume RDF-star triples.
The Deserialize JSON-LD to RDF Algorithm has minimal changes to allow an embedded triple to be used as the subject or object of an RDF-star triple, and to use annotation objects, where appropriate.
After step 1.3.1 add the following step:
The Object to RDF algorithm has a minimal update to allow a serialized embedded node to be transformed into an RDF-star triple by invoking the Deserialize JSON-LD to RDF Algorithm recursively.
The first argument MAY be an embedded node in canonical lexical form.
Before Step 4 add the following steps:
OPEN BRACE ({) it MUST represent a serialized embedded node:
@default and
value a new map with a new entry using
the value of @id from entry as key and entry
as value. If the value of @id is not a string,
use the canonical lexical form
as the key.The Serialize RDF as JSON-LD Algorithm algorithm has updates to transform RDF-star triples used as the subject or object of another triple to be used as the index into a node map and represented as embedded nodes.
Change step 5.7.1 to the following steps:
@id entry from the
result of using
the RDF to Object Conversion algorithm
passing subject.@id whose value is
set to embedded subject.@id whose value is
set to subject.Before step 5.7.4, add the following steps:
@id entry from the
result of using
the RDF to Object Conversion algorithm
passing object.@id whose value is
set to embedded object.After step 6.4, add the following steps:
The RDF to Object Conversion algorithm has updates to transform RDF-star triples into an embedded node.
Before step 2, add the following steps:
@id whose value
is the result of calling this algorithm, recursively,
passing the subject from value.rdf:type,
and the useRdfType flag is not true,
add an entry for @type whose value
is an array containing the object from value.Referenced in:
Referenced in: