JSON-LD-star

Draft Community Group Report

Latest editor's draft:
https://json-ld.github.io/json-ld-star/
Test suite:
https://json-ld.github.io/json-ld-star/tests/
Implementation report:
https://json-ld.github.io/json-ld-star/reports/
Editors:
Gregg Kellogg
Pierre-Antoine Champin (ERCIM)
Participate:
GitHub json-ld/json-ld-star
File a bug
Commit history
Pull requests

Abstract

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.

Status of This Document

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).

1. Introduction

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.

Example 1: An RDF Triple and its Reification
@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:

Example 2: Annotation on an RDF triple
@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.

2. Conformance

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.

3. JSON-LD-star-specific Terms

This section is non-normative.

The Following terms are used within specific algorithms.

Annotation Object
An annotation object is a node object which is the value of @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.
Embedded Node
An embedded node is a node object describing exactly one property/value pair. The node object MAY be identified as with other node objects (including with an embedded node). The property MUST be either @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.
JSON-LD-star document
A JSON-LD-star document is a serialization of an RDF dataset as extended by [RDFStar].
RDF-star dataset
An RDF dataset extended to allow the use of an RDF-star graph instead of a plain RDF graph.
RDF-star graph
A set of RDF-star triples.
RDF-star triple
An RDF triple extended to allow an RDF-star triple to be used in the subject or object position.

4. Basic Concepts

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.

5. Advanced Concepts

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.

5.1 Reverse Properties

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:

5.2 Deep Embedding

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.

5.3 Mixing Annotations and 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.

6. Data Model

The JSON-LD Data Model is extended consistent with [RDFStar]:

Embedded Nodes can be considered as reified triples.

Editor's note

Align with [RDFStar].

7. Grammar Extensions

The JSON-LD 1.1 is extended as follows:

8. Algorithmic Extensions

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.

8.1 Expansion Algorithm

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.

Note

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:

  1. If the rdfstar flag is not set, and active property is @annotation, an invalid annotation error has been detected and processing is aborted.
  2. If value is a non-empty map and the rdfstar flag is set, set expanded value to the result of using this algorithm recursively passing active context, 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:

  1. If expanded property is `@annotation:
    1. Continue with the next key from element if the rdfstar flag is not set.
    2. Set expanded value to the result of using this algorithm recursively passing active context, @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:

  1. If result contains the entry @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.

8.2 Compaction Algorithm

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:

  1. Otherwise, if expanded value is an embedded node, initialize compacted value with the result of calling this algorithm, recursively, passing active context, null for active property, expanded value for element, and the compactArrays and ordered flags.

8.3 Flattening Algorithms

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.

8.3.1 Flattening Algorithm

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:

  1. Update element using the Rename Blank Nodes algorithm passing element.

Before step 3 add the following step:

  1. If the createAnnotations flag is set:
    1. For each key-value pair graph name-graph in node map, perform the following steps:
      1. Update graph in node map by invoking the Create Annotations Algorithm passing graph for node map.

8.3.2 Node Map Generation

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:

  • As indicated in § 8.3.1 Flattening Algorithm, most blank node regeneration is performed prior to invoking this algorithm, rather than inline. The exception is for node objects without an explicit @id, and where a blank node is used as a property.
  • A new argument reverse is introduced which is passed when processing an @reverse map.
  • If an @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.
  • If the active subject is an embedded node, the result of the JSON Canonicalization Scheme (JCS) [RFC8785] is used as an index into the node map.

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:

  1. If element has an @annotation entry:
    1. Initialize annotation subject as a new map with an entry for @id taken from active subject. If active subject is a node reference, use value of @id from active subject.
    2. Add an entry for active property with the value an array containing element, after removing the @annotation value from element.
    3. Initialize annotation as an array containing the values from the @annotation entry in element adding an @id entry to each with the value annotation subject.
    4. Recursively call this algorithm passing annotation for element, node map, and active graph.

Replace 6.3 and 6.4 with the following steps:

  1. If id is a map, set serialized id to the canonical lexical form of id, otherwise to id.
  2. If graph does not contain an entry serialized id, create one and initialize its value to a map consisting of a single entry @id whose value is id.
  3. Reference the value of the serialized id entry of graph using the variable node.

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:

  1. If element has an @annotation entry:
    1. Initialize annotation subject as a new map.
    2. If reverse is true:
      1. Add an entry for @id with the value id.
      2. Add an entry for active property with the value from active subject. If active subject is a node reference, use value of @id from active subject.
    3. Otherwise:
      1. Add an entry for @id taken from active subject. If active subject is a node reference, use value of @id from active subject.
      2. Add an entry for active property with the value id.
    4. Initialize annotation as an array containing the values from the @annotation entry in element adding an @id entry to each with the value annotation subject.
    5. Recursively call this algorithm passing annotation for element, node map, and active graph.

Update step 6.9.3.1.1 to include a reverse parameter with the value true.

8.3.3 Rename Blank Nodes

This algorithm use used to comprehensively rename the blank node identifiers used within a map by recursively visiting each element of the map.

Note

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.

  1. If element is an array:
    1. Initialize an empty array result.
    2. For each item in element add the result of invoking this algorithm recursively passing item for element.
  2. Otherwise, if element is a map:
    1. Initialize an empty map result.
    2. For each key-value pair in element:
      1. If key is @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.
      2. Otherwise, add an entry to result for @id with the value from the result of calling this algorithm recursively using value for element.
  3. Otherwise, set result to element

Return result.

8.3.4 Create Annotations

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.

  1. For each entry key/annotation in node map, where the first character of key is an OPEN BRACE ({), ordered by decreasing length:
    1. Initialize embedded from the value for the @id entry of annotation.
    2. Initialize id with the value of the @id entry from embedded, using the canonical lexical form if it is a map.
    3. Initialize node to the entry for id in node map. If there is no such entry, continue to the next entry in node map.
    4. Besides @id, embedded will have exactly one entry. Initialize property and value to the key and the first value from that entry.
    5. If node has an entry for property with a value value:
      1. Remove the key entry from node map.
      2. Remove the @id entry from annotation.
      3. Use add value to add annotation to the property property in node, using true for as array.
  2. Return node map.

8.4 RDF Serialization/Deserialization Algorithms

The RDF transformation algorithms have minimal changes to allow emit and consume RDF-star triples.

8.4.1 Deserialize JSON-LD to RDF Algorithm

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:

  1. If subject is a string with the form of an embedded node. Transform it into an RDF-star triple using the Object to RDF Algorithm passing subject as item.

8.4.2 Object to RDF Algorithm

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:

  1. If item is a string where the first character is an OPEN BRACE ({) it MUST represent a serialized embedded node:
    1. Initialize dataset as a new empty RDF dataset.
    2. Transform item into a map by deserializing item as JSON.
    3. Invoke the Object to RDF Algorithm passing a new map with the entry @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.
    4. The only entry in dataset will be a single RDF-star triple in the defaultGraph. Return that RDF-star triple.

8.4.3 Serialize RDF as JSON-LD Algorithm

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:

  1. If subject is an RDF-star triple:
    1. Set embedded subject to the value of the @id entry from the result of using the RDF to Object Conversion algorithm passing subject.
    2. Set subject index to the result of using the canonical lexical form of embedded subject.
    3. If node map does not have a subject index entry, create one and initialize its value to a new map consisting of a single entry @id whose value is set to embedded subject.
  2. Otherwise, if node map does not have a subject entry, create one and initialize its value to a new map consisting of a single entry @id whose value is set to subject.

Before step 5.7.4, add the following steps:

  1. If object is an RDF-star triple:
    1. Set embedded object to the value of the @id entry from the result of using the RDF to Object Conversion algorithm passing object.
    2. Set object index to the result of using the canonical lexical form of embedded object.
    3. If node map does not have an object index entry, create one and initialize its value to a new map consisting of a single entry @id whose value is set to embedded object.

After step 6.4, add the following steps:

  1. Update graph object in graph map by invoking the Create Annotations Algorithm passing graph object for node map.

8.4.4 RDF to Object Conversion

The RDF to Object Conversion algorithm has updates to transform RDF-star triples into an embedded node.

Before step 2, add the following steps:

  1. Otherewise, if value is an RDF-star triple:
    1. Create a new map embedded node with the entry @id whose value is the result of calling this algorithm, recursively, passing the subject from value.
    2. If the predicate from value is rdf:type, and the useRdfType flag is not true, add an entry for @type whose value is an array containing the object from value.
    3. Otherwise, add an entry for predicate whose value is an array containing the result of calling this algorithm, recursively, passing the object from value.
  2. Return embedded node.

A. References

A.1 Normative references

[INFRA]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[JSON-LD11]
JSON-LD 1.1. Gregg Kellogg; Pierre-Antoine Champin; Dave Longley. W3C. 16 July 2020. W3C Recommendation. URL: https://www.w3.org/TR/json-ld11/
[JSON-LD11-API]
JSON-LD 1.1 Processing Algorithms and API. Gregg Kellogg; Dave Longley; Pierre-Antoine Champin. W3C. 16 July 2020. W3C Recommendation. URL: https://www.w3.org/TR/json-ld11-api/
[rdf-primer]
RDF Primer. Frank Manola; Eric Miller. W3C. 10 February 2004. W3C Recommendation. URL: https://www.w3.org/TR/rdf-primer/
[RDF11-CONCEPTS]
RDF 1.1 Concepts and Abstract Syntax. Richard Cyganiak; David Wood; Markus Lanthaler. W3C. 25 February 2014. W3C Recommendation. URL: https://www.w3.org/TR/rdf11-concepts/
[RDFStar]
RDF-star and SPARQL-star. Olaf Hartig; Pierre-Antoine Champin. W3C. 2021-02-18. W3C CG Draft. URL: https://w3c.github.io/rdf-star/cg-spec/2021-02-18.html
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC3987]
Internationalized Resource Identifiers (IRIs). M. Duerst; M. Suignard. IETF. January 2005. Proposed Standard. URL: https://tools.ietf.org/html/rfc3987
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://tools.ietf.org/html/rfc8174
[RFC8785]
JSON Canonicalization Scheme (JCS). A. Rundgren; B. Jordan; S. Erdtman. IETF. June 2020. Informational. URL: https://tools.ietf.org/html/rfc8785

A.2 Informative references

[BCP47]
Tags for Identifying Languages. A. Phillips; M. Davis. IETF. September 2009. IETF Best Current Practice. URL: https://tools.ietf.org/html/bcp47
[ECMASCRIPT]
ECMAScript Language Specification. Ecma International. URL: https://tc39.es/ecma262/
[JSON-LD]
JSON-LD 1.0. Manu Sporny; Gregg Kellogg; Markus Lanthaler. W3C. 3 November 2020. W3C Recommendation. URL: https://www.w3.org/TR/json-ld/
[JSON-LD-star-tests]
JSON-LD-star Test Suite. W3C. unofficial. URL: https://json-ld.github.io/json-ld-star/tests/
[JSON-LD11-FRAMING]
JSON-LD 1.1 Framing. Dave Longley; Gregg Kellogg; Pierre-Antoine Champin. W3C. 16 July 2020. W3C Recommendation. URL: https://www.w3.org/TR/json-ld11-framing/
[LINKED-DATA]
Linked Data Design Issues. Tim Berners-Lee. W3C. 27 July 2006. W3C-Internal Document. URL: https://www.w3.org/DesignIssues/LinkedData.html
[RDF-SCHEMA]
RDF Schema 1.1. Dan Brickley; Ramanathan Guha. W3C. 25 February 2014. W3C Recommendation. URL: https://www.w3.org/TR/rdf-schema/
[RFC8259]
The JavaScript Object Notation (JSON) Data Interchange Format. T. Bray, Ed.. IETF. December 2017. Internet Standard. URL: https://tools.ietf.org/html/rfc8259
[WEBIDL]
Web IDL. Boris Zbarsky. W3C. 15 December 2016. W3C Editor's Draft. URL: https://heycam.github.io/webidl/