Copyright © 2020-2021 the Contributors to the JSON-LD-star Specification, published by the JSON for Linking 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 Linking 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.
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 subject (instead of the object) 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.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.