JSON-LD-star

Draft Community Group Report

Latest published version:
https://json-ld.github.io/json-ld-star/publications/2021-02-18.html
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/
Previous version:
https://json-ld.github.io/json-ld-star/publications/2021-02-18.html
Editors:
Gregg Kellogg
Pierre-Antoine Champin (ERCIM)
Feedback:
GitHub json-ld/json-ld-star (pull requests, new issue, open issues)
public-linked-json@w3.org with subject line [json-ld-star] … message topic … (archives)

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 is a preview

Do not attempt to implement this version of the specification. Do not reference this version as authoritative in any way. Instead, see https://json-ld.github.io/json-ld-star/ for the Editor's draft.

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

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.

Terms imported from Other Specifications

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]

array
In the JSON serialization, an array structure is represented as square brackets surrounding zero or more values. Values are separated by commas. In the internal representation, a list (also called an array) is an ordered collection of zero or more values. While JSON-LD uses the same array representation as JSON, the collection is unordered by default. While order is preserved in regular JSON arrays, it is not in regular JSON-LD arrays unless specifically defined (see the Sets and Lists section of JSON-LD 1.1.
boolean
The values true and false that are used to express one of two possible states.
JSON object
In the JSON serialization, an object structure is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members). A name is a string. A single colon comes after each name, separating the name from the value. A single comma separates a value from a following name. In JSON-LD the names in an object must be unique.

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.

null
The use of the null value within JSON-LD is used to ignore or reset values. A map entry in the @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.
number
In the JSON serialization, a number is similar to that used in most programming languages, except that the octal and hexadecimal formats are not used and that leading zeros are not allowed. In the internal representation, a number is equivalent to either a long or double, depending on if the number has a non-zero fractional part (see [WEBIDL]).
scalar
A scalar is either a string, number, true, or false.
string
A string is a sequence of zero or more Unicode (UTF-8) characters, wrapped in double quotes, using backslash escapes (if necessary). A character is represented as a single character string.
Unicode code point order
This refers to determining the order of two Unicode strings (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]

IRI
The absolute form of an IRI containing a scheme along with a path and optional query and fragment segments.
IRI reference
Denotes the common usage of an Internationalized Resource Identifier. An IRI reference may be absolute or relative. However, the "IRI" that results from such a reference only includes absolute IRIs; any relative IRI references are resolved to their absolute form.
relative IRI reference
A relative IRI reference is an IRI reference that is relative to some other IRI, typically the base IRI of the document. Note that properties, values of @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]

base IRI
The base IRI is an IRI established in the context, or is based on the JSON-LD document location. The base IRI is used to turn relative IRI references into IRIs.
blank node
A node in a graph that is neither an IRI, nor a literal. A blank node does not contain a de-referenceable identifier because it is either ephemeral in nature or does not contain information that needs to be linked to from outside of the linked data graph. In JSON-LD, a blank node is assigned an identifier starting with the prefix _:.
blank node identifier
A blank node identifier is a string that can be used as an identifier for a blank node within the scope of a JSON-LD document. Blank node identifiers begin with _:.
dataset
A dataset representing a collection of RDF graphs including exactly one default graph and zero or more named graphs.
datatype IRI
A datatype IRI is an IRI identifying a datatype that determines how the lexical form maps to a literal value.
default graph
The default graph of a dataset is an RDF graph having no name, which may be empty.
graph name
The IRI or blank node identifying a named graph.
language-tagged string
A language-tagged string consists of a string and a non-empty language tag as defined by [BCP47]. The language tag must be well-formed according to section 2.2.9 Classes of Conformance of [BCP47]. Processors may normalize language tags to lowercase.
Linked Data
A set of documents, each containing a representation of a linked data graph or dataset.
list
A list is an ordered sequence of IRIs, blank nodes, and literals.
literal
An object expressed as a value such as a string or number. Implicitly or explicitly includes a datatype IRI and, if the datatype is rdf:langString, an optional language tag.
named graph
A named graph is a linked data graph that is identified by an IRI or blank node.
node
A node in an RDF graph, either the subject and object of at least one triple. Note that a node can play both roles (subject and object) in a graph, even in the same triple.
object
An object is a node in a linked data graph with at least one incoming edge.
property
The name of a directed-arc in a linked data graph. Every property is directional and is labeled with an IRI or a blank node identifier. Whenever possible, a property should be labeled with an IRI.
Note
The use of blank node identifiers to label properties is obsolete, and may be removed in a future version of JSON-LD.
Also, see predicate in [RDF11-CONCEPTS].
RDF graph
A labeled directed graph, i.e., a set of nodes connected by directed-arcs. Also called linked data graph.
resource
A resource denoted by an IRI, a blank node or literal representing something in the world (the "universe of discourse").
subject
A subject is a node in a linked data graph with at least one outgoing edge, related to an object node through a property.
triple
A component of an RDF graph including a subject, predicate, and object, which represents a node-arc-node segment of an RDF graph.

JSON-LD Specific Term Definitions

active context
A context that is used to resolve terms while the processing algorithm is running.
base direction
The base direction is the direction used when a string does not have a direction associated with it directly. It can be set in the context using the @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.
compact IRI
A compact IRI has the form of prefix:suffix and is used as a way of expressing an IRI without needing to define separate term definitions for each IRI contained within a common vocabulary identified by prefix.
context
A set of rules for interpreting a JSON-LD document as described in the The Context section of JSON-LD 1.1, and normatively specified in the Context Definitions section of JSON-LD 1.1.
default language
The default language is the language used when a string does not have a language associated with it directly. It can be set in the context using the @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 object
A default object is a map that has a @default key.
embedded context
An embedded context is a context which appears as the @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.
expanded term definition
An expanded term definition is a term definition where the value is a map containing one or more keyword keys to define the associated IRI, if this is a reverse property, the type associated with string values, and a container mapping. See the Expanded Term Definition section of JSON-LD 1.1 for a normative description.
frame
A JSON-LD document, which describes the form for transforming another JSON-LD document using matching and embedding rules. A frame document allows additional keywords and certain map entries to describe the matching and transforming process.
frame object
A frame object is a map element within a frame which represents a specific portion of the frame matching either a node object or a value object in the input. See the Frame Objects section of JSON-LD 1.1 for a normative description.
graph object
A graph object represents a named graph as the value of a map entry within a node object. When expanded, a graph object must have an @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.
id map
An id map is a map value of a term defined with @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.
implicitly named graph
A named graph created from the value of a map entry having an expanded term definition where @container is set to @graph.
included block
An included block is an entry in a node object where the key is either @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.
index map
An index map is a map value of a term defined with @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.
JSON literal
A JSON literal is a literal where the associated datatype IRI is 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.
JSON-LD document
A JSON-LD document is a serialization of an RDF dataset. See the JSON-LD Grammar section in JSON-LD 1.1 for a formal description.
JSON-LD internal representation
The JSON-LD internal representation is the result of transforming a JSON syntactic structure into the core data structures suitable for direct processing: arrays, maps, strings, numbers, booleans, and null.
JSON-LD Processor
A JSON-LD Processor is a system which can perform the algorithms defined in JSON-LD 1.1 Processing Algorithms and API. See the Conformance section in JSON-LD 1.1 API for a formal description.
JSON-LD value
A JSON-LD value is a string, a number, true or false, a typed value, or a language-tagged string. It represents an RDF literal.
keyword
A string that is specific to JSON-LD, described in the Syntax Tokens and Keywords section of JSON-LD 1.1, and normatively specified in the Keywords section of JSON-LD 1.1,
language map
A language map is a map value of a term defined with @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 object
A list object is a map that has a @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.
local context
A context that is specified with a map, specified via the @context keyword.
nested property
A nested property is a key in a node object whose value is a map containing entries which are treated as if they were values of the node object. The nested property itself is semantically meaningless and used only to create a sub-structure within a node object. See the Property Nesting section of JSON-LD 1.1 for a normative description.
node object
A node object represents zero or more properties of a node in the graph serialized by the JSON-LD document. A map is a node object if it exists outside of the JSON-LD context and:
  • it does not contain the @value, @list, or @set keywords, or
  • it is not the top-most map in the JSON-LD document consisting of no other entries than @graph and @context.
The entries of a node object whose keys are not keywords are also called properties of the node object. See the Node Objects section of JSON-LD 1.1 for a normative description.
node reference
A node object used to reference a node having only the @id key.
prefix
A prefix is the first component of a compact IRI which comes from a term that maps to a string that, when prepended to the suffix of the compact IRI, results in an IRI.
processing mode
The processing mode defines how a JSON-LD document is processed. By default, all documents are assumed to be conformant with this specification. By defining a different version using the @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.
scoped context
A scoped context is part of an expanded term definition using the @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 object
A set object is a map that has an @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.
term
A term is a short word defined in a context that may be expanded to an IRI. See the Terms section of JSON-LD 1.1 for a normative description.
term definition
A term definition is an entry in a context, where the key defines a term which may be used within a map as a key, type, or elsewhere that a string is interpreted as a vocabulary item. Its value is either a string (simple term definition), expanding to an IRI, or a map (expanded term definition).
For context processing, term definition values are converted internally to a dedicated data structure that is easier to process.
type map
A type map is a map value of a term defined with @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.
typed value
A typed value consists of a value, which is a string, and a type, which is an IRI.
value object
A value object is a map that has an @value entry. See the Value Objects section of JSON-LD 1.1 for a normative description.
vocabulary mapping
The vocabulary mapping is set in the context using the @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.
active graph
The name of the currently active graph that the processor should use when processing.
active object
The currently active object that the processor should use when processing.
active property
The currently active property or keyword that the processor should use when processing. The active property is represented in the original lexical form, which is used for finding coercion mappings in the active context.
active subject
The currently active subject that the processor should use when processing.
add value
Used as a macro within various algorithms as a way to add a value to an entry in a map (object) using a specified key. The invocation may include an as array flag defaulting to false.
  1. If as array is true and the value of key in object does not exist or is not an array, set it to a new array containing any original value.
  2. If value is an array, then for each element v in value, use add value recursively to add v to key in entry.
  3. Otherwise:
    1. If key is not an entry in object, add value as the value of key in object.
    2. Otherwise
      1. If the value of the key entry in object is not an array, set it to a new array containing the original value.
      2. Append value to the value of the key entry in object.
explicit inclusion flag
A flag specifying that for properties to be included in the output, they must be explicitly declared in the matching frame.
framing state
A map containing values for the object embed flag, the require all flag, the embedded flag, used internally to help determine if object embedding is appropriate, the explicit inclusion flag, and the omit default flag.
input frame
The initial Frame provided to the framing algorithm.
IRI compacting
Used as a macro within various algorithms as to reduce the language used to describe the process of compacting a string var representing an IRI or keyword using an active context either specified directly, or coming from the scope of the algorithm step using this term. An optional value is used, if explicitly provided. Unless specified, the vocab flag defaults to true, and the reverse flag defaults to false.
  1. Return the result of using the IRI Compaction algorithm, passing active context, var, value (if supplied), vocab, and result.
IRI expanding
Used as a macro within various algorithms as to reduce the language used to describe the process of expanding a string value representing an IRI or keyword using an active context either specified directly, or coming from the scope of the algorithm step using this term. Optional defined and local context arguments are used, if explicitly provided. Unless specified, the document relative flag defaults to false, and the vocab flag defaults to true.
  1. Return the result of using the IRI Expansion algorithm, passing active context, value, local context (if supplied), defined (if supplied), document relative, and vocab.
JSON-LD input
The JSON-LD data structure that is provided as input to the algorithm.
JSON-LD output
The JSON-LD data structure that is produced as output by the algorithm.
map of flattened subjects
A map of subjects that is the result of the Node Map Generation algorithm.
object embed flag
A flag specifying that node objects should be directly embedded in the output, instead of being referred to by their IRI.
omit default flag
A flag specifying that properties that are missing from the JSON-LD input, but present in the input frame, should be omitted from the output.
omit graph flag
A flag that determines if framing output is always contained within a @graph entry, or only if required to represent multiple node objects.
processor state
The processor state, which includes the active context, active subject, and active property. The processor state is managed as a stack with elements from the previous processor state copied into a new processor state when entering a new JSON object.
require all flag
A flag specifying that all properties present in the input frame must either have a default value or be present in the JSON-LD input for the frame to match.

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 object (instead of the subject) 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, 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:

  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://www.rfc-editor.org/rfc/rfc2119
[RFC3987]
Internationalized Resource Identifiers (IRIs). M. Duerst; M. Suignard. IETF. January 2005. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc3987
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[RFC8785]
JSON Canonicalization Scheme (JCS). A. Rundgren; B. Jordan; S. Erdtman. IETF. June 2020. Informational. URL: https://www.rfc-editor.org/rfc/rfc8785

A.2 Informative references

[BCP47]
Tags for Identifying Languages. A. Phillips, Ed.; M. Davis, Ed. IETF. September 2009. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc5646
[ECMASCRIPT]
ECMAScript Language Specification. Ecma International. URL: https://tc39.es/ecma262/multipage/
[JSON-LD-star-tests]
JSON-LD-star Test Suite. W3C. unofficial. URL: https://json-ld.github.io/json-ld-star/tests/
[JSON-LD10]
Reference not found.
[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://www.rfc-editor.org/rfc/rfc8259
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/
[XPATH-FUNCTIONS]
XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition). Ashok Malhotra; Jim Melton; Norman Walsh; Michael Kay. W3C. 14 December 2010. W3C Recommendation. URL: https://www.w3.org/TR/xpath-functions/