CARVIEW |
JSON-LD 1.1 Processing Algorithms and API
W3C Recommendation
- This version:
- https://www.w3.org/TR/2020/REC-json-ld11-api-20200716/
- Latest published version:
- https://www.w3.org/TR/json-ld11-api/
- Latest editor's draft:
- https://w3c.github.io/json-ld-api/
- Test suite:
- https://w3c.github.io/json-ld-api/tests/
- Implementation report:
- https://w3c.github.io/json-ld-api/reports/
- Previous version:
- https://www.w3.org/TR/2020/PR-json-ld11-api-20200507/
- Previous Recommendation:
- https://www.w3.org/TR/2014/REC-json-ld-api-20140116/
- Editors:
- Gregg Kellogg (v1.0 and v1.1)
- Dave Longley (Digital Bazaar) (v1.1)
- Pierre-Antoine Champin (LIRIS - Université de Lyon) (v1.1)
- Former editors:
- Markus Lanthaler (Google) (v1.0)
- Manu Sporny (Digital Bazaar) (v1.0)
- Authors:
- Dave Longley (Digital Bazaar) (v1.0 and v1.1)
- Gregg Kellogg (v1.0 and v1.1)
- Markus Lanthaler (Google) (v1.0)
- Manu Sporny (Digital Bazaar) (v1.0)
- Niklas Lindström (v1.0)
- Participate:
- GitHub w3c/json-ld-api
- File a bug
- Commit history
- Pull requests
Please check the errata for any errors or issues reported since publication.
See also translations.
This document is also available in this non-normative format: EPUB
Copyright © 2010-2020 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
Abstract
This specification defines a set of algorithms for programmatic transformations of JSON-LD documents. Restructuring data according to the defined transformations often dramatically simplifies its usage. Furthermore, this document proposes an Application Programming Interface (API) for developers implementing the specified algorithms.
This specification describes a superset of the features defined in JSON-LD 1.0 Processing Algorithms And API [JSON-LD10-API] and, except where noted, the algorithms described in this specification are fully compatible with documents created using JSON-LD 1.0 [JSON-LD10].
Status of This Document
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.
This document has been developed by the JSON-LD Working Group and was derived from the JSON-LD Community Group's Final Report.
There is a live JSON-LD playground that is capable of demonstrating the features described in this document.
This specification is intended to supersede the JSON-LD 1.0 Processing Algorithms And API [JSON-LD10-API] specification.
This document was published by the JSON-LD Working Group as a Recommendation.
GitHub Issues are preferred for discussion of this specification. Alternatively, you can send comments to our mailing list. Please send them to public-json-ld-wg@w3.org (archives).
Please see the Working Group's implementation report.
This document has been reviewed by W3C Members, by software developers, and by other W3C groups and interested parties, and is endorsed by the Director as a W3C Recommendation. It is a stable document and may be used as reference material or cited from another document. W3C's role in making the Recommendation is to draw attention to the specification and to promote its widespread deployment. This enhances the functionality and interoperability of the Web.
This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 1 March 2019 W3C Process Document.
Set of Documents
This document is one of three JSON-LD 1.1 Recommendations produced by the JSON-LD Working Group:
1. Introduction
This section is non-normative.
This document is a detailed specification of the JSON-LD processing algorithms. The document is primarily intended for the following audiences:
- Software developers who want to implement the algorithms to transform JSON-LD documents.
- Web authors and developers who want a very detailed view of how a JSON-LD Processor operates.
- Developers who want an overview of the proposed JSON-LD API.
To understand the basics in this specification you must first be familiar with JSON, which is detailed in [RFC8259]. You must also understand the JSON-LD syntax defined in the JSON-LD 1.1 Syntax specification [JSON-LD11], which is the base syntax used by all of the algorithms in this document. To understand the API and how it is intended to operate in a programming environment, it is useful to have working knowledge of the JavaScript programming language [ECMASCRIPT] and WebIDL [WEBIDL]. To understand how JSON-LD maps to RDF, it is helpful to be familiar with the basic RDF concepts [RDF11-CONCEPTS].
1.1 How to Read this Document
This section is non-normative.
This document is a detailed specification for a serialization of Linked Data in JSON. The document is primarily intended for the following audiences:
- Software developers who want to implement processors and APIs for JSON-LD
A companion document, the JSON-LD 1.1 specification [JSON-LD11], specifies the grammar of JSON-LD documents.
To understand the basics in this specification you must first be familiar with JSON, which is detailed in [RFC8259].
This document can highlight changes since the JSON-LD 1.0 version. Select to changes.
1.2 Contributing
This section is non-normative.
There are a number of ways that one may participate in the development of this specification:
- Technical discussion typically occurs on the public mailing list: public-json-ld-wg@w3.org
- The working group uses #json-ld IRC channel is available for real-time discussion on irc.w3.org.
- The #json-ld IRC channel is also available for real-time discussion on irc.freenode.net.
1.3 Typographical conventions
This section is non-normative.
The following typographic conventions are used in this specification:
markup
- Markup (elements, attributes, properties), machine processable values (string, characters, media types), property name, or a file name is in red-orange monospace font.
- variable
- A variable in pseudo-code or in an algorithm description is in italics.
- definition
- A definition of a term, to be used elsewhere in this or other specifications, is in bold and italics.
- definition reference
- A reference to a definition in this document is underlined and is also an active link to the definition itself.
markup definition reference
- A references to a definition in this document, when the reference itself is also a markup, is underlined, red-orange monospace font, and is also an active link to the definition itself.
- external definition reference
- A reference to a definition in another document is underlined, in italics, and is also an active link to the definition itself.
markup external definition reference
- A reference to a definition in another document, when the reference itself is also a markup, is underlined, in italics red-orange monospace font, and is also an active link to the definition itself.
- hyperlink
- A hyperlink is underlined and in blue.
- [reference]
- A document reference (normative or informative) is enclosed in square brackets and links to the references section.
- Changes from Recommendation
- Sections or phrases changed from the previous Recommendation may be highlighted using a control in § 1.1 How to Read this Document.
Notes are in light green boxes with a green left border and with a "Note" header in green. Notes are always informative.
Examples are in light khaki boxes, with khaki left border, and with a numbered "Example" header in khaki. Examples are always informative. The content of the example is in monospace font and may be syntax colored. Examples may have tabbed navigation buttons to show the results of transforming an example into other representations.
1.4 Terminology
This document uses the following terms as defined in external specifications and defines terms specific to JSON-LD.
Terms imported from Other Specifications
Terms imported from ECMAScript Language Specification [ECMASCRIPT], The JavaScript Object Notation (JSON) Data Interchange Format [RFC8259], Infra Standard [INFRA], and Web IDL [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
andfalse
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, isnull
, explicitly decouples a term's association with an IRI. A map entry in the body of a JSON-LD document whose value isnull
has the same meaning as if the map entry was not defined. If@value
,@list
, or@set
is set tonull
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
, orfalse
. - 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.
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.
Also, see predicate in [RDF11-CONCEPTS].NoteThe use of blank node identifiers to label properties is obsolete, and may be removed in a future version of JSON-LD.
- 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"
, ornull
. 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 ornull
. 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. - 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.
- 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 it 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. - 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 Therdf: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
orfalse
, 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
-
An 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. - 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
.
- it does not contain the
- 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 tojson-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 to1.1
. This specification extends JSON-LD 1.0 via thejson-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).
- 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, ornull
. See the Context Definitions section of JSON-LD 1.1 for a normative description.
1.4.1 Algorithm Terms
The Following terms are used within specific algorithms.
- active graph
- The name of the currently active graph 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.
- 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
. - 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 tofalse
.- 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 totrue
.- 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.
1.4.2 Syntax Tokens and Keywords
In addition to the keywords defined in the JSON-LD 1.1 Syntax specification [JSON-LD11], this specification adds an additional keyword to support JSON-LD 1.1 Framing [JSON-LD11-FRAMING]:
@preserve
- Used in an expanded document created as the result of the Framing algorithm to represent values that might otherwise be removed as part of the Expansion algorithm.
1.5 Example Conventions
This section is non-normative.
Note that in the examples used in this document, output is of necessity shown in serialized form as JSON. While the algorithms describe operations on the JSON-LD internal representation, when they as displayed as examples, the JSON serialization is used. In particular, the internal representation use of maps are represented using JSON objects.
{ "@context": { "name": "https://xmlns.com/foaf/0.1/name", "knows": "https://xmlns.com/foaf/0.1/knows" }, "@id": "https://me.markus-lanthaler.com/", "name": "Markus Lanthaler", "knows": [ { "name": "Dave Longley" } ] }
In the internal representation, the example above would be of a
map containing @context
, @id
, name
, and knows
entries,
with either maps, strings, or arrays of
maps or strings values. In the JSON serialization, JSON objects are used
for maps, while arrays and strings are serialized using a
convention common to many programming languages.
2. Features
This section is non-normative.
The JSON-LD 1.1 Syntax specification [JSON-LD11] defines a syntax to express Linked Data in JSON. Because there is more than one way to express Linked Data using this syntax, it is often useful to be able to transform JSON-LD documents so that they may be more easily consumed by specific applications.
To allow these algorithms to be adapted for syntaxes other than JSON, the algorithms operate on the JSON-LD internal representation, which uses the generic concepts of arrays, maps, strings, numbers, booleans, and null to describe the data represented by a JSON document. Algorithms act on this internal representation with API entry points responsible for transforming between the concrete and internal representations.
JSON-LD uses contexts to allow Linked Data to be expressed in a way that is specifically tailored to a particular person or application. By providing a context, JSON data can be expressed in a way that is a natural fit for a particular person or application whilst also indicating how the data should be understood at a global scale. In order for people or applications to share data that was created using a context that is different from their own, a JSON-LD processor must be able to transform a document from one context to another. Instead of requiring JSON-LD processors to write specific code for every imaginable context switching scenario, it is much easier to specify a single algorithm that can remove any context. Similarly, another algorithm can be specified to subsequently apply any context. These two algorithms represent the most basic transformations of JSON-LD documents. They are referred to as expansion and compaction, respectively.
JSON-LD 1.1 introduces new features that are
compatible with JSON-LD 1.0 [JSON-LD10],
but if processed by a JSON-LD 1.0 processor may produce different results.
Processors default to json-ld-1.1
, unless the
processingMode
API option
is explicitly set to json-ld-1.0
.
Publishers are encouraged to use the @version
map entry within a context
set to 1.1
to ensure that JSON-LD 1.0 processors will not misinterpret JSON-LD 1.1 features.
There are four major types of transformation that are discussed in this document: expansion, compaction, flattening, and RDF serialization/deserialization.
2.1 Expansion
This section is non-normative.
The algorithm that removes context is called expansion. Before performing any other transformations on a JSON-LD document, it is easiest to remove any context from it and to make data structures more regular.
To get an idea of how context and data structuring affects the same data, here is an example of JSON-LD that uses only terms and is fairly compact:
The next input example uses one IRI to express a property and a map to encapsulate a value, but leaves the rest of the information untouched.
Note that both inputs are valid JSON-LD and both represent the same information. The difference is in their context information and in the data structures used. A JSON-LD processor can remove context and ensure that the data is more regular by employing expansion.
Expansion has two important goals: removing any contextual
information from the document, and ensuring all values are represented
in a regular form. These goals are accomplished by expanding all entry keys
to IRIs and by expressing all
values in arrays in
expanded form. Expanded form is the most verbose
and regular way of expressing of values in JSON-LD; all contextual
information from the document is instead stored locally with each value.
Running the Expansion algorithm
(expand()
)
operation) against the above examples results in the following output:
[ { "@id": "https://me.markus-lanthaler.com/", "https://xmlns.com/foaf/0.1/name": [ { "@value": "Markus Lanthaler" } ], "https://xmlns.com/foaf/0.1/homepage": [ { "@id": "https://www.markus-lanthaler.com/" } ] } ]
The example above is the JSON-LD serialization of the output of the expansion algorithm, where the algorithm's use of maps are replaced with JSON objects.
Note that in the output above all context definitions have been removed, all terms and compact IRIs have been expanded to absolute IRIs, and all JSON-LD values are expressed in arrays in expanded form. While the output is more verbose and difficult for a human to read, it establishes a baseline that makes JSON-LD processing easier because of its very regular structure.
2.2 Compaction
This section is non-normative.
While expansion removes context from a given input, compaction's primary function is to perform the opposite operation: to express a given input according to a particular context. Compaction applies a context that specifically tailors the way information is expressed for a particular person or application. This simplifies applications that consume JSON or JSON-LD by expressing the data in application-specific terms, and it makes the data easier to read by humans.
Compaction uses a developer-supplied context to shorten IRIs to terms or compact IRIs and JSON-LD values expressed in expanded form to simple values such as strings or numbers.
For example, assume the following expanded JSON-LD input document:
[ { "@id": "https://me.markus-lanthaler.com/", "https://xmlns.com/foaf/0.1/name": [ { "@value": "Markus Lanthaler" } ], "https://xmlns.com/foaf/0.1/homepage": [ { "@id": "https://www.markus-lanthaler.com/" } ] } ]
Additionally, assume the following developer-supplied JSON-LD context:
{ "@context": { "name": "https://xmlns.com/foaf/0.1/name", "homepage": { "@id": "https://xmlns.com/foaf/0.1/homepage", "@type": "@id" } } }
Running the Compaction Algorithm
(compact()
)
operation) given the context supplied above against the JSON-LD input
document provided above would result in the following output:
The example above is the JSON-LD serialization of the output of the compaction algorithm, where the algorithm's use of maps are replaced with JSON objects.
Note that all IRIs have been compacted to
terms as specified in the context,
which has been injected into the output. While compacted output is
useful to humans, it is also used to generate structures that are easy to
program against. Compaction enables developers to map any expanded document
into an application-specific compacted document. While the context provided
above mapped https://xmlns.com/foaf/0.1/name
to name
, it
could also have been mapped to any other term provided by the developer.
2.3 Flattening
This section is non-normative.
While expansion ensures that a document is in a uniform structure, flattening goes a step further to ensure that the shape of the data is deterministic. In expanded documents, the properties of a single node may be spread across a number of different node objects. By flattening a document, all properties of a node are collected in a single node object and all blank nodes are labeled with a blank node identifier. This may drastically simplify the code required to process JSON-LD data in certain applications.
For example, assume the following JSON-LD input document:
{ "@context": { "name": "https://xmlns.com/foaf/0.1/name", "knows": "https://xmlns.com/foaf/0.1/knows" }, "@id": "https://me.markus-lanthaler.com/", "name": "Markus Lanthaler", "knows": [ {"name": "Dave Longley"} ] }
Running the Flattening Algorithm
(flatten()
)
operation) with a context set to null to prevent compaction
returns the following document:
The example above is the JSON-LD serialization of the output of the flattening algorithm, where the algorithm's use of maps are replaced with JSON objects.
Note how in the output above all properties of a node are collected in a
single node object and how the blank node representing
"Dave Longley" has been assigned the blank node identifier
_:b0
.
To make it easier for humans to read or for certain applications to process it, a flattened document can be compacted by passing a context. Using the same context as the input document, the flattened and compacted document looks as follows:
Please note that the result of flattening and compacting a document
is always a map,
(represented as a JSON object when serialized),
which contains an @graph
entry that represents the default graph.
2.4 RDF Serialization/Deserialization
This section is non-normative.
JSON-LD can be used to serialize RDF data as described in [RDF11-CONCEPTS]. This ensures that data can be round-tripped to and from any RDF syntax without any loss in fidelity.
For example, assume the following RDF input serialized in Turtle [TURTLE]:
@prefix foaf: <https://xmlns.com/foaf/0.1/> . <https://me.markus-lanthaler.com/> foaf:name "Markus Lanthaler" ; foaf:homepage <https://www.markus-lanthaler.com/> .
Using the Serialize RDF as JSON-LD Algorithm a developer could transform this document into expanded JSON-LD:
[ { "@id": "https://me.markus-lanthaler.com/", "https://xmlns.com/foaf/0.1/name": [ { "@value": "Markus Lanthaler" } ], "https://xmlns.com/foaf/0.1/homepage": [ { "@id": "https://www.markus-lanthaler.com/" } ] } ]
The example above is the JSON-LD serialization of the output of the Serialize RDF as JSON-LD Algorithm, where the algorithm's use of maps are replaced with JSON objects.
Note that the output above could easily be compacted using the technique outlined in the previous section. It is also possible to deserialize the JSON-LD document back to RDF using the Deserialize JSON-LD to RDF Algorithm.
3. 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, MUST NOT, and SHOULD 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.
There are two classes of products that can claim conformance to this specification: JSON-LD Processors, and RDF Serializers/Deserializers.
A conforming JSON-LD Processor is a system which can perform the Expansion, Compaction, and Flattening operations in a manner consistent with the algorithms defined in this specification.
JSON-LD Processors MUST NOT attempt to correct malformed IRIs or language tags; however, they SHOULD issue validation warnings. IRIs are not modified other than conversion between relative and absolute IRIs.
A conforming RDF Serializer/Deserializer is a system that can deserialize JSON-LD to RDF and serialize RDF as JSON-LD as defined in this specification.
Unless specified using
processingMode
API option,
the processing mode is set using the @version
entry
in a local context and
affects the behavior of algorithms including expansion and compaction.
Once set, it is an error to attempt to change to a different processing mode,
and processors MUST generate,
a processing mode conflict
error and abort further processing.
The algorithms in this specification are generally written with more concern for clarity than efficiency. Thus, JSON-LD Processors may implement the algorithms given in this specification in any way desired, so long as the end result is indistinguishable from the result that would be obtained by the specification's algorithms.
In algorithm steps that describe operations on keywords, those steps also apply to keyword aliases.
Implementers can partially check their level of conformance to this specification by successfully passing the test cases of the JSON-LD test suite. Note, however, that passing all the tests in the test suite does not imply complete conformance to this specification. It only implies that the implementation conforms to aspects tested by the test suite.
This specification makes use of the following namespace prefixes:
Prefix | IRI |
---|---|
rdf | https://www.w3.org/1999/02/22-rdf-syntax-ns# |
xsd | https://www.w3.org/2001/XMLSchema# |
4. Context Processing Algorithms
The following sections describe algorithms for processing a JSON-LD context.
4.1 Context Processing Algorithm
When processing a JSON-LD data structure, each processing rule is applied using information provided by the active context. This section describes how to produce an active context.
The active context consists of:
- the active term definitions which specify how keys and values have to be interpreted (array of term definitions),
- the current base IRI (IRI),
- the original base URL (IRI),
- an inverse context (inverse context),
- an optional vocabulary mapping (IRI),
- an optional default language (string),
- an optional default base direction (
"ltr"
or"rtl"
), - and an optional previous context (context), used when a non-propagated context is defined.
Each term definition consists of:
- an IRI mapping (IRI),
- a prefix flag (boolean),
- a protected flag (boolean),
- a reverse property flag (boolean),
- an optional base URL (IRI),
- an optional context (context),
- an optional container mapping (array of strings),
- an optional direction mapping (
"ltr"
or"rtl"
), - an optional index mapping (string),
- an optional language mapping (string),
- an optional nest value (string),
- and an optional type mapping (IRI).
A term definition can not only be used to map a term to an IRI, but also to map a term to a keyword, in which case it is referred to as a keyword alias.
When processing, active context is initialized
with a null
inverse context,
without any term definitions,
vocabulary mapping, default base direction, or default language.
If a local context is encountered during processing, a new
active context is created by cloning the existing
active context. Then the information from the
local context is merged into the new active context.
Given that local contexts may contain
references to remote contexts, this includes their retrieval.
4.1.1 Overview
This section is non-normative.
First we prepare a new active context result by cloning the current active context. Then we normalize the form of the original local context to an array. Local contexts may be in the form of a map, a string, or an array containing a combination of the two. Finally we process each context contained in the local context array as follows.
If context is a string, it represents a reference to
a remote context. We dereference the remote context and replace context
with the value of the @context
entry of the top-level object in the
retrieved JSON-LD document.
If there's no such entry, an
invalid remote context
has been detected. Otherwise, we process context by recursively using
this algorithm ensuring that there is no cyclical reference.
If context is a map,
it is a context definition.
We first update
the base IRI,
the default base direction,
the default language,
context propagation,
the processing mode,
and the vocabulary mapping
by processing six specific keywords:
@base
,
@direction
,
@language
,
@propagate
,
@version
,
and @vocab
.
These are handled before any other entries in the local context because
they affect how the other entries are processed.
If context contains @import
, it is retrieved and is reverse-merged
into the containing context, allowing JSON-LD 1.0 contexts to be upgraded to JSON-LD 1.1.
Please note that @base
is ignored when processing remote contexts.
If context is not to be propagated, a reference to the previous context is retained so that it may be rolled back when a new node object is entered. By default, all contexts are propagated, other than type-scoped contexts.
When an active context is initialized, the value
of the original base URL
is initialized from the original
of the document containing the initial context, if available,
otherwise from the documentUrl
API option.
This is necessary when resetting the active context
by setting it to base
null
to retain the original default base IRI.
When initialized, or when any entry of
an active context is changed,
or any associated term definition is added, changed, or removed,
the inverse context field
in active context is set to null
.
Then, for every other entry in local context, we update the term definition in result. Since term definitions in a local context may themselves contain terms or compact IRIs, we may need to recurse. When doing so, we must ensure that there is no cyclical dependency, which is an error. After we have processed any term definition dependencies, we update the current term definition, which may be a keyword alias.
Finally, we return result as the new active context.
4.1.2 Algorithm
This algorithm specifies how a new active context is updated
with a local context. The algorithm takes three required
and four optional
input variables.
The required inputs are
an active context,
a local context,
and a base URL used when resolving relative context URLs.
The optional inputs are
an array remote contexts,
defaulting to a new empty array, which is used to detect cyclical context inclusions,
override protected, defaulting to false
,
which is used to allow changes to protected terms,
propagate, defaulting to true
to mark term definitions associated with non-propagated contexts,
and validate scoped context defaulting to true
,
which is used to limit recursion when validating possibly recursive scoped contexts..
- Initialize result to the result of cloning
active context,
with inverse context set to
null
.. - If local context is an object containing the member
@propagate
, its value MUST be booleantrue
orfalse
, set propagate to that value.NoteError handling is performed in step 5.11. - If propagate is
false
, and result does not have a previous context, set previous context in result to active context. - If local context is not an array, set local context to an array containing only local context.
-
For each item context in local context:
- If context is
null
:- If override protected is
false
and active context contains any protected term definitions, aninvalid context nullification
has been detected and processing is aborted. - Initialize result as a
newly-initialized active context,
setting both base IRI and original base URL to the value of
original base URL in active context,
and, if propagate is
false
, previous context in result to the previous value of result. - Continue with the next context.
- If override protected is
- If context is a string,
- Initialize context to the result of resolving context against
base URL. If base URL is not a valid IRI,
then context MUST be a valid IRI, otherwise
a
loading document failed
error has been detected and processing is aborted. - If validate scoped context is
false
, and remote contexts already includes context do not process context further and continue to any next context in local context. - If the number of entries in the remote contexts array
exceeds a processor defined limit, a
context overflow
error has been detected and processing is aborted; otherwise, add context to remote contexts. - If context was previously dereferenced,
then the processor MUST NOT do a further dereference, and
context is set to the
previously established internal representation:
set context document to the previously dereferenced document,
and set loaded context to the value of the
@context
entry from the document in context document.NoteOnly the@context
entry need be retained. - Otherwise, set context document
to the
obtained by dereferencing context using theRemoteDocument
LoadDocumentCallback
, passing context for url, andhttps://www.w3.org/ns/json-ld#context
forprofile
and forrequestProfile
.- If context cannot be dereferenced,
or the
from context document cannot be transformed into the internal representation , adocument
loading remote context failed
error has been detected and processing is aborted. - If the
has no top-level map with andocument
@context
entry, aninvalid remote context
has been detected and processing is aborted. - Set loaded context to the value of that entry.
- If context cannot be dereferenced,
or the
- Set result to the result of recursively calling this algorithm,
passing result for active context,
loaded context for local context,
the
of context document for base URL, a copy of remote contexts, and validate scoped context.documentUrl
NoteIf context was previously dereferenced, processors MUST make provisions for retaining the base URL of that context for this step to enable the resolution of any relative context URLs that may be encountered during processing. - Continue with the next context.
- Initialize context to the result of resolving context against
base URL. If base URL is not a valid IRI,
then context MUST be a valid IRI, otherwise
a
- If context is not a map, an
invalid local context
error has been detected and processing is aborted. - Otherwise, context is a context definition.
- If context has an
@version
entry:- If the associated value is not
1.1
, aninvalid @version value
has been detected, and processing is aborted.NoteThe use of1.1
for the value of@version
is intended to cause a JSON-LD 1.0 processor to stop processing. Although it is clearly meant to be related to JSON-LD 1.1, it does not otherwise adhere to the requirements for Semantic Versioning. Implementations may require special consideration when comparing the values of numbers with a non-zero fractional part. - If processing mode
is set to
json-ld-1.0
, aprocessing mode conflict
error has been detected and processing is aborted.
- If the associated value is not
- If context has an
@import
entry:- If processing mode is
json-ld-1.0
, aninvalid context entry
error has been detected and processing is aborted. - Otherwise, if the value of
@import
is not a string, aninvalid @import value
error has been detected and processing is aborted. - Initialize import to the result of resolving the value of
@import
against base URL. - Dereference import using
the
LoadDocumentCallback
, passing import for url, andhttps://www.w3.org/ns/json-ld#context
forprofile
and forrequestProfile
. - If import cannot be dereferenced,
or cannot be transformed into the internal representation,
a
loading remote context failed
error has been detected and processing is aborted. - If the dereferenced document has no
top-level map with an
@context
entry, or if the value of@context
is not a context definition (i.e., it is not an map), aninvalid remote context
has been detected and processing is aborted; otherwise, set import context to the value of that entry. - If import context has a
@import
entry, aninvalid context entry
error has been detected and processing is aborted. - Set context to the result of merging context into import context, replacing common entries with those from context.
- If processing mode is
- If context has an
@base
entry and remote contexts is empty, i.e., the currently being processed context is not a remote context:- Initialize value to the value associated with the
@base
entry. - If value is
null
, remove the base IRI of result. - Otherwise, if value is an IRI, the base IRI of result is set to value.
- Otherwise, if value is a relative IRI reference and
the base IRI of result is not
null
, set the base IRI of result to the result of resolving value against the current base IRI of result. - Otherwise, an
invalid base IRI
error has been detected and processing is aborted.
- Initialize value to the value associated with the
- If context has an
@vocab
entry:- Initialize value to the value associated with the
@vocab
entry. - If value is null, remove any vocabulary mapping from result.
- Otherwise, if value is
an IRI
or blank node identifier, the vocabulary mapping
of result is set to
the result of
IRI expanding value
using
true
for document relative . If it is not an IRI, or a blank node identifier, aninvalid vocab mapping
error has been detected and processing is aborted.NoteThe use of blank node identifiers to value for@vocab
is obsolete, and may be removed in a future version of JSON-LD.
- Initialize value to the value associated with the
- If context has an
@language
entry:- Initialize value to the value associated with the
@language
entry. - If value is
null
, remove any default language from result. - Otherwise, if value is a string, the
default language of result is set to
value.
If it is not a string, an
invalid default language
error has been detected and processing is aborted. If value is not well-formed according to section 2.2.9 of [BCP47], processors SHOULD issue a warning.NoteProcessors MAY normalize language tags to lower case.
- Initialize value to the value associated with the
- If context has an
@direction
entry:- If processing mode is
json-ld-1.0
, aninvalid context entry
error has been detected and processing is aborted. - Initialize value to the value associated with the
@direction
entry. - If value is
null
, remove any base direction from result. - Otherwise, if value is a string, the
base direction of result is set to
value. If it is not
null
,"ltr"
, or"rtl"
, aninvalid base direction
error has been detected and processing is aborted.
- If processing mode is
- If context has an
@propagate
entry:- If processing mode is
json-ld-1.0
, aninvalid context entry
error has been detected and processing is aborted. - Otherwise, if the value of
@propagate
is not booleantrue
orfalse
, aninvalid @propagate value
error has been detected and processing is aborted.NoteThe previous context is actually set earlier in this algorithm; the previous two steps exist for error checking only.
- If processing mode is
- Create a map defined to keep track of whether or not a term has already been defined or is currently being defined during recursion.
- For each key-value pair in context where
key is not
@base
,@direction
,@import
,@language
,@propagate
,@protected
,@version
, or@vocab
, invoke the Create Term Definition algorithm, passing result for active context, context for local context, key, defined, base URL, the value of the@protected
entry from context, if any, for protected, override protected, and a copy of remote contexts.
- If context is
- Return result.
4.2 Create Term Definition
This algorithm is called from the Context Processing algorithm to create a term definition in the active context for a term being processed in a local context.
4.2.1 Overview
This section is non-normative.
Term definitions are created by parsing the information in the given local context for the given term. If the given term is a compact IRI, it may omit an IRI mapping by depending on its prefix having its own term definition. If the prefix is an entry in the local context, then its term definition must first be created, through recursion, before continuing. Because a term definition can depend on other term definitions, a mechanism must be used to detect cyclical dependencies. The solution employed here uses a map, defined, that keeps track of whether or not a term has been defined or is currently in the process of being defined. This map is checked before any recursion is attempted.
After all dependencies for a term have been defined, the rest of the information in the local context for the given term is taken into account, creating the appropriate IRI mapping, container mapping, and type mapping, language mapping, or direction mapping for the term.
4.2.2 Algorithm
The algorithm has four required and five optional inputs.
The required inputs are
an active context,
a local context,
a term,
and a map defined.
The optional inputs are
base URL defaulting to null
,
protected which defaults to false
,
and override protected, defaulting to false
,
which is used to allow changes to protected terms,
an array remote contexts,
defaulting to a new empty array, which is used to detect cyclical context inclusions,
and validate scoped context defaulting to true
,
which is used to limit recursion when validating possibly recursive scoped contexts..
- If defined contains the entry term and the associated
value is
true
(indicating that the term definition has already been created), return. Otherwise, if the value isfalse
, acyclic IRI mapping
error has been detected and processing is aborted. - If term is the empty string (
"carview.php?tsp="
), aninvalid term definition
error has been detected and processing is aborted. Otherwise, set the value associated with defined's term entry tofalse
. This indicates that the term definition is now being created but is not yet complete. - Initialize value to a copy of the value associated with the entry term in local context.
- If term is
@type
, and processing mode isjson-ld-1.0
, akeyword redefinition
error has been detected and processing is aborted. At this point, value MUST be a map with only either or both of the following entries:- An entry for
@container
with value@set
. - An entry for
@protected
.
keyword redefinition
error has been detected and processing is aborted. - An entry for
- Otherwise, since keywords cannot be overridden,
term MUST NOT be a keyword and a
keyword redefinition
error has been detected and processing is aborted. If term has the form of a keyword (i.e., it matches the ABNF rule"@"1*ALPHA
from [RFC5234]), return; processors SHOULD generate a warning. - Initialize previous definition to any existing term definition for term in active context, removing that term definition from active context.
- If value is
null
, convert it to a map consisting of a single entry whose key is@id
and whose value isnull
. - Otherwise, if value is a string, convert it
to a map consisting of a single entry whose
key is
@id
and whose value is value. Set simple term totrue
. - Otherwise, value MUST be a map, if not, an
invalid term definition
error has been detected and processing is aborted. Set simple term tofalse
. - Create a new term definition, definition,
initializing prefix flag to
false
, protected to protected, and reverse property tofalse
. - If value has an
@protected
entry, set the protected flag in definition to the value of this entry. If the value of@protected
is not a boolean, aninvalid @protected value
error has been detected and processing is aborted. If processing mode isjson-ld-1.0
, aninvalid term definition
has been detected and processing is aborted. - If value contains the entry
@type
:- Initialize type to the value associated with the
@type
entry, which MUST be a string. Otherwise, aninvalid type mapping
error has been detected and processing is aborted. - Set type to the result of IRI expanding type, using local context, and defined.
- If the expanded type is
@json
or@none
, and processing mode isjson-ld-1.0
, aninvalid type mapping
error has been detected and processing is aborted. - Otherwise, if the expanded type is
neither
@id
, nor@json
, nor@none
, nor@vocab
, nor an IRI, aninvalid type mapping
error has been detected and processing is aborted. - Set the type mapping for definition to type.
- Initialize type to the value associated with the
- If value contains the entry
@reverse
:- If value contains
@id
or@nest
, entries, aninvalid reverse property
error has been detected and processing is aborted. - If the value associated with the
@reverse
entry is not a string, aninvalid IRI mapping
error has been detected and processing is aborted. - If the value associated with the
@reverse
entry is a string having the form of a keyword (i.e., it matches the ABNF rule"@"1*ALPHA
from [RFC5234]), return; processors SHOULD generate a warning. - Otherwise, set the IRI mapping of definition to the
result of
IRI expanding
the value associated with the
@reverse
entry, using local context, and defined. If the result does not have the form of an IRI or a blank node identifier, aninvalid IRI mapping
error has been detected and processing is aborted. - If value contains an
@container
entry, set the container mapping of definition to an array containing its value; if its value is neither@set
, nor@index
, nornull
, aninvalid reverse property
error has been detected (reverse properties only support set- and index-containers) and processing is aborted. - Set the reverse property flag of definition
to
true
. - Set the term definition of term in
active context to definition and the
value associated with defined's entry term to
true
and return.
- If value contains
- If value contains the entry
@id
and its value does not equal term:- If the
@id
entry of value isnull
, the term is not used for IRI expansion, but is retained to be able to detect future redefinitions of this term. - Otherwise:
- If the value associated with the
@id
entry is not a string, aninvalid IRI mapping
error has been detected and processing is aborted. - If the value associated with the
@id
entry is not a keyword, but has the form of a keyword (i.e., it matches the ABNF rule"@"1*ALPHA
from [RFC5234]), return; processors SHOULD generate a warning. - Otherwise, set the IRI mapping of definition to the
result of
IRI expanding
the value associated with the
@id
entry, using local context, and defined. If the resulting IRI mapping is neither a keyword, nor an IRI, nor a blank node identifier, aninvalid IRI mapping
error has been detected and processing is aborted; if it equals@context
, aninvalid keyword alias
error has been detected and processing is aborted. - If the term contains a colon (
:
) anywhere but as the first or last character of term, or if it contains a slash (/
) anywhere:- Set the value associated with defined's term entry to
true
. - If the result of IRI expanding term
using local context, and defined,
is not the same as the IRI mapping of definition,
an
invalid IRI mapping
error has been detected and processing is aborted.
- Set the value associated with defined's term entry to
- If term contains neither a colon (
:
) nor a slash (/
), simple term istrue
, and if the IRI mapping of definition is either an IRI ending with a gen-delim character, or a blank node identifier, set the prefix flag in definition totrue
.
- If the value associated with the
- If the
-
Otherwise if the term contains a colon (
:
) anywhere after the first character:- If term is a compact IRI with a prefix that is an entry in local context a dependency has been found. Use this algorithm recursively passing active context, local context, the prefix as term, and defined.
- If term's prefix has a term definition in active context, set the IRI mapping of definition to the result of concatenating the value associated with the prefix's IRI mapping and the term's suffix.
- Otherwise, term is an IRI or blank node identifier. Set the IRI mapping of definition to term.
-
Otherwise if the term contains a slash (
/
):- Term is a relative IRI reference.
- Set the IRI mapping of definition to the
result of IRI expanding term.
If the resulting IRI mapping is not an IRI, an
invalid IRI mapping
error has been detected and processing is aborted.
- Otherwise, if term is
@type
, set the IRI mapping of definition to@type
. - Otherwise, if active context has a
vocabulary mapping, the IRI mapping
of definition is set to the result of concatenating the value
associated with the vocabulary mapping and term.
If it does not have a vocabulary mapping, an
invalid IRI mapping
error been detected and processing is aborted. - If value contains the entry
@container
:- Initialize container to the value associated with the
@container
entry, which MUST be either@graph
,@id
,@index
,@language
,@list
,@set
,@type
, or an array containing exactly any one of those keywords, an array containing@graph
and either@id
or@index
optionally including@set
, or an array containing a combination of@set
and any of@index
,@graph
,@id
,@type
,@language
in any order . Otherwise, aninvalid container mapping
has been detected and processing is aborted. - If the container value
is
@graph
,@id
, or@type
, or is otherwise not a string, generate aninvalid container mapping
error and abort processing if processing mode isjson-ld-1.0
. - Set the container mapping of definition to container coercing to an array, if necessary.
- If the container mapping of definition includes
@type
:- If type mapping in definition is undefined, set it to
@id
. - If type mapping in definition is neither
@id
nor@vocab
, aninvalid type mapping
error has been detected and processing is aborted.
- If type mapping in definition is undefined, set it to
- Initialize container to the value associated with the
- If value contains the entry
@index
:- If processing mode is
json-ld-1.0
or container mapping does not include@index
, aninvalid term definition
has been detected and processing is aborted. - Initialize index to the value associated with the
@index
entry. If the result of IRI expanding that value is not an IRI, aninvalid term definition
has been detected and processing is aborted. - Set the index mapping of definition to index
- If processing mode is
- If value contains the entry
@context
:- If processing mode is
json-ld-1.0
, aninvalid term definition
has been detected and processing is aborted. - Initialize context to the value associated with the
@context
entry, which is treated as a local context. - Invoke the Context Processing algorithm
using the active context, context as local context,
base URL,
true
for override protected, a copy of remote contexts, andfalse
for validate scoped context. If any error is detected, aninvalid scoped context
error has been detected and processing is aborted.NoteThe result of the Context Processing algorithm is discarded; it is called to detect errors at definition time. If used, the context will be re-processed and applied to the active context as part of expansion or compaction.
- Set the local context of definition to context, and base URL to base URL.
- If processing mode is
- If value contains the entry
@language
and does not contain the entry@type
:- Initialize language to the value associated with the
@language
entry, which MUST be eithernull
or a string. If language is not well-formed according to section 2.2.9 of [BCP47], processors SHOULD issue a warning. Otherwise, aninvalid language mapping
error has been detected and processing is aborted. - Set the language mapping of definition to language.
NoteProcessors MAY normalize language tags to lower case.
- Initialize language to the value associated with the
- If value contains the entry
@direction
and does not contain the entry@type
:- Initialize direction to the value associated with the
@direction
entry, which MUST be eithernull
,"ltr"
, or"rtl"
. Otherwise, aninvalid base direction
error has been detected and processing is aborted. - Set the direction mapping of definition to direction.
- Initialize direction to the value associated with the
- If value contains the entry
@nest
:- If processing mode is
json-ld-1.0
, aninvalid term definition
has been detected and processing is aborted. - Initialize nest value in definition to the value associated with the
@nest
entry, which MUST be a string and MUST NOT be a keyword other than@nest
. Otherwise, aninvalid @nest value
error has been detected and processing is aborted.
- If processing mode is
- If value contains the entry
@prefix
:- If processing mode is
json-ld-1.0
, or if term contains a colon (:
) or slash (/
), aninvalid term definition
has been detected and processing is aborted. - Set the prefix flag to the value associated with the
@prefix
entry, which MUST be a boolean. Otherwise, aninvalid @prefix value
error has been detected and processing is aborted. - If the prefix flag of definition is set to
true
, and its IRI mapping is a keyword, aninvalid term definition
has been detected and processing is aborted.
- If processing mode is
- If value contains any entry other than
@id
,@reverse
,@container
,@context
,@direction
,@index
,@language
,@nest
,@prefix
,@protected
, or@type
, aninvalid term definition
error has been detected and processing is aborted. - If override protected is
false
and previous definition exists and is protected;- If definition is not the same as previous definition
(other than the value of protected),
a
protected term redefinition
error has been detected, and processing is aborted. - Set definition to previous definition to retain the value of protected.
- If definition is not the same as previous definition
(other than the value of protected),
a
- Set the term definition of term in
active context to definition and set the value
associated with defined's entry term to
true
.
4.3 Inverse Context Creation
When there is more than one term that could be chosen to compact an IRI, it has to be ensured that the term selection is both deterministic and represents the most context-appropriate choice whilst taking into consideration algorithmic complexity.
In order to make term selections, the concept of an inverse context is introduced. An inverse context is essentially a reverse lookup table that maps container mapping, type mappings, and language mappings to a simple term for a given active context. A inverse context only needs to be generated for an active context if it is being used for compaction.
To make use of an inverse context, a list of preferred container mapping and the type mapping or language mapping are gathered for a particular value associated with an IRI. These parameters are then fed to the Term Selection algorithm, which will find the term that most appropriately matches the value's mappings.
4.3.1 Overview
This section is non-normative.
To create an inverse context for a given
active context, each term in the
active context is visited, ordered by length, shortest
first (ties are broken by choosing the lexicographically least
term). For each term, an entry is added to
the inverse context for each possible combination of
container mapping and type mapping
or language mapping that would legally match the
term. Illegal matches include differences between a
value's type mapping or language mapping and
that of the term. If a term has no
container mapping, type mapping, or
language mapping (or some combination of these), then it
will have an entry in the inverse context using the special
key @none
. This allows the
Term Selection algorithm to fall back
to choosing more generic terms when a more
specifically-matching term is not available for a particular
IRI and value combination.
Although normalizing language tags is optional, the inverse context creates entries based on normalized language tags, so that the proper term can be selected regardless of representation.
4.3.2 Algorithm
The algorithm takes one required input: the active context that the inverse context is being created for.
- Initialize result to an empty map.
- Initialize default language to
@none
. If the active context has a default language, set default language to the default language from the active context normalized to lower case. - For each key term and value term definition in
the active context, ordered by shortest term
first (breaking ties by choosing the lexicographically least
term):
- If the term definition is
null
, term cannot be selected during compaction, so continue to the next term. - Initialize container to
@none
. If the container mapping is not empty, set container to the concatenation of all values of the container mapping in lexicographical order . - Initialize var to the value of the IRI mapping for the term definition.
- If var is not an entry of result, add an entry where the key is var and the value is an empty map to result.
- Reference the value associated with the var entry in result using the variable container map.
- If container map has no container entry,
create one and set its value to a new
map with three entries.
The first entry is
@language
and its value is a new empty map, the second entry is@type
and its value is a new empty map, and the third entry is@any
and its value is a new map with the entry@none
set to the term being processed. - Reference the value associated with the container entry in container map using the variable type/language map.
- Reference the value associated with the
@type
entry in type/language map using the variable type map. - Reference the value associated with the
@language
entry in type/language map using the variable language map. - If the term definition indicates that the term represents a reverse property:
- Otherwise, if term definition has a
type mapping which is
@none
: - Otherwise, if term definition has a
type mapping:
- If type map does not have an entry corresponding to the type mapping in term definition, create one and set its value to the term being processed.
- Otherwise, if term definition has both
a language mapping and a direction mapping:
- Create a new variable lang dir.
- If neither the language mapping nor the direction mapping
are
null
, set lang dir to the concatenation of language mapping and direction mapping separated by an underscore ("_"
) normalized to lower case. - Otherwise, if language mapping is not
null
, set lang dir to the language mapping, normalized to lower case. - Otherwise, if direction mapping is not
null
, set lang dir to direction mapping preceded by an underscore ("_"
). - Otherwise, set lang dir to
@null
. - If language map does not have a lang dir entry, create one and set its value to the term being processed.
- Otherwise, if term definition has a
language mapping (might be
null
):- If the language mapping equals
null
, set language to@null
; otherwise to the language mapping, normalized to lower case. - If language map does not have a language entry, create one and set its value to the term being processed.
- If the language mapping equals
- Otherwise, if term definition has a
direction mapping (might be
null
):- If the direction mapping equals
null
, set direction to@none
; otherwise to direction mapping preceded by an underscore ("_"
). - If language map does not have a direction entry, create one and set its value to the term being processed.
- If the direction mapping equals
- Otherwise, if active context has a
default base direction:
- Initialize a variable lang dir
with the concatenation of default language and default base direction,
separate by an underscore (
"_"
), normalized to lower case. - If language map does not have a lang dir entry, create one and set its value to the term being processed.
- If language map does not have an
@none
entry, create one and set its value to the term being processed. - If type map does not have an
@none
entry, create one and set its value to the term being processed.
- Initialize a variable lang dir
with the concatenation of default language and default base direction,
separate by an underscore (
- Otherwise:
- If language map does not have a default language entry (after being normalized to lower case), create one and set its value to the term being processed.
- If language map does not have an
@none
entry, create one and set its value to the term being processed. - If type map does not have an
@none
entry, create one and set its value to the term being processed.
- If the term definition is
- Return result.
4.4 Term Selection
This algorithm, invoked via the IRI Compaction algorithm, makes use of an active context's inverse context to find the term that is best used to compact an IRI. Other information about a value associated with the IRI is given, including which container mapping and which type mapping or language mapping would be best used to express the value.
4.4.1 Overview
This section is non-normative.
The inverse context's entry for the IRI will be first searched according to the preferred container mapping, in the order that they are given. Amongst terms with a matching container mapping, preference will be given to those with a matching type mapping or language mapping, over those without a type mapping or language mapping. If there is no term with a matching container mapping then the term without a container mapping that matches the given type mapping or language mapping is selected. If there is still no selected term, then a term with no type mapping or language mapping will be selected if available. No term will be selected that has a conflicting type mapping or language mapping. Ties between terms that have the same mappings are resolved by first choosing the shortest terms, and then by choosing the lexicographically least term. Note that these ties are resolved automatically because they were previously resolved when the Inverse Context Creation algorithm was used to create the inverse context.
4.4.2 Algorithm
This algorithm has five required inputs. They are: an active context, a keyword or IRI var, an array containers that represents an ordered list of preferred container mapping, a string type/language that indicates whether to look for a term with a matching type mapping or language mapping, and an array representing an ordered list of preferred values for the type mapping or language mapping to look for.
- If the active context has a
null
inverse context, set inverse context in active context to the result of calling the Inverse Context Creation algorithm using active context. - Initialize inverse context to the value of inverse context in active context.
- Initialize container map to the value associated with var in the inverse context.
- For each item container in containers:
- If container is not an entry of container map, then there is no term with a matching container mapping for it, so continue to the next container.
- Initialize type/language map to the value associated with the container entry in container map.
- Initialize value map to the value associated with type/language entry in type/language map.
- For each item in preferred values:
- If item is not an entry of value map, then there is no term with a matching type mapping or language mapping, so continue to the next item.
- Otherwise, a matching term has been found, return the value associated with the item entry in value map.
- No matching term has been found. Return
null
.
4.4.3 Examples
This section is non-normative.
The following examples are intended to illustrate how the term selection algorithm behaves for different term definitions and values. It is not comprehensive, but intended to illustrate different parts of the algorithm.
Language Map Term
If the term definition has "@container": "@language"
, it will only match a
value object having no @type
.
Datatyped Term
If the term definition has a datatype, it will only match a value object having a matching datatype.
5. Expansion Algorithms
The following sections describe algorithms for expanding JSON-LD documents, IRIs and values.
5.1 Expansion Algorithm
This algorithm expands a JSON-LD document, such that all context definitions are removed, all terms and compact IRIs are expanded to IRIs, blank node identifiers, or keywords and all JSON-LD values are expressed in arrays in expanded form.
5.1.1 Overview
This section is non-normative.
Starting with its root element, we can process the JSON-LD document recursively, until we have a fully expanded result. When expanding an element, we can treat each one differently according to its type, in order to break down the problem:
- If the element is
null
, there is nothing to expand. - Otherwise, if element is a scalar, we expand it according to the Value Expansion algorithm.
- Otherwise, if the element is an array, then we expand each of its items recursively and return them in a new array.
- Otherwise, element is a map. We expand each of its entries, adding them to our result, and then we expand each value for each entry recursively. Some of the entry keys will be terms or compact IRIs and others will be keywords or simply ignored because they do not have definitions in the context. Any IRIs will be expanded using the IRI Expansion algorithm.
Finally, after ensuring result is in an array, we return result.
Although the data model, based on [RDF11-CONCEPTS], does not support multiple unordered property values, this algorithm does not remove duplicates that may be found during expansion within an unordered array. Other algorithms, such as § 6.1 Compaction Algorithm, and § 7.1 Flattening Algorithm, do eliminate duplicate values from unordered arrays. A future version of this specification may be updated to remove duplicate array values when the form a set.
5.1.2 Algorithm
The algorithm takes four required and three optional input variables.
The required inputs are an active context,
an active property, an element to be expanded,
and a base URL associated with the
of the original
document to expand.
The optional inputs are the
documentUrl
flag allowing special forms of input used for frame expansion,
the frameExpansion
flag, used to order
map entry keys lexicographically, where noted,
and the from map flag, used to control reverting
previous term definitions in the active context associated with non-propagated contexts.
If not passed, the optional flags are set to ordered
false
.
The algorithm also performs processing steps specific to expanding
a JSON-LD Frame. For a frame, the @id
and
@type
entries can accept an array of IRIs or
an empty map. The entries of a value object can also
accept an array of strings, or an empty map.
Framing also uses additional keyword entries:
(@explicit
, @default
,
@embed
, @explicit
, @omitDefault
, or
@requireAll
) which are preserved through expansion.
Special processing for a JSON-LD Frame is invoked when the
flag is set to frameExpansion
true
.
As mentioned in Terms [JSON-LD11],
to avoid forward-compatibility issues, terms should not start with an
@
character as future versions of JSON-LD may introduce
additional keywords.
This algorithm will treat such terms like any other term, i.e., they are ignored unless mapped to an IRI.
Implementations of this algorithm may consider providing a
runtime flag to show a warning if such terms are encountered.
The use of empty terms ("carview.php?tsp="
) is not
allowed as not all programming languages are able to handle empty JSON keys.
Implementations of this algorithm may consider providing a
runtime flag to show a warning if such terms are encountered.
The use of blank node identifiers to label properties is obsolete, and may be removed in a future version of JSON-LD. Implementations of this algorithm may consider providing a runtime flag to show a warning if such terms are encountered.
- If element is
null
, returnnull
. - If active property is
@default
, initialize the
flag toframeExpansion
false
. - If active property has a term definition in active context with a local context, initialize property-scoped context to that local context.
- If element is a scalar,
- If active property is
null
or@graph
, drop the free-floating scalar by returningnull
. - If property-scoped context is defined, set active context to the result of the Context Processing algorithm, passing active context, property-scoped context as local context, and base URL from the term definition for active property in active context.
- Return the result of the Value Expansion algorithm, passing the active context, active property, and element as value.
- If active property is
- If element is an array,
- Initialize an empty array, result.
- For each item in element:
- Initialize expanded item to the result of using this
algorithm recursively, passing active context,
active property, item as element,
base URL,
the
frameExpansion
, and from map flags.ordered
- If the container mapping
of active property includes
@list
, and expanded item is an array, set expanded item to a new map containing the entry@list
where the value is the original expanded item. - If expanded item is an array, append each of its items to result. Otherwise, if expanded item is not null, append it to result.
- Initialize expanded item to the result of using this
algorithm recursively, passing active context,
active property, item as element,
base URL,
the
- Return result.
- Otherwise element is a map.
- If active context has a previous context,
the active context is not propagated.
If from map is undefined or
false
, and element does not contain an entry expanding to@value
, and element does not consist of a single entry expanding to@id
(where entries are IRI expanded, set active context to previous context from active context, as the scope of a term-scoped context does not apply when processing new node objects. - If property-scoped context is defined,
set active context to the result of the
Context Processing algorithm,
passing active context, property-scoped context as local context,
base URL from the term definition for active property,
in active context
and
true
for override protected. - If element contains the entry
@context
, set active context to the result of the Context Processing algorithm, passing active context, the value of the@context
entry as local context and base URL. - Initialize type-scoped context to active context. This is used for expanding values that may be relevant to any previous type-scoped context.
- For each key and value in element
ordered lexicographically by key
where key IRI expands to
@type
:- Convert value into an array, if necessary.
- For each term which is a value of value ordered lexicographically,
if term is a string,
and term's term definition in type-scoped context
has a local context, set active context to the result
Context Processing algorithm,
passing active context,
the value of the
term's local context as local context,
base URL from the term definition for value
in active context,
and
false
for propagate.
- Initialize two empty maps, result
and nests.
Initialize input type to expansion of the last value of the first entry in element
expanding to
@type
(if any), ordering entries lexicographically by key. Both the key and value of the matched entry are IRI expanded. -
For each key and value in element,
ordered lexicographically by key if
isordered
true
:- If key is
@context
, continue to the next key. - Initialize expanded property to the result of IRI expanding key.
- If expanded property is
null
or it neither contains a colon (:
) nor it is a keyword, drop key by continuing to the next key. - If expanded property is a keyword:
- If active property equals
@reverse
, aninvalid reverse property map
error has been detected and processing is aborted. - If result already has an expanded property entry,
other than
@included
or@type
(unless processing mode isjson-ld-1.0
), acolliding keywords
error has been detected and processing is aborted. - If expanded property is
@id
:- If value is not a string, an
invalid @id value
error has been detected and processing is aborted. When the
flag is set, value MAY be an empty map, or an array of one or more strings.frameExpansion
- Otherwise,
set expanded value to the result of
IRI expanding value
using
true
for document relative andfalse
for vocab. When the
flag is set, expanded value will be an array of one or more of the values, with string values expanded using the IRI Expansion algorithm as above.frameExpansion
- If value is not a string, an
- If expanded property is
@type
:- If value
is neither a string nor an array of
strings, an
invalid type value
error has been detected and processing is aborted. When the
flag is set, value MAY be an empty map, or a default object where the value offrameExpansion
@default
is restricted to be an IRI. All other values mean thatinvalid type value
error has been detected and processing is aborted. - If value is an empty map, set expanded value to value.
- Otherwise, if value
is a default object, set expanded value to
a new default object with the value of
@default
set to the result of IRI expanding value using type-scoped context for active context, andtrue
for document relative. - Otherwise,
set expanded value to the result of
IRI expanding
each of its values
using type-scoped context for active context,
and
true
for document relative. - If result already has an entry for
@type
, prepend the value of@type
in result to expanded value, transforming it into an array, if necessary.
- If value
is neither a string nor an array of
strings, an
- If expanded property is
@graph
, set expanded value to the result of using this algorithm recursively passing active context,@graph
for active property, value for element, base URL, and the
andframeExpansion
flags, ensuring that expanded value is an array of one or more maps.ordered
- If expanded property is
@included
:- If processing mode is
json-ld-1.0
, continue with the next key from element. - 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
andframeExpansion
flags, ensuring that the result is an array.ordered
- If any element of expanded value is not a node object,
an
invalid @included value
error has been detected and processing is aborted. - If result already has an entry for
@included
, prepend the value of@included
in result to expanded value.
- If processing mode is
- If expanded property is
@value
:- If
input type is
@json
, set expanded value to value. If processing mode isjson-ld-1.0
, aninvalid value object value
error has been detected and processing is aborted. - Otherwise, if value is not a scalar or
null
, aninvalid value object value
error has been detected and processing is aborted. When the
flag is set, value MAY be an empty map or an array of scalar values.frameExpansion
- Otherwise, set expanded value to value.
When the
flag is set, expanded value will be an array of one or more string values or an array containing an empty map.frameExpansion
- If expanded value
is
null
, set the@value
entry of result tonull
and continue with the next key from element. Null values need to be preserved in this case as the meaning of an@type
entry depends on the existence of an@value
entry.
- If
input type is
- If expanded property is
@language
:- If value is not a string, an
invalid language-tagged string
error has been detected and processing is aborted. When the
flag is set, value MAY be an empty map or an array of zero or more strings.frameExpansion
-
Otherwise, set expanded value to value.
If value is not well-formed according to
section 2.2.9 of [BCP47],
processors SHOULD issue a warning.
When the
flag is set, expanded value will be an array of one or more string values or an array containing an empty map.frameExpansion
NoteProcessors MAY normalize language tags to lower case.
- If value is not a string, an
- If expanded property is
@direction
:- If processing mode is
json-ld-1.0
, continue with the next key from element. - If value is neither
"ltr"
nor"rtl"
, aninvalid base direction
error has been detected and processing is aborted. When the
flag is set, value MAY be an empty map or an array of zero or more strings.frameExpansion
- Otherwise, set expanded value to value.
When the
flag is set, expanded value will be an array of one or more string values or an array containing an empty map.frameExpansion
- If processing mode is
- If expanded property is
@index
:- If value is not a string, an
invalid @index value
error has been detected and processing is aborted. - Otherwise, set expanded value to value.
- If value is not a string, an
- If expanded property is
@list
:- If active property is
null
or@graph
, continue with the next key from element to remove the free-floating list. - Otherwise, initialize expanded value to the result of using
this algorithm recursively passing active context,
active property, value for element,
base URL,
and the
andframeExpansion
flags, ensuring that the result is an array..ordered
- If active property is
- If expanded property is
@set
, set expanded value to the result of using this algorithm recursively, passing active context, active property, value for element, base URL, and the
andframeExpansion
flags.ordered
- If expanded property is
@reverse
:- If value is not a map, an
invalid @reverse value
error has been detected and processing is aborted. - Otherwise initialize expanded value to the result of using this
algorithm recursively, passing active context,
@reverse
as active property, value as element, base URL, and the
andframeExpansion
flags.ordered
- If expanded value contains an
@reverse
entry, i.e., properties that are reversed twice, execute for each of its property and item the following steps: - If expanded value contains an entry other than
@reverse
:- Set reverse map to the value
of the
@reverse
entry in result, initializing it to an empty map, if necessary. - For each property and items in expanded value
other than
@reverse
:- For each item in items:
- If item is a value object or list object, an
invalid reverse property value
has been detected and processing is aborted. - Use add value to add item
to the property entry in reverse map
using
true
for as array.
- If item is a value object or list object, an
- For each item in items:
- Set reverse map to the value
of the
- Continue with the next key from element.
- If value is not a map, an
- If expanded property is
@nest
, add key to nests, initializing it to an empty array, if necessary. Continue with the next key from element. - When the
flag is set, if expanded property is any other framing keyword (frameExpansion
@default
,@embed
,@explicit
,@omitDefault
, or@requireAll
), set expanded value to the result of performing the Expansion Algorithm recursively, passing active context, active property, value for element, base URL, and the
andframeExpansion
flags.ordered
- Unless expanded value is
null
, expanded property is@value
, and input type is not@json
, set the expanded property entry of result to expanded value. - Continue with the next key from element.
- If active property equals
- Initialize container mapping to key's container mapping in active context.
- If key's term definition in active context
has a type mapping of
@json
, set expanded value to a new map, set the entry@value
to value, and set the entry@type
to@json
. - Otherwise, if container mapping includes
@language
and value is a map then value is expanded from a language map as follows:- Initialize expanded value to an empty array.
- Initialize direction to the default base direction from active context.
- If key's term definition in active context has a direction mapping, update direction with that value.
- For each key-value pair language-language value
in value, ordered lexicographically by language if
isordered
true
:- If language value is not an array set language value to an array containing only language value.
- For each item in language value:
- If item is
null
, continue to the next entry in language value. - item must be a string,
otherwise an
invalid language map value
error has been detected and processing is aborted. - Initialize a new map v
consisting of two
key-value pairs: (
@value
-item) and (@language
-language). If item is neither@none
nor well-formed according to section 2.2.9 of [BCP47], processors SHOULD issue a warning.NoteProcessors MAY normalize language tags to lower case. - If language is
@none
, or expands to@none
, remove@language
from v. -
If direction is not
null
, add an entry for@direction
to v with direction. - Append v to expanded value.
- If item is
- Otherwise, if container mapping
includes
@index
,@type
, or@id
and value is a map then value is expanded from an map as follows:- Initialize expanded value to an empty array.
- Initialize index key to
the key's index mapping in active context,
or
@index
, if it does not exist. - For each key-value pair index-index value
in value, ordered lexicographically by index
if
isordered
true
:- If container mapping includes
@id
or@type
, initialize map context to the previous context from active context if it exists, otherwise, set map context to active context. - If container mapping includes
@type
and index's term definition in map context has a local context, update map context to the result of the Context Processing algorithm, passing map context as active context the value of the index's local context as local context and base URL from the term definition for index in map context. - Otherwise, set map context to active context.
- Initialize expanded index to the result of IRI expanding index.
- If index value is not an array set index value to an array containing only index value.
- Initialize index value to the result of
using this algorithm recursively, passing
map context as active context,
key as active property,
index value as element,
base URL,
true
for from map, and the
andframeExpansion
flags.ordered
- For each item in index value:
- If container mapping includes
@graph
, and item is not a graph object, set item to a new map containing the key-value pair@graph
-item, ensuring that the value is represented using an array. - If container mapping includes
@index
, index key is not@index
, and expanded index is not@none
:- Initialize re-expanded index to the result of calling the Value Expansion algorithm, passing the active context, index key as active property, and index as value.
- Initialize expanded index key to the result of IRI expanding index key.
- Initialize index property values to an array consisting of re-expanded index followed by the existing values of the concatenation of expanded index key in item, if any.
- Add the key-value pair (expanded index key-index property values) to item.
- If item is a value object,
it MUST NOT contain any extra properties;
an
invalid value object
error has been detected and processing is aborted.
- Otherwise, if container mapping includes
@index
, item does not have an entry@index
, and expanded index is not@none
, add the key-value pair (@index
-index) to item. - Otherwise, if container mapping includes
@id
item does not have the entry@id
, and expanded index is not@none
, add the key-value pair (@id
-expanded index) to item, where expanded index is set to the result of IRI expandingindex usingtrue
for document relative andfalse
for vocab. - Otherwise, if container mapping includes
@type
and expanded index is not@none
, initialize types to a new array consisting of expanded index followed by any existing values of@type
in item. Add the key-value pair (@type
-types) to item. - Append item to expanded value.
- If container mapping includes
- If container mapping includes
- Otherwise, initialize expanded value to the result of
using this algorithm recursively, passing active context,
key for active property, value for element,
base URL,
and the
andframeExpansion
flags.ordered
- If expanded value is
null
, ignore key by continuing to the next key from element. - If container mapping includes
@list
and expanded value is not already a list object, convert expanded value to a list object by first setting it to an array containing only expanded value if it is not already an array, and then by setting it to a map containing the key-value pair@list
-expanded value. - If container mapping includes
@graph
, and includes neither@id
nor@index
, convert expanded value into an array, if necessary, then convert each value ev in expanded value into a graph object:- Convert ev into
a graph object by creating a map containing the key-value
pair
@graph
-ev where ev is represented as an array.NoteThis may lead to a graph object including another graph object, if ev was already in the form of a graph object.
- Convert ev into
a graph object by creating a map containing the key-value
pair
- If the term definition associated to
key indicates that it is a reverse property
- If result has no
@reverse
entry, create one and initialize its value to an empty map. - Reference the value of the
@reverse
entry in result using the variable reverse map. - If expanded value is not an array, set it to an array containing expanded value.
- For each item in expanded value
- If item is a value object or list object, an
invalid reverse property value
has been detected and processing is aborted. - If reverse map has no expanded property entry, create one and initialize its value to an empty array.
- Use add value to add item
to the expanded property entry in reverse map
using
true
for as array.
- If item is a value object or list object, an
- If result has no
- Otherwise, key is not a reverse property
use add value to add expanded value
to the expanded property entry in result
using
true
for as array.
- If key is
- For each key nesting-key in nests,
ordered lexicographically if
isordered
true
:- Initialize nested values to the value of nesting-key in element, ensuring that it is an array.
- For each nested value in nested values:
- If nested value is not a map, or any key within
nested value expands to
@value
, aninvalid @nest value
error has been detected and processing is aborted. - Recursively repeat steps 13 and 14 using nested value for element.
- If nested value is not a map, or any key within
nested value expands to
- If result contains the entry
@value
:- The result must not contain any entries other than
@direction
,@index
,@language
,@type
, and@value
. It must not contain an@type
entry if it contains either@language
or@direction
entries. Otherwise, aninvalid value object
error has been detected and processing is aborted. - If the result's
@type
entry is@json
, then the@value
entry may contain any value, and is treated as a JSON literal. - Otherwise, if the value of result's
@value
entry isnull
, or an empty array, returnnull
. - Otherwise, if the value of result's
@value
entry is not a string and result contains the entry@language
, aninvalid language-tagged value
error has been detected (only strings can be language-tagged) and processing is aborted. - Otherwise, if the result has an
@type
entry and its value is not an IRI, aninvalid typed value
error has been detected and processing is aborted.
- The result must not contain any entries other than
- Otherwise, if result contains the entry
@type
and its associated value is not an array, set it to an array containing only the associated value. - Otherwise, if result contains the entry
@set
or@list
:- The result must contain at most one other entry
which must be
@index
. Otherwise, aninvalid set or list object
error has been detected and processing is aborted. - If result contains the entry
@set
, then set result to the entry's associated value.
- The result must contain at most one other entry
which must be
- If result is a map that contains only the entry
@language
, returnnull
. - If active property is
null
or@graph
, drop free-floating values as follows: - Return result.
5.2 IRI Expansion
In JSON-LD documents, some keys and values may represent IRIs. This section defines an algorithm for transforming a string that represents an IRI into an absolute IRI or blank node identifier. It also covers transforming keyword aliases into keywords.
IRI expansion may occur during context processing or during any of the other JSON-LD algorithms. If IRI expansion occurs during context processing, then the local context and its related defined map from the Context Processing algorithm are passed to this algorithm. This allows for term definition dependencies to be processed via the Create Term Definition algorithm.
5.2.1 Overview
This section is non-normative.
In order to expand value to an IRI, we must
first determine if it is null
, a term, a
keyword alias, or some form of IRI. Based on what
we find, we handle the specific kind of expansion; for example, we expand
a keyword alias to a keyword and a term
to an IRI according to its IRI mapping
in the active context. While inspecting value we
may also find that we need to create term definition
dependencies because we're running this algorithm during context processing.
We can tell whether or not we're running during context processing by
checking local context against null
.
We know we need to create a term definition in the
active context when value is
an entry in the local context and the defined map
does not have an entry for value with an associated value of
true
. The defined map is used during
Context Processing to keep track of
which terms have already been defined or are
in the process of being defined. We create a
term definition by using the
Create Term Definition algorithm.
Values that have the form of a keyword,
but are not keywords (i.e., they begin with "@"
) do not
map to any value, as they are reserved for future use.
The algorithm returns null
, so that they will be ignored when encountered.
5.2.2 Algorithm
The algorithm takes two required and four optional input variables. The
required inputs are an active context and a value
to be expanded. The optional inputs are two flags,
document relative and vocab, that specifying
whether value can be interpreted as a relative IRI reference
against the document's base IRI or the
active context's
vocabulary mapping, respectively, and
a local context and a map defined to be used when
this algorithm is used during Context Processing.
If not passed, the two flags are set to false
and
local context and defined are initialized to null
.
- If value is a keyword or
null
, return value as is. -
If value has the form of a keyword
(i.e., it matches the ABNF rule
"@"1*ALPHA
from [RFC5234]), a processor SHOULD generate a warning and returnnull
. - If local context is not
null
, it contains an entry with a key that equals value, and the value of the entry for value in defined is nottrue
, invoke the Create Term Definition algorithm, passing active context, local context, value as term, and defined. This will ensure that a term definition is created for value in active context during Context Processing. - If active context has a term definition for value, and the associated IRI mapping is a keyword, return that keyword.
- If vocab is
true
and the active context has a term definition for value, return the associated IRI mapping. - If value contains a colon (
:
) anywhere after the first character, it is either an IRI, a compact IRI, or a blank node identifier:- Split value into a prefix and suffix
at the first occurrence of a colon (
:
). - If prefix is underscore (
_
) or suffix begins with double-forward-slash (//
), return value as it is already an IRI or a blank node identifier. - If local context is not
null
, it contains a prefix entry, and the value of the prefix entry in defined is nottrue
, invoke the Create Term Definition algorithm, passing active context, local context, prefix as term, and defined. This will ensure that a term definition is created for prefix in active context during Context Processing. - If active context contains a term definition
for prefix
having a non-
null
IRI mapping and the prefix flag of the term definition istrue
, return the result of concatenating the IRI mapping associated with prefix and suffix. - If value has the form of an IRI, return value.
- Split value into a prefix and suffix
at the first occurrence of a colon (
- If vocab is
true
, and active context has a vocabulary mapping, return the result of concatenating the vocabulary mapping with value. - Otherwise, if document relative is
true
set value to the result of resolving value against the base IRI from active context. Only the basic algorithm in section 5.2 of [RFC3986] is used; neither Syntax-Based Normalization nor Scheme-Based Normalization are performed. Characters additionally allowed in IRI references are treated in the same way that unreserved characters are treated in URI references, per section 6.5 of [RFC3987]. - Return value as is.
5.3 Value Expansion
Some values in JSON-LD can be expressed in a compact form. These values are required to be expanded at times when processing JSON-LD documents. A value is said to be in expanded form after the application of this algorithm.
5.3.1 Overview
This section is non-normative.
If active property has a type mapping in the
active context set to @id
or @vocab
,
and the value is a string,
a map with a single entry @id
whose
value is the result of using the
IRI Expansion algorithm on value
is returned.
Otherwise, the result will be a map containing
an @value
entry whose value is the passed value.
Additionally, an @type
entry will be included if there is a
type mapping associated with the active property
or an @language
entry if value is a
string and there is language mapping associated
with the active property.
Note that values interpreted as IRIs fall into two categories:
those that are document relative, and those that are
vocabulary relative. Properties and values of @type
,
along with terms marked as "@type": "@vocab"
are vocabulary relative, meaning that they need to be either
a defined term, a compact IRI
where the prefix is a term,
or a string which is turned into an IRI using
the vocabulary mapping.
5.3.2 Algorithm
The algorithm takes three required inputs: an active context, an active property, and a value to expand.
- If the active property has a type mapping
in active context that is
@id
, and the value is a string, return a new map containing a single entry where the key is@id
and the value is the result IRI expanding value usingtrue
for document relative andfalse
for vocab. - If active property has a type mapping in
active context that is
@vocab
, and the value is a string, return a new map containing a single entry where the key is@id
and the value is the result of IRI expanding value usingtrue
for document relative. - Otherwise, initialize result to a map
with an
@value
entry whose value is set to value. - If active property has a type mapping in
active context,
other than
@id
,@vocab
, or@none
, add@type
to result and set its value to the value associated with the type mapping. - Otherwise, if value is a string:
- Initialize language to the language mapping for active property in active context, if any, otherwise to the default language of active context.
- Initialize direction to the direction mapping for active property in active context, if any, otherwise to the default base direction of active context.
- If language is not
null
, add@language
to result with the value language. - If direction is not
null
, add@direction
to result with the value direction.
- Return result.
6. Compaction Algorithms
The following sections describe algorithms for compacting JSON-LD documents, IRIs and values.
6.1 Compaction Algorithm
This algorithm compacts a JSON-LD document, such that the given context is applied. This must result in shortening any applicable IRIs to terms or compact IRIs, any applicable keywords to keyword aliases, and any applicable JSON-LD values expressed in expanded form to simple values such as strings or numbers.
6.1.1 Overview
This section is non-normative.
Starting with its root element, we can process the JSON-LD document recursively, until we have a fully compacted result. When compacting an element, we can treat each one differently according to its type, in order to break down the problem:
- If the element is a scalar, it is already in compacted form, so we simply return it.
- If the element is an array, we compact each of its items recursively and return them in a new array.
- Otherwise element is a map. The value
of each entry in element is compacted recursively. Some of the entry keys will be
compacted, using the IRI Compaction algorithm,
to terms or compact IRIs
and others will be compacted from keywords to
keyword aliases or simply left
unchanged because they do not have definitions in the context.
Values will be converted to compacted form via the
Value Compaction algorithm. Some data
will be reshaped based on container mapping
specified in the context such as
@index
or@language
maps.
6.1.2 Algorithm
The algorithm takes three required and two optional input variables.
The required inputs are an active context,
an active property,
and an element to be compacted.
The optional inputs are the
flag
and the compactArrays
flag, used to order
map entry keys lexicographically, where noted.
If not passed, both flags are set to ordered
false
.
- Initialize type-scoped context to active context. This is used for compacting values that may be relevant to any previous type-scoped context.
- If element is a scalar, it is already in its most compact form, so simply return element.
- If element is an array:
- Initialize result to an empty array.
- For each item in element:
- Initialize compacted item to the result of using this
algorithm recursively, passing active context,
active property,
item for element,
and the
andcompactArrays
flags.ordered
- If compacted item is not
null
, then append it to result.
- Initialize compacted item to the result of using this
algorithm recursively, passing active context,
active property,
item for element,
and the
- If result is empty or contains more than one value,
or
iscompactArrays
false
, or active property is either@graph
or@set
, or container mapping for active property in active context includes either@list
or@set
, return result. - Otherwise, return the value in result.
- Otherwise element is a map.
- If active context has a previous context,
the active context is not propagated.
If element does not contain an
@value
entry, and element does not consist of a single@id
entry, set active context to previous context from active context, as the scope of a term-scoped context does not apply when processing new node objects. - If the term definition for active property in active context
has a local context:
- Set active context to the result of the
Context Processing algorithm,
passing active context,
the value of the active property's local context as local context,
base URL from the term definition for active property
in active context,
and
true
for override protected.
- Set active context to the result of the
Context Processing algorithm,
passing active context,
the value of the active property's local context as local context,
base URL from the term definition for active property
in active context,
and
- If element has an
@value
or@id
entry and the result of using the Value Compaction algorithm, passing active context, active property, and element as value is a scalar, or the term definition for active property has a type mapping of@json
, return that result. - If element is a
list object, and the container mapping for
active property in active context includes
@list
, return the result of using this algorithm recursively, passing active context, active property, value of@list
in element for element, and the
andcompactArrays
flags.ordered
- Initialize inside reverse to
true
if active property equals@reverse
, otherwise tofalse
. - Initialize result to an empty map.
- If element has an
@type
entry, create a new array compacted types initialized by transforming each expanded type of that entry into its compacted form by IRI compacting expanded type. Then, for each term in compacted types ordered lexicographically:- If the term definition for term in type-scoped context has a
local context
set active context to the result of the
Context Processing algorithm,
passing active context and the value of term's
local context in type-scoped context as local context
base URL from the term definition for term
in type-scoped context,
and
false
for propagate.
- If the term definition for term in type-scoped context has a
local context
set active context to the result of the
Context Processing algorithm,
passing active context and the value of term's
local context in type-scoped context as local context
base URL from the term definition for term
in type-scoped context,
and
- For each key expanded property and value expanded value
in element, ordered lexicographically by expanded property
if
isordered
true
:- If expanded property is
@id
:- If expanded value is a string,
then initialize compacted value
by IRI compacting expanded value
with vocab set to
false
. - Initialize alias by IRI compacting expanded property.
- Add an entry alias to result whose value is set to compacted value and continue to the next expanded property.
- If expanded value is a string,
then initialize compacted value
by IRI compacting expanded value
with vocab set to
- If expanded property is
@type
:- If expanded value is a string, then initialize compacted value by IRI compacting expanded value using type-scoped context for active context.
- Otherwise, expanded value must be a
@type
array:- Initialize compacted value to an empty array.
- For each item expanded type in
expanded value:
- Set term by IRI compacting expanded type using type-scoped context for active context.
- Append term, to compacted value.
- Initialize alias by IRI compacting expanded property.
- Initialize as array
to
true
if processing mode isjson-ld-1.1
and the container mapping for alias in the active context includes@set
, otherwise to the negation of
.compactArrays
- Use add value to add compacted value to the alias entry in result using as array.
- Continue to the next expanded property.
- If expanded property is
@reverse
:- Initialize compacted value to the result of using this
algorithm recursively, passing active context,
@reverse
for active property, expanded value for element, and the
andcompactArrays
flags.ordered
- For each property and value in compacted value:
- If the term definition for property in the
active context indicates that property is
a reverse property
- Initialize as array
to
true
if the container mapping for property in the active context includes@set
, otherwise the negation of
.compactArrays
- Use add value to add value to the property entry in result using as array.
- Remove the property entry from compacted value.
- Initialize as array
to
- If the term definition for property in the
active context indicates that property is
a reverse property
- If compacted value has some remaining map entries, i.e.,
it is not an empty map:
- Initialize alias
by IRI compacting
@reverse
. - Set the value of the alias entry of result to compacted value.
- Initialize alias
by IRI compacting
- Continue with the next expanded property from element.
- Initialize compacted value to the result of using this
algorithm recursively, passing active context,
- If expanded property is
@preserve
then:- Initialize compacted value to the result of using this
algorithm recursively, passing
active context,
active property,
expanded value for element,
and the
andcompactArrays
flags.ordered
- Add compacted value as the value of
@preserve
in result unless expanded value is an empty array.
- Initialize compacted value to the result of using this
algorithm recursively, passing
active context,
active property,
expanded value for element,
and the
- If expanded property is
@index
and active property has a container mapping in active context that includes@index
, then the compacted result will be inside of an@index
container, drop the@index
entry by continuing to the next expanded property. - Otherwise, if expanded property is
@direction
,@index
,@language
, or@value
:- Initialize alias by IRI compacting expanded property.
- Add an entry alias to result whose value is set to expanded value and continue with the next expanded property.
- If expanded value is an empty array:
- Initialize item active property by IRI compacting expanded property using expanded value for value and inside reverse for reverse.
- If the term definition for item active property
in the active context has a nest value
entry (nest term):
- If nest term is not
@nest
, or a term in the active context that expands to@nest
, aninvalid @nest value
error has been detected, and processing is aborted. - If result does not have a nest term entry, initialize it to an empty map.
- Initialize nest result to the value of nest term in result.
- If nest term is not
- Otherwise, initialize nest result to result.
- Use add value to add an empty array
to the item active property entry in nest result
using
true
for as array.
-
At this point, expanded value must be an
array due to the
Expansion algorithm.
For each item expanded item in expanded value:
- Initialize item active property by IRI compacting expanded property using expanded item for value and inside reverse for reverse.
- If the term definition for item active property
in the active context has a nest value
entry (nest term):
- If nest term is not
@nest
, or a term in the active context that expands to@nest
, aninvalid @nest value
error has been detected, and processing is aborted. - If result does not have a nest term entry, initialize it to an empty map.
- Initialize nest result to the value of nest term in result.
- If nest term is not
- Otherwise, initialize nest result to result.
- Initialize container to container mapping for item active property in active context, or to a new empty array, if there is no such container mapping.
- Initialize as array
to
true
if container includes@set
, or if item active property is@graph
or@list
, otherwise the negation of
.compactArrays
- Initialize compacted item to the result of using
this algorithm recursively, passing
active context,
item active property for active property,
expanded item for element,
along with the
andcompactArrays
flags. If expanded item is a list object or a graph object, use the value of theordered
@list
or@graph
entries, respectively, for element instead of expanded item. - If expanded item is a list object:
- If compacted item is not an array, then set compacted item to an array containing only compacted item.
- If container does not include
@list
:- Convert compacted item to a
list object by setting it to a
map containing an entry
where the key is the result of
IRI compacting
@list
and the value is the original compacted item. - If expanded item contains the entry
@index
-value, then add an entry to compacted item where the key is the result of IRI compacting@index
and value is value. - Use add value to add compacted item to the item active property entry in nest result using as array.
- Convert compacted item to a
list object by setting it to a
map containing an entry
where the key is the result of
IRI compacting
- Otherwise, set the value of the item active property entry in nest result to compacted item.
- If expanded item is a graph object:
- If container includes
@graph
and@id
:- Initialize map object to the value of item active property in nest result, initializing it to a new empty map, if necessary.
- Initialize map key
by IRI compacting
the value of
@id
in expanded item or@none
if no such value exists with vocab set tofalse
if there is an@id
entry in expanded item. - Use add value to add compacted item to the map key entry in map object using as array.
- Otherwise, if container includes
@graph
and@index
and expanded item is a simple graph object:- Initialize map object to the value of item active property in nest result, initializing it to a new empty map, if necessary.
- Initialize map key the value of
@index
in expanded item or@none
, if no such value exists. - Use add value to add compacted item to the map key entry in map object using as array.
- Otherwise, if container includes
@graph
and expanded item is a simple graph object the value cannot be represented as a map object.- If compacted item is an array
with more than one value, it cannot be directly represented,
as multiple objects would be interpreted as different named graphs.
Set compacted item to a new map,
containing the key
from IRI compacting
@included
and the original compacted item as the value. - Use add value to add compacted item to the item active property entry in nest result using as array.
- If compacted item is an array
with more than one value, it cannot be directly represented,
as multiple objects would be interpreted as different named graphs.
Set compacted item to a new map,
containing the key
from IRI compacting
- Otherwise, container does not include
@graph
or otherwise does not match one of the previous cases.- Set compacted item to a new map containing
the key
from IRI compacting
@graph
using the original compacted item as a value. - If expanded item contains an
@id
entry, add an entry in compacted item using the key from IRI compacting@id
using the value of IRI compacting the value of@id
in expanded item usingfalse
for vocab. - If expanded item contains an
@index
entry, add an entry in compacted item using the key from IRI compacting@index
and the value of@index
in expanded item. - Use add value to add compacted item to the item active property entry in nest result using as array.
- Set compacted item to a new map containing
the key
from IRI compacting
- If container includes
-
Otherwise, if container includes
@language
,@index
,@id
, or@type
and container does not include@graph
:- Initialize map object to the value of item active property in nest result, initializing it to a new empty map, if necessary.
- Initialize container key
by IRI compacting
either
@language
,@index
,@id
, or@type
based on the contents of container. - Initialize index key to the value of index mapping in
the term definition associated with item active property in active context,
or
@index
, if no such value exists. - If container includes
@language
and expanded item contains a@value
entry, then set compacted item to the value associated with its@value
entry. Set map key to the value of@language
in expanded item, if any. - Otherwise, if container includes
@index
and index key is@index
, set map key to the value of@index
in expanded item, if any. - Otherwise, if container includes
@index
and index key is not@index
:- Reinitialize container key by IRI compacting index key.
- Set map key to the first value of container key in compacted item, if any.
- If there are remaining values in compacted item for container key, use add value to add those remaining values to the container key in compacted item. Otherwise, remove that entry from compacted item.
- Otherwise, if container includes
@id
, set map key to the value of container key in compacted item and remove container key from compacted item. - Otherwise, if container includes
@type
:- Set map key to the first value of container key in compacted item, if any.
- If there are remaining values in compacted item for container key, use add value to add those remaining values to the container key in compacted item.
- Otherwise, remove that entry from compacted item.
- If compacted item contains a single entry with a key expanding
to
@id
, set compacted item to the result of using this algorithm recursively, passing active context, item active property for active property, and a map composed of the single entry for@id
from expanded item for element.
- If map key is
null
, set it to the result of IRI compacting@none
. - Use add value to add compacted item to the map key entry in map object using as array.
- Otherwise, use add value to add compacted item to the item active property entry in nest result using as array.
- If expanded property is
- Return result.
6.2 IRI Compaction
This algorithm compacts an IRI to a term or compact IRI, or a keyword to a keyword alias. A value that is associated with the IRI may be passed in order to assist in selecting the most context-appropriate term.
6.2.1 Overview
This section is non-normative.
If the passed IRI is null
,
we simply return null
.
Otherwise, we first try to find a term that the IRI or keyword
can be compacted to if it is relative to
active context's vocabulary mapping.
In order to select the most appropriate term,
we may have to collect information about the passed value.
This information includes determining the preferred container mapping,
type mapping or language mapping
for expressing the value.
For JSON-LD lists, the type mapping
or language mapping will be chosen based on the most
specific values that work for all items in the list.
Once this information is gathered,
it is passed to the Term Selection algorithm,
which will return the most appropriate term.
If no term was found that could be used to compact the IRI,
an attempt is made to compact the IRI
using the active context's vocabulary mapping,
if there is one.
If the IRI could not be compacted,
an attempt is made to find a compact IRI.
A term will be used to create a compact IRI
only if the term definition contains the prefix flag
with the value true
.
If there is no appropriate compact IRI,
and the compactToRelative
option is true
,
the IRI is transformed to a relative IRI reference
using the document's base IRI.
Finally, if the IRI or keyword still could not be compacted,
it is returned as is.
When considering language mapping, the direction mapping is also considered, either with, or without, a language mapping, and the language mapping is normalized to lower case.
In the case were this algorithm would return the input IRI as is, and that IRI can be mistaken for a compact IRI in the active context, this algorithm will raise an error, because it has no way to return an unambiguous representation of the original IRI.
6.2.2 Algorithm
This algorithm takes two required inputs and three optional inputs.
The required inputs are an active context,
and the var to be compacted.
The optional inputs are a value associated with the var,
a vocab flag which specifies whether the passed var
should be compacted using the active context's vocabulary mapping,
and a reverse flag which specifies whether a reverse property is being compacted.
If not passed, value is set to null
and both vocab and reverse are both set to false
.
- If var is
null
, returnnull
. - If the active context has a
null
inverse context, set inverse context in active context to the result of calling the Inverse Context Creation algorithm using active context. - Initialize inverse context to the value of inverse context in active context.
- If vocab is
true
and var is an entry of inverse context:- Initialize default language
based on the active context's
default language, normalized to lower case and default base direction:
- If the active context's default base direction
is not
null
, to the concatenation of the active context's default language and default base direction, separated by an underscore ("_"
), normalized to lower case. - Otherwise, to the active context's default language,
if it has one,
normalized to lower case,
otherwise to
@none
.
- If the active context's default base direction
is not
- If value is a map containing an
@preserve
entry, use the first element from the value of@preserve
as value. - Initialize containers to an empty array. This
array will be used to keep track of an ordered list of
preferred container mapping for a term,
based on what is compatible with value.
NoteAlgorithm steps may append the same value to containers, but the order in which they are added is significant for choosing the most appropriate term.
- Initialize type/language to
@language
, and type/language value to@null
. These two variables will keep track of the preferred type mapping or language mapping for a term, based on what is compatible with value. - If value is a map containing an
@index
entry, and value is not a graph object then append the values@index
and@index@set
to containers. - If reverse is
true
, set type/language to@type
, type/language value to@reverse
, and append@set
to containers. - Otherwise, if value is a list object, then set
type/language and type/language value
to the most specific values that work for all items in
the list as follows:
- If
@index
is not an entry in value, then append@list
to containers. - Initialize list to the array associated
with the
@list
entry in value. - Initialize common type and common language to
null
. If list is empty, set common language to default language. - For each item in list:
- Initialize item language to
@none
and item type to@none
. - If item contains an
@value
entry:- If item contains an
@direction
entry, then set item language to the concatenation of the item's@language
entry (if any) the item's@direction
, separated by an underscore ("_"
), normalized to lower case. - Otherwise, if item contains an
@language
entry, then set item language to its associated value, normalized to lower case. - Otherwise, if item contains a
@type
entry, set item type to its associated value. - Otherwise, set item language to
@null
.
- If item contains an
- Otherwise, set item type to
@id
. - If common language is
null
, set common language to item language. - Otherwise, if item language does not equal
common language and item contains a
@value
entry, then set common language to@none
because list items have conflicting languages. - If common type is
null
, set common type to item type. - Otherwise, if item type does not equal
common type, then set common type
to
@none
because list items have conflicting types. - If common language is
@none
and common type is@none
, then stop processing items in the list because it has been detected that there is no common language or type amongst the items.
- Initialize item language to
- If common language is
null
, set common language to@none
. - If common type is
null
, set common type to@none
. - If common type is not
@none
then set type/language to@type
and type/language value to common type. - Otherwise, set type/language value to common language.
- If
- Otherwise, if value is a graph object,
prefer a mapping most appropriate for the particular value.
- If value contains an
@index
entry, append the values@graph@index
and@graph@index@set
to containers. - If value contains an
@id
entry, append the values@graph@id
and@graph@id@set
to containers. - Append the values
@graph
@graph@set
, and@set
to containers. - If value does not contain an
@index
entry, append the values@graph@index
and@graph@index@set
to containers. - If the value does not contain an
@id
entry, append the values@graph@id
and@graph@id@set
to containers. - Append the values
@index
and@index@set
to containers. - Set type/language to
@type
and set type/language value to@id
.
- If value contains an
- Otherwise:
- If value is a value object:
- If value contains an
@direction
entry and does not contain an@index
entry, then set type/language value to the concatenation of the value's@language
entry (if any) and the value's@direction
entry, separated by an underscore ("_"
), normalized to lower case. Append@language
and@language@set
to containers. - Otherwise, if value contains an
@language
entry and does not contain an@index
entry, then set type/language value to the value of@language
normalized to lower case, and append@language
, and@language@set
to containers. - Otherwise, if value contains an
@type
entry, then set type/language value to its associated value and set type/language to@type
.
- If value contains an
- Otherwise, set type/language to
@type
and set type/language value to@id
, and append@id
,@id@set
,@type
, and@set@type
, to containers. - Append
@set
to containers.
- If value is a value object:
- Append
@none
to containers. This represents the non-existence of a container mapping, and it will be the last container mapping value to be checked as it is the most generic. -
If processing mode is not
json-ld-1.0
and value is not a map or does not contain an@index
entry, append@index
and@index@set
to containers. -
If processing mode is not
json-ld-1.0
and value is a map containing only an@value
entry, append@language
and@language@set
to containers. - If type/language value is
null
, set type/language value to@null
. This is the key under whichnull
values are stored in the inverse context entry. - Initialize preferred values to an empty array. This array will indicate, in order, the preferred values for a term's type mapping or language mapping.
- If type/language value is
@reverse
, append@reverse
to preferred values. - If type/language value is
@id
or@reverse
and value is a map containing an@id
entry:- If the result of
IRI compacting
the value of the
@id
entry in value has a term definition in the active context with an IRI mapping that equals the value of the@id
entry in value, then append@vocab
,@id
, and@none
, in that order, to preferred values. - Otherwise, append
@id
,@vocab
, and@none
, in that order, to preferred values.
- If the result of
IRI compacting
the value of the
- Otherwise, append type/language value and
@none
, in that order, to preferred values. If value is a list object with an empty array as the value of@list
, set type/language to@any
. - Append
@any
to preferred values. - If preferred values
contains any entry having an underscore (
"_"
), append the substring of that entry from the underscore to the end of the string to preferred values. - Initialize term to the result of the Term Selection algorithm, passing var, containers, type/language, and preferred values.
- If term is not
null
, return term.
- Initialize default language
based on the active context's
default language, normalized to lower case and default base direction:
- At this point, there is no simple term that var
can be compacted to. If vocab is
true
and active context has a vocabulary mapping:- If var begins with the vocabulary mapping's value but is longer, then initialize suffix to the substring of var that does not match. If suffix does not have a term definition in active context, then return suffix.
- The var could not be compacted using the
active context's vocabulary mapping.
Try to create a compact IRI, starting by initializing
compact IRI to
null
. This variable will be used to store the created compact IRI, if any. - For each term definition definition in active context:
- If the IRI mapping of definition is
null
, its IRI mapping equals var, its IRI mapping is not a substring at the beginning of var, or definition does not have atrue
prefix flag, definition's key cannot be used as a prefix. Continue with the next definition. - Initialize candidate by concatenating definition key,
a colon (
:
), and the substring of var that follows after the value of the definition's IRI mapping. - If either compact IRI is
null
, candidate is shorter or the same length but lexicographically less than compact IRI and candidate does not have a term definition in active context, or if that term definition has an IRI mapping that equals var and value isnull
, set compact IRI to candidate.
- If the IRI mapping of definition is
- If compact IRI is not
null
, return compact IRI. - To ensure that the IRI var is
not confused with a compact IRI,
if the IRI scheme of var
matches any term in active context with prefix flag set to
true
, and var has no IRI authority (preceded by double-forward-slash (//
), anIRI confused with prefix
error has been detected, and processing is aborted. - If vocab is
false
, transform var to a relative IRI reference using the base IRI from active context, if it exists. - Finally, return var as is.
6.3 Value Compaction
Expansion transforms all values into expanded form in JSON-LD. This algorithm performs the opposite operation, transforming a value into compacted form. This algorithm compacts a value according to the term definition in the given active context that is associated with the value's associated active property.
6.3.1 Overview
This section is non-normative.
The value to compact has either an @id
or an
@value
entry.
For the former case, if the type mapping of
active property is set to @id
or @vocab
and value consists of only an @id
entry and, if
the container mapping of active property
includes @index
, an @index
entry, value
can be compacted to a string by returning the result of
using the IRI Compaction algorithm
to compact the value associated with the @id
entry.
Otherwise, value cannot be compacted and is returned as is.
For the latter case, it might be possible to compact value
just into the value associated with the @value
entry.
This can be done if the active property has a matching
type mapping or language mapping and there
is either no @index
entry or the container mapping
of active property includes @index
. It can
also be done if @value
is the only entry in value
(apart an @index
entry in case the container mapping
of active property includes @index
) and
either its associated value is not a string, there is
no default language, or there is an explicit
null
language mapping for the
active property.
6.3.2 Algorithm
This algorithm has three required inputs: an active context, an active property, and a value to be compacted.
- Initialize result to a copy of value.
- If the active context has a
null
inverse context, set inverse context in active context to the result of calling the Inverse Context Creation algorithm using active context. - Initialize inverse context to the value of inverse context in active context.
- Initialize language to the language mapping for active property in active context, if any, otherwise to the default language of active context.
- Initialize direction to the direction mapping for active property in active context, if any, otherwise to the default base direction of active context.
- If value has an
@id
entry and has no other entries other than@index
:- If the type mapping of active property
is set to
@id
, set result to the result of IRI compacting the value associated with the@id
entry usingfalse
for vocab. - Otherwise, if the type mapping of active property
is set to
@vocab
, set result to the result of IRI compacting the value associated with the@id
entry.
- If the type mapping of active property
is set to
- Otherwise, if value has an
@type
entry whose value matches the type mapping of active property, set result to the value associated with the@value
entry of value. - Otherwise, if the type mapping of active property is
@none
, or value has an@type
entry, and the value of@type
in value does not match the type mapping of active property, leave value as is, as value compaction is disabled.- Replace any value of
@type
in result with the result of IRI compacting the value of the@type
entry.
- Replace any value of
- Otherwise, if the value of the
@value
entry is not a string:- If value has an
@index
entry, and the container mapping associated to active property includes@index
, or if value has no@index
entry, set result to the value associated with the@value
entry.
- If value has an
- Otherwise, if value has an
@language
entry whose value exactly matches language, using a case-insensitive comparison if it is notnull
, or is not present, if language isnull
, and the value has an@direction
entry whose value exactly matches direction, if it is notnull
, or is not present, if direction isnull
:- If value has an
@index
entry, and the container mapping associated to active property includes@index
, or value has no@index
entry, set result to the value associated with the@value
entry.
- If value has an
- If result is a map, replace each key in result with the result of IRI compacting that key.
- Return result.
7. Flattening Algorithms
The following sections describe algorithms for flattening JSON-LD documents, creating node maps, and generating blank nodes.
7.1 Flattening Algorithm
This algorithm flattens an expanded JSON-LD document by collecting all properties of a node in a single map and labeling all blank nodes with blank node identifiers. This resulting uniform shape of the document, may drastically simplify the code required to process JSON-LD data in certain applications.
7.1.1 Overview
This section is non-normative.
First, a node map is generated using the Node Map Generation algorithm which collects all properties of a node in a single map. In the next step, the node map is converted to a JSON-LD document in flattened document form.
7.1.2 Algorithm
The algorithm takes one required and one optional input variables.
The required input is an element to flatten.
The optional input is
the
flag, used to order
map entry keys lexicographically, where noted.
If not passed, the ordered
flag is set to ordered
false
.
This algorithm uses the Generate Blank Node Identifier algorithm to generate new blank node identifiers and relabel existing blank node identifiers. The Generate Blank Node Identifier algorithm maintains an identifier map to ensure that blank node identifiers in the source document are consistently remapped to new blank node identifiers avoiding collisions. Thus, before this algorithm is run, the identifier map is reset.
- Initialize node map to a map consisting of
a single entry whose key is
@default
and whose value is an empty map. - Perform the Node Map Generation algorithm, passing element and node map.
- Initialize default graph to the value of the
@default
entry of node map, which is a map representing the default graph. - For each key-value pair graph name-graph in node map
where graph name is not
@default
, ordered lexicographically by graph name if
isordered
true
, perform the following steps:- If default graph does not have a graph name entry, create
one and initialize its value to a map consisting of an
@id
entry whose value is set to graph name. - Reference the value associated with the graph name entry in default graph using the variable entry.
- Add an
@graph
entry to entry and set it to an empty array. - For each id-node pair in graph ordered lexicographically by id
if
isordered
true
, add node to the@graph
entry of entry, unless the only entry of node is@id
.
- If default graph does not have a graph name entry, create
one and initialize its value to a map consisting of an
- Initialize an empty array flattened.
- For each id-node pair in default graph ordered lexicographically by id
if
isordered
true
, add node to flattened, unless the only entry of node is@id
. - Return flattened.
7.2 Node Map Generation
This algorithm creates a map node map holding an indexed
representation of the graphs and nodes
represented in the passed expanded document. All nodes that are not
uniquely identified by an IRI get assigned a (new) blank node identifier.
The resulting node map will have an map entry for every graph in the document whose
value is another object with an entry for every node represented in the document.
The default graph is stored under the @default
entry, all other graphs are
stored under their graph name.
7.2.1 Overview
This section is non-normative.
The algorithm recursively runs over an expanded JSON-LD document to
collect all entries of a node
in a single map. The algorithm updates a
map node map whose keys represent the
graph names used in the document
(the default graph is stored under the @default
entry)
and whose associated values are maps
which index the nodes in the
graph. If a
entry's value is a node object,
it is replaced by a node object consisting of only an
@id
entry. If a node object has no @id
entry or it is identified by a blank node identifier,
a new blank node identifier is generated. This relabeling
of blank node identifiers is
also done for properties and values of
@type
.
7.2.2 Algorithm
The algorithm takes as input an expanded JSON-LD document element and a reference to
a map node map. Furthermore it has the optional parameters
active graph (which defaults to @default
), an active subject,
active property, and a reference to a map list. If
not passed, active subject, active property, and list are
set to null
.
- If element is an array, process each item in element
as follows and then return:
- Run this algorithm recursively by passing item for element, node map, active graph, active subject, active property, and list.
- Otherwise element is a map. Reference the
map which is the value of the active graph
entry of node map using the variable graph. If the
active subject is
null
, set node tonull
otherwise reference the active subject entry of graph using the variable subject node. - For each item in the
@type
entry of element, if any, or for the value of@type
, if the value of@type
exists and is not an array:- If item is a blank node identifier, replace it with a newly generated blank node identifier passing item for identifier.
- If element has an
@value
entry, perform the following steps:- If list is
null
:- If subject node does not have an active property entry, create one and initialize its value to an array containing element.
- Otherwise, compare element against every item in the array associated with the active property entry of subject node. If there is no item equivalent to element, append element to the array. Two maps are considered equal if they have equivalent map entries.
- Otherwise, append element to the
@list
entry of list.
- If list is
- Otherwise, if element has an
@list
entry, perform the following steps:- Initialize a new map result consisting of a single entry
@list
whose value is initialized to an empty array. - Recursively call this algorithm passing the value of element's
@list
entry for element, node map, active graph, active subject, active property, and result for list. - If list is
null
, append result to the value of the active property entry of subject node. - Otherwise, append result to the
@list
entry of list.
- Initialize a new map result consisting of a single entry
- Otherwise element is a node object, perform
the following steps:
- If element has an
@id
entry, set id to its value and remove the entry from element. If id is a blank node identifier, replace it with a newly generated blank node identifier passing id for identifier. - Otherwise, set id to the result of the
Generate Blank Node Identifier algorithm
passing
null
for identifier. - If graph does not contain an entry id, create one and initialize
its value to a map consisting of a single entry
@id
whose value is id. - Reference the value of the id entry of graph using the variable node.
- If active subject is a map, a reverse property relationship
is being processed. Perform the following steps:
- If node does not have a active property entry, create one and initialize its value to an array containing active subject.
- Otherwise, compare active subject against every item in the array associated with the active property entry of node. If there is no item equivalent to active subject, append active subject to the array. Two maps are considered equal if they have equivalent map entries.
- Otherwise, if active property is not
null
, perform the following steps:- Create a new map reference consisting of a single entry
@id
whose value is id. - If list is
null
:- If subject node does not have an active property entry, create one and initialize its value to an array containing reference.
- Otherwise, compare reference against every item in the array associated with the active property entry of subject node. If there is no item equivalent to reference, append reference to the array. Two maps are considered equal if they have equivalent map entries.
- Otherwise, append reference to the
@list
entry of list.
- Create a new map reference consisting of a single entry
- If element has an
@type
entry, append each item of its associated array to the array associated with the@type
entry of node unless it is already in that array. Finally remove the@type
entry from element. - If element has an
@index
entry, set the@index
entry of node to its value. If node already has an@index
entry with a different value, aconflicting indexes
error has been detected and processing is aborted. Otherwise, continue by removing the@index
entry from element. - If element has an
@reverse
entry:- Create a map referenced node with a single entry
@id
whose value is id. - Initialize reverse map to the value of the
@reverse
entry of element. - For each key-value pair property-values in reverse map:
- For each value of values:
- Recursively invoke this algorithm passing value for element, node map, active graph, referenced node for active subject, and property for active property. Passing a map for active subject indicates to the algorithm that a reverse property relationship is being processed.
- For each value of values:
- Remove the
@reverse
entry from element.
- Create a map referenced node with a single entry
- If element has an
@graph
entry, recursively invoke this algorithm passing the value of the@graph
entry for element, node map, and id for active graph before removing the@graph
entry from element. - If element has an
@included
entry, recursively invoke this algorithm passing the value of the@included
entry for element, node map, and active graph before removing the@included
entry from element. - Finally, for each key-value pair property-value in element ordered by
property perform the following steps:
- If property is a blank node identifier, replace it with a newly
generated blank node identifier
passing property for identifier.
NoteThe use of blank node identifiers to label properties is obsolete, and may be removed in a future version of JSON-LD.
- If node does not have a property entry, create one and initialize its value to an empty array.
- Recursively invoke this algorithm passing value for element, node map, active graph, id for active subject, and property for active property.
- If property is a blank node identifier, replace it with a newly
generated blank node identifier
passing property for identifier.
- If element has an
7.3 Merge Node Maps
This algorithm creates a new map of subjects to nodes using all graphs contained in the graph map created using the Node Map Generation algorithm to create merged node objects containing information defined for a given subject in each graph contained in the node map.
- Create result as an empty map
- For each graph name and node map in graph map and for each id and node in node map:
- Return result.
7.4 Generate Blank Node Identifier
This algorithm is used to generate new blank node identifiers or to relabel an existing blank node identifier to avoid collision by the introduction of new ones.
7.4.1 Overview
This section is non-normative.
The simplest case is if there exists already a blank node identifier
in the identifier map for the passed identifier, in which
case it is simply returned. Otherwise, a new blank node identifier
is generated. If the passed identifier is not null
,
an entry is created in the identifier map associating the
identifier with the blank node identifier.
7.4.2 Algorithm
The algorithm takes a single input variable identifier which may
be null
. The algorithm
maintains an identifier map to relabel existing
blank node identifiers to new blank node identifiers,
which is reset when the invoking algorithm is initialized.
- If identifier is not
null
and has an entry in the identifier map, return the mapped identifier. - Otherwise, generate a new unique blank node identifier.
- If identifier is not
null
, create a new entry for identifier in identifier map and set its value to the new blank node identifier. - Return the new blank node identifier.
One way of generating new blank node identifiers is to maintain a counter
and increment it when generating a new identifier and appending it to
a string such as _:b
.
8. RDF Serialization/Deserialization Algorithms
This section describes algorithms to deserialize a JSON-LD document to an RDF dataset and vice versa. The algorithms are designed for in-memory implementations with random access to map elements.
8.1 Deserialize JSON-LD to RDF Algorithm
This algorithm deserializes a JSON-LD document to an RDF dataset. Please note that RDF does not allow a blank node to be used as a property, while JSON-LD does. Therefore, by default triples that would have contained blank nodes as properties are discarded when interpreting JSON-LD as RDF.
The use of blank node identifiers to label properties is obsolete, and may be removed in a future version of JSON-LD.
If the
option is not rdfDirection
null
, then special processing is used to
convert from an i18n-datatype
or compound-literal
form.
Implementations MUST generate only well-formed triples and graph names:
- An IRI is well-formed if it matches the ABNF for IRI as described in [RFC3987].
- A blank node identifier is well-formed if it matches the
EBNF for
BLANK_NODE_LABEL as described in [Turtle].
NoteWhen following the algorithm described here, all blank node identifiers will be normalized using the Generate Blank Node Identifier algorithm and automatically adhere to this form.
- A literal is well-formed if it has the lexical form of a string, any datatype IRI is well-formed, and any language tag is well-formed according to section 2.2.9 of [BCP47].
8.1.1 Overview
This section is non-normative.
The JSON-LD document is expanded and converted to a node map using the
Node Map Generation algorithm.
This allows each graph represented within the document to be
extracted and flattened, making it easier to process each
node object.
Each graph from the node map is processed to extract triple,
to which any (non-default) graph name is applied to create an RDF dataset.
Each node object in the node map has an @id
entry
which corresponds to the subject,
the other entries represent predicates.
Each entry value is either an IRI or blank node identifier
or can be transformed to anRDF literal
to generate an triple.
Lists are transformed into an RDF collection
using the List to RDF Conversion algorithm.
8.1.2 Algorithm
The algorithm takes a map node map, which
is the result of the Node Map Generation algorithm and
an RDF dataset dataset into which new graphs and triples are added.
It also takes two optional input variables
and produceGeneralizedRdf
.
Unless the rdfDirection
option
is set to produceGeneralizedRdf
true
, triple
containing a blank node predicate
are excluded from output.
The use of blank node identifiers to label properties is obsolete,
and may be removed in a future version of JSON-LD,
as is the support for generalized RDF Datasets
and thus the
option may be also be removed.produceGeneralizedRdf
- For each graph name and graph in node map
ordered by graph name:
- If graph name is not well-formed, continue with the next graph name-graph pair.
- If graph name is
@default
, initialize triples to the value of thedefaultGraph
attribute of dataset. Otherwise, initialize triples as an emptyRdfGraph
and add to dataset using its
method along with graph name foradd
graphName
. - For each subject and node in graph ordered
by subject:
- If subject is not well-formed, continue with the next subject-node pair.
- For each property and values in node
ordered by property:
- If property is
@type
, then for each type in values, create a newRdfTriple
composed of subject,rdf:type
forpredicate
, and type forobject
and add to triples using its
method, unless type is not well-formed.add
- Otherwise, if property is a keyword continue with the next property-values pair.
- Otherwise, if property is a blank node identifier and
the
option is notproduceGeneralizedRdf
true
, continue with the next property-values pair.NoteThe use of blank node identifiers to label properties is obsolete, and may be removed in a future version of JSON-LD, as is the support for generalized RDF Datasets and thus the
option may be also be removed.produceGeneralizedRdf
- Otherwise, if property is not well-formed, continue with the next property-values pair.
- Otherwise, property is an IRI or
blank node identifier. For each item
in values:
- Initialize list triples as an empty array.
Note
- Add a triple
composed of subject, property, and
the result of using the
Object to RDF Conversion algorithm
passing item
and list triples
to triples using its
method, unless the result isadd
null
, indicating a non-well-formed resource that has to be ignored. - Add all
RdfTriple
instances from list triples to triples using its
method.add
- Initialize list triples as an empty array.
- If property is
8.2 Object to RDF Conversion
This algorithm takes a node object, list object, or value object
and transforms it into an resource to be used as the object of an triple.
If a node object containing a relative IRI reference is passed to
the algorithm, null
is returned which then causes the resulting
triple to be ignored.
If the input is a list object, it will also
return the triples created from that input.
8.2.1 Overview
This section is non-normative.
Value objects are transformed to
RDF literals as described in
§ 8.6 Data Round Tripping
whereas node objects are transformed
to IRIs,
blank node identifiers,
or null
.
8.2.2 Algorithm
The algorithm takes as two arguments item which MUST be either a value object, list object, or node object and list triples, which is an empty array.
- If item is a node object and the value of
its
@id
entry is not well-formed, returnnull
. - If item is a node object, return the
IRI or blank node identifier associated
with its
@id
entry. - If item is a list object
return the result of the
List Conversion algorithm, passing
the value associated with the
@list
entry from item and list triples. - Otherwise, item is a value object. Initialize
value to the value associated with the
@value
entry in item. - Initialize datatype to the value associated with the
@type
entry of item ornull
if item does not have such an entry. - If datatype is not
null
and neither a well-formed IRI nor@json
, returnnull
. - If item has an
@language
entry which is not well-formed, returnnull
. - If datatype is
@json
, convert value to the canonical lexical form using the result of transforming the internal representation of value to JSON and set datatype tordf:JSON
.IssueThe JSON Canonicalization Scheme (JCS) [RFC8785] is an emerging standard for JSON canonicalization. This specification will likely be updated to require such a canonical representation. Users are cautioned from depending on the JSON literal lexical representation as an RDF literal, as the specifics of serialization may change in a future revision of this document. - If value is
true
orfalse
, set value to the stringtrue
orfalse
which is the canonical lexical form as described in § 8.6 Data Round Tripping If datatype isnull
, set datatype toxsd:boolean
. - Otherwise, if value is a number with a non-zero fractional
part (the result of a modulo‑1 operation)
or an absolute value greater or equal to 1021,
or value is a number
and datatype equals
xsd:double
, convert value to a string in canonical lexical form of anxsd:double
as defined in [XMLSCHEMA11-2] and described in § 8.6 Data Round Tripping. If datatype isnull
, set datatype toxsd:double
. - Otherwise, if value is a number,
convert it to a string in canonical lexical form of
an
xsd:integer
as defined in [XMLSCHEMA11-2] and described in § 8.6 Data Round Tripping. If datatype isnull
, set datatype toxsd:integer
.NoteIt follows from the previous step that value has no non-zero fractional part. - Otherwise, if datatype is
null
, set datatype toxsd:string
orrdf:langString
, depending on if item has an@language
entry. - If item contains an
@direction
entry and
is notrdfDirection
null
, item is a value object which is serialized using special rules.-
Initialize language to the value of
@language
in item normalized to lower case, or the empty string ("carview.php?tsp="
) if there is no such entry.NoteGenerally, language tags are not normalized, but when creating ani18n-datatype
orcompound-literal
values are normalized to lower case for improved interoperability. - If
isrdfDirection
i18n-datatype
, set datatype to the result of appending language and the value of@direction
in item separated by an underscore ("_"
) tohttps://www.w3.org/ns/i18n#
. Initialize literal as an RDF literal using value and datatype.NoteProcessors MAY normalize language tags to lower case.NoteAs@direction
may be used without@language
, it is possible, and legitimate, to create a datatype IRI such ashttps://w3.org/ns/i18n#_ltr
, which does not encode a language tag. - Otherwise, if
isrdfDirection
compound-literal
:- Initialize literal as a new blank node.
- Create a new triple using literal as the subject,
rdf:value
as the predicate, and the value of@value
in item as the object, and add it to list triples. - If the item has an entry for
@language
, create a new triple using literal as the subject,rdf:language
as the predicate, and language as the object, and add it to list triples. - Create a new triple using literal as the subject,
rdf:direction
as the predicate, and the value of@direction
in item as the object, and add it to list triples.
-
Initialize language to the value of
- Otherwise, initialize literal as an RDF literal using
value and datatype. If item has an
@language
entry, add the value associated with the@language
entry as the language tag of literal. - Return literal.
8.3 List to RDF Conversion
List Conversion is the process of taking a list object and transforming it into an RDF collection as defined in RDF Semantics [RDF11-MT].
8.3.1 Overview
This section is non-normative.
For each element of the list a new blank node identifier
is allocated which is used to generate rdf:first
and
rdf:rest
. The
algorithm returns the list head, which is either the first allocated
blank node identifier or rdf:nil
if the
list is empty. If a list element represents an IRI,
the corresponding rdf:first
triple is omitted.
8.3.2 Algorithm
The algorithm takes two inputs: an array list and an empty array list triples used for returning the generated triples.
- If list is empty, return
rdf:nil
. - Otherwise, create an array bnodes composed of a newly generated blank node identifier for each entry in list.
- For each pair of subject from bnodes and item from list:
- Initialize embedded triples to a new empty array.
- Initialize object to the result of using the Object to RDF Conversion algorithm passing item and embedded triples for list triples.
- Unless object is
null
, append a triple composed of subject,rdf:first
, and object to list triples. - Initialize rest as the next entry in bnodes, or if that
does not exist,
rdf:nil
. Append a triple composed of subject,rdf:rest
, and rest to list triples. - Append all values from embedded triples to list triples
- Return the first blank node from bnodes or
rdf:nil
if bnodes is empty.
8.4 Serialize RDF as JSON-LD Algorithm
This algorithm serializes an RDF dataset consisting of a default graph and zero or more named graphs into a JSON-LD document.
In the RDF abstract syntax, RDF literals have a lexical form, as defined in [RDF11-CONCEPTS]. The form of these literals is used when creating JSON-LD values based on these literals.
8.4.1 Overview
This section is non-normative.
Iterate through each graph in the dataset, converting each
RDF collection into a list
and generating a JSON-LD document in expanded form for all
RDF literals, IRIs
and blank node identifiers.
If the useNativeTypes
flag is set to true
,
RDF literals with a
datatype IRI
that equals xsd:integer
or xsd:double
are converted
to a JSON numbers and RDF literals
with a datatype IRI
that equals xsd:boolean
are converted to true
or
false
based on their
lexical form
as described in
§ 8.6 Data Round Tripping.
Unless the useRdfType
flag is set to true, rdf:type
predicates will be serialized as @type
as long as the associated object is
either an IRI or blank node identifier.
If the
option is not rdfDirection
null
, then special processing is used to
convert from an i18n-datatype
or compound-literal
form.
8.4.2 Algorithm
The algorithm takes one required and four optional inputs:
an RDF dataset dataset
and the four optional arguments are
the
flag, defaulting to ordered
false
, used to order
map entry keys lexicographically, where noted,
defaulting to rdfDirection
null
,
the useNativeTypes
flag, defaulting to false
,
and the useRdfType
flag, defaulting to false
.
The dataset is iterable
to iterate over graphs and graph names
contained within the RdfDataset
. Each graph is also iterable
for iterating over triples contained within the RdfGraph
.
- Initialize default graph to an empty map.
- Initialize graph map to a map consisting
of a single entry
@default
whose value references default graph. - Initialize referenced once to an empty map.
- Initialize compound literal subjects to an empty map.
- For each graph in dataset:
- If graph is the default graph,
initialize name to
@default
, otherwise to the graph name associated with graph. - If graph map has no name entry, create one and set its value to an empty map.
- If compound literal subjects has no name entry, create one and set its value to an empty map.
- If graph is not the default graph and
default graph does not have a name entry,
create such an entry and initialize its value to a new
map with a single entry
@id
whose value is name. - Reference the value of the name entry in graph map using the variable node map.
- Reference the value of the name entry in compound literal subjects using the variable compound map.
- For each triple in graph
consisting of subject, predicate, and object:
- 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. - Reference the value of the subject entry in node map using the variable node.
- If the
option isrdfDirection
compound-literal
and predicate isrdf:direction
, add an entry in compound map for subject with the valuetrue
. - If object is an IRI or blank node identifier,
and node map does not have an object entry,
create one and initialize its value to a new map
consisting of a single entry
@id
whose value is set to object. - If predicate equals
rdf:type
, theuseRdfType
flag is nottrue
, and object is an IRI or blank node identifier, append object to the value of the@type
entry of node; unless such an item already exists. If no such entry exists, create one and initialize it to an array whose only item is object. Finally, continue to the next triple. - Initialize value to the result of using the
RDF to Object Conversion algorithm,
passing object,
, andrdfDirection
useNativeTypes
. - If node does not have a predicate entry, create one and initialize its value to an empty array.
- If there is no item equivalent to value in the array associated with the predicate entry of node, append a reference to value to the array. Two maps are considered equal if they have equivalent map entries.
- If object is
rdf:nil
, it represents the termination of an RDF collection: - Otherwise, if referenced once has an entry for object,
set the object entry of referenced once to
false
. - Otherwise, if object is a blank node identifier, it might represent a list node:
- If node map does not have a subject entry,
create one and initialize its value to a new map
consisting of a single entry
- If graph is the default graph,
initialize name to
- For each name and graph object in graph map:
- If compound literal subjects
has an entry for name, then for each cl
which is a key in that entry:
- Initialize cl entry to the value of cl in referenced once, continuing to the next cl if cl entry is not a map.
- Initialize node to the value of
node
in cl entry. - Initialize property to value of
property
in cl entry. - Initialize value to value of
value
in cl entry. - Initialize cl node to the value of cl in graph object, and remove that entry from graph object, continuing to the next cl if cl node is not a map.
- For each cl reference in the value of property in node
where the value of
@id
in cl reference is cl:- Delete the
@id
entry in cl reference. - Add an entry to cl reference for
@value
with the value taken from therdf:value
entry in cl node. - Add an entry to cl reference for
@language
with the value taken from therdf:language
entry in cl node, if any. If that value is not well-formed according to section 2.2.9 of [BCP47], aninvalid language-tagged string
error has been detected and processing is aborted. - Add an entry to cl reference for
@direction
with the value taken from therdf:direction
entry in cl node, if any. If that value is not"ltr"
or"rtl"
, aninvalid base direction
error has been detected and processing is aborted.
- Delete the
- If graph object has no
rdf:nil
entry, continue with the next name-graph object pair as the graph does not contain any lists that need to be converted. - Initialize nil to the value of the
rdf:nil
entry of graph object. - For each item usage in the
usages
entry of nil, perform the following steps:- Initialize node to the value of the value of the
node
entry of usage, property to the value of theproperty
entry of usage, and head to the value of thevalue
entry of usage. - Initialize two empty arrays list and list nodes.
- While property equals
rdf:rest
, the value of the@id
entry of node is a blank node identifier, the value of the entry of referenced once associated with the@id
entry ofnode
is a map, node hasrdf:first
andrdf:rest
entries, both of which have as value an array consisting of a single element, and node has no other entries apart from an optional@type
entry whose value is an array with a single item equal tordf:List
, node represents a well-formed list node. Perform the following steps to traverse the list backwards towards its head:- Append the only item of
rdf:first
entry of node to the list array. - Append the value of the
@id
entry of node to the list nodes array. - Initialize node usage to the value of the entry of referenced once associated with the
@id
entry ofnode
. - Set node to the value of the
node
entry of node usage, property to the value of theproperty
entry of node usage, and head to the value of thevalue
entry of node usage. - If the
@id
entry of node is an IRI instead of a blank node identifier, exit the while loop.
- Append the only item of
- Remove the
@id
entry from head. - Reverse the order of the list array.
- Add an
@list
entry to head and initialize its value to the list array. - For each item node id in list nodes, remove the node id entry from graph object.
- Initialize node to the value of the value of the
- If compound literal subjects
has an entry for name, then for each cl
which is a key in that entry:
- Initialize an empty array result.
- For each subject and node in default graph
ordered lexicographically by subject
if
isordered
true
: - Return result.
8.5 RDF to Object Conversion
This algorithm transforms an RDF literal to a JSON-LD value object and a RDF blank node or IRI to an JSON-LD node object.
8.5.1 Overview
This section is non-normative.
RDF literals are transformed to value objects whereas IRIs and blank node identifiers are transformed to node objects.
Literals with datatype rdf:JSON
are transformed into a value object using the internal representation
based on the lexical-to-value mapping defined in
JSON datatype in [JSON-LD11],
and @type
of @json
.
With the
option set to rdfDirection
i18n-datatype
,
literals with datatype starting with https://www.w3.org/ns/i18n#
are transformed into a value object by decoding
the language tag and base direction from the datatype.
With the
option set to rdfDirection
compound-literal
,
blank node objects using rdf:direction
are
are transformed into a value object by decoding
the rdf:value
, rdf:language
, and rdf:direction
properties.
If the useNativeTypes
flag is set to true
,
RDF literals with a
datatype IRI
that equals xsd:integer
or xsd:double
are converted
to a JSON numbers and RDF literals
with a datatype IRI
that equals xsd:boolean
are converted to true
or
false
based on their
lexical form
as described in
§ 8.6 Data Round Tripping.
8.5.2 Algorithm
This algorithm takes three required inputs:
a value to be converted to a map,
,
and a flag rdfDirection
useNativeTypes
.
- If value is an IRI or a
blank node identifier, return a new map
consisting of a single entry
@id
whose value is set to value. - Otherwise value is an
RDF literal:
- Initialize a new empty map result.
- Initialize converted value to value.
- Initialize type to
null
- If
useNativeTypes
istrue
- If the
datatype IRI
of value equals
xsd:string
, set converted value to the lexical form of value. - Otherwise, if the
datatype IRI
of value equals
xsd:boolean
, set converted value totrue
if the lexical form of value matchestrue
, orfalse
if it matchesfalse
. If it matches neither, set type toxsd:boolean
. - Otherwise, if the
datatype IRI
of value equals
xsd:integer
orxsd:double
and its lexical form is a validxsd:integer
orxsd:double
according [XMLSCHEMA11-2], set converted value to the result of converting the lexical form to a JSON number.
- If the
datatype IRI
of value equals
- Otherwise, if processing mode is not
json-ld-1.0
, and value is a JSON literal, set converted value to the result of turning the lexical value of value into the JSON-LD internal representation, and set type to@json
. If the lexical value of value is not valid JSON according to the JSON Grammar [RFC8259], aninvalid JSON literal
error has been detected and processing is aborted. - Otherwise, if the datatype IRI of value starts with
https://www.w3.org/ns/i18n#
, and
isrdfDirection
i18n-datatype
:- Set converted value to the lexical form of value.
- If the string prefix of the fragment identifier
of the datatype IRI up until the underscore (
"_"
) is not empty, add an entry@language
to result and set its value to that prefix.NoteAs@direction
may be used without@language
, it is possible, and legitimate, to create a datatype IRI such ashttps://w3.org/ns/i18n#_ltr
, which does not encode a language tag. - Add an entry
@direction
to result and set its value to the substring of the fragment identifier following the underscore ("_"
).
- Otherwise, if value is a
language-tagged string
add an entry
@language
to result and set its value to the language tag of value. - Otherwise, set type to the
datatype IRI
of value, unless it equals
xsd:string
which is ignored. - Add an entry
@value
to result whose value is set to converted value. - If type is not
null
, add an entry@type
to result whose value is set to type. - Return result.
8.6 Data Round Tripping
When deserializing JSON-LD to RDF
JSON-native numbers are automatically
type-coerced to xsd:integer
or xsd:double
depending on whether the number has a non-zero fractional part
or not (the result of a modulo‑1 operation), the boolean values
true
and false
are coerced to xsd:boolean
,
and strings are coerced to xsd:string
.
The JSON, numeric, or boolean values themselves are converted to
canonical lexical form, i.e., a deterministic string
representation as defined in [XMLSCHEMA11-2].
The canonical lexical form of an integer, i.e., a
number with no non-zero fractional part
and an absolute value less than 1021,
or a number coerced to xsd:integer
,
is a finite-length sequence of decimal
digits (0-9
) with an optional leading minus sign; leading
zeros are prohibited. In JavaScript, implementers can use the following
snippet of code to convert an integer to
canonical lexical form:
(value).toFixed(0).toString()
The canonical lexical form of a double, i.e., a
number
with a non-zero fractional part or an absolute value greater or equal to 1021,
or a number
coerced to xsd:double
, consists of a mantissa followed by the
character E
, followed by an exponent. The mantissa is a
decimal number and the exponent is an integer. Leading zeros and a
preceding plus sign (+
) are prohibited in the exponent.
If the exponent is zero, it is indicated by E0
. For the
mantissa, the preceding optional plus sign is prohibited and the
decimal point is required. Leading and trailing zeros are prohibited
subject to the following: number representations must be normalized
such that there is a single digit which is non-zero to the left of
the decimal point and at least a single digit to the right of the
decimal point unless the value being represented is zero. The
canonical representation for zero is 0.0E0
.
xsd:double
's value space is defined by the IEEE
double-precision 64-bit floating point type [IEEE-754-2008] whereas
the value space of JSON numbers is not
specified; when deserializing JSON-LD to RDF the mantissa is rounded to
15 digits after the decimal point. In JavaScript, implementers
can use the following snippet of code to convert a double to
canonical lexical form:
(value).toExponential(15).replace(/(\d)0*e\+?/,'$1E')
The canonical lexical form of the boolean
values true
and false
are the strings
true
and false
.
The canonical lexical form of a JSON literal
is the result of serializing the internal representation
into the JSON format [RFC8259] in compliance with the constraints of the value space description within
The rdf:JSON
Datatype of [JSON-LD11].
When JSON-native numbers are deserialized
to RDF, lossless data round-tripping cannot be guaranteed, as rounding
errors might occur. When
serializing RDF as JSON-LD,
similar rounding errors might occur. Furthermore, the datatype or the lexical
representation might be lost. An xsd:double
with a value
of 2.0
will, e.g., result in an xsd:integer
with a value of 2
in canonical lexical form
when converted from RDF to JSON-LD and back to RDF. It is important
to highlight that in practice it might be impossible to losslessly
convert an xsd:integer
to a number because
its value space is not limited. While the JSON specification [RFC8259]
does not limit the value space of numbers
either, concrete implementations typically do have a limited value
space.
To ensure lossless round-tripping the
Serialize RDF as JSON-LD Algorithm
specifies a useNativeTypes
flag which controls whether
RDF literals
with a datatype IRI
equal to xsd:integer
, xsd:double
, or
xsd:boolean
are converted to their JSON-native
counterparts. If the useNativeTypes
flag is set to
false
, all literals remain in their original string
representation.
Some JSON serializers, such as PHP's native implementation in some versions,
backslash-escape the forward slash character. For example, the value
https://example.com/
would be serialized as http:\/\/example.com\/
.
This is problematic as other JSON parsers might not understand those escaping characters.
There is no need to backslash-escape forward slashes in JSON-LD. To aid
interoperability between JSON-LD processors, forward slashes MUST NOT be
backslash-escaped.
9. The Application Programming Interface
This API provides a clean mechanism that enables developers to convert JSON-LD data into a variety of output formats that are often easier to work with.
The JSON-LD API uses Promises to represent the result of the various deferred operations. Promises are defined in [ECMASCRIPT]. General use within specifications can be found in [promises-guide]. Implementations MAY chose to implement in an appropriate way for their native environments as long as they generally use the same methods, arguments, and options and return the same results.
Interfaces are marked [Exposed=JsonLd]
,
which creates a global interface.
The use of WebIDL in JSON-LD, while appropriate for use within browsers,
is not limited to such use.
9.1 The JsonLdProcessor
Interface
The JsonLdProcessor
interface is the high-level programming structure
that developers use to access the JSON-LD transformation methods.
It is important to highlight that implementations do not modify the input parameters.
If an error is detected, the Promise
is
rejected with a JsonLdError
having an appropriate
and processing is stopped.code
If the documentLoader
option is specified, it is used to dereference remote documents and contexts.
The
in the returned documentUrl
RemoteDocument
is used as base IRI and the
is used instead of looking at the HTTP Link Header directly. For the sake of simplicity, none of the algorithms
in this document mention this directly.contextUrl
WebIDL/* * The JsonLd interface is created to expose the JsonLdProcessor interface. */ [Global=JsonLd, Exposed=JsonLd
] interfaceJsonLd
{}; [Exposed=JsonLd
] interfaceJsonLdProcessor
{constructor
(); static Promise<JsonLdRecord
>compact
(JsonLdInput
input, optionalJsonLdContext
context = null, optionalJsonLdOptions
options = {}); static Promise<sequence<JsonLdRecord
>>expand
(JsonLdInput
input, optionalJsonLdOptions
options = {}); static Promise<JsonLdRecord
>flatten
(JsonLdInput
input, optionalJsonLdContext
context = null, optionalJsonLdOptions
options = {}); static Promise<sequence<JsonLdRecord
>>fromRdf
(RdfDataset
input, optionalJsonLdOptions
options = {}); static Promise<RdfDataset
>toRdf
(JsonLdInput
input, optionalJsonLdOptions
options = {}); };
compact()
-
Compacts the given input using the context according to the steps in the Compaction algorithm:
The final output is a map derived from compacted output. If compacted output is an array, it is included with an entry of (a possibly aliased)
@graph
with the value of compacted output, otherwise compacted output is used as the map result. If context notnull
, an@context
entry is added to the map result.- Create a new
Promise
promise and return it. The following steps are then deferred. - If the provided input
is a
RemoteDocument
, initialize remote document to input. - Otherwise, if the provided input
is a string representing the IRI of a remote document, await and dereference it as remote document
using
LoadDocumentCallback
, passing input for url, and the
option from options forextractAllScripts
extractAllScripts
. - Set expanded input to the result of
using the
expand()
method using either remote document or input if there is no remote document for input, and options, with
set toordered
false
, and
defaulting toextractAllScripts
false
. - Set context base to the
from remote document, if available, otherwise to thedocumentUrl
option from options.base
- If context is a map
having an
@context
entry, set context to that entry's value, otherwise to context. - Initialize active context to the result of the Context Processing algorithm passing a new empty context as active context context as local context, and context base as base URL.
- Set base IRI in active context to the
option from options, if set; otherwise, if thebase
compactToRelative
option is true, to the IRI of the currently being processed document, if available; otherwise tonull
. - Set compacted output to the result of using the Compaction algorithm,
using active context,
null
for active property, expanded input as element, and the
andcompactArrays
flags from options.ordered
- If compacted output is an empty array, replace it with a new map.
- Otherwise, if compacted output is an array,
replace it with a new map with a single entry
whose key is the result of
IRI compacting
@graph
and value is compacted output. - If context was not
null
, add an@context
entry to compacted output and set its value to the provided context.
- Resolve the promise with compacted output transforming compacted output from the internal representation to a JSON serialization.
- input
- The map, array of maps to perform the compaction upon, or an IRI referencing the JSON-LD document to compact.
- context
- The context to use when compacting the input; it can be specified by using a map, an IRI, or an array consisting of maps and IRIs.
- options
- A set of options to configure the algorithms.
This allows, e.g., to set the input document's base IRI.
The
type defines default option values.JsonLdOptions
- Create a new
expand()
-
Expands the given input according to the steps in the Expansion algorithm:
- Create a new
Promise
promise and return it. The following steps are then deferred. - If the provided input
is a
RemoteDocument
, initialize remote document to input. - Otherwise, if the provided input
is a string representing the IRI of a remote document, await and dereference it as remote document
using
LoadDocumentCallback
, passing input for url, the
option from options forextractAllScripts
extractAllScripts
. - If
from remote document is a string, transform into the internal representation. Ifdocument
cannot be transformed to the internal representation, reject promise passing adocument
loading document failed
error. - Initialize a new empty active context.
The base IRI and original base URL of the active context is set to the
from remote document, if available; otherwise to thedocumentUrl
option from options. If set, thebase
option from options overrides the base IRI.base
- If the
option in options is set, update the active context using the Context Processing algorithm, passing theexpandContext
as local context and the original base URL from active context as base URL. IfexpandContext
is a map having anexpandContext
@context
entry, pass that entry's value instead for local context. - If remote document has a
, update the active context using the Context Processing algorithm, passing thecontextUrl
as local context, andcontextUrl
as base URL.contextUrl
- Set expanded output to the result of using the Expansion algorithm,
passing the active context,
from remote document or input if there is no remote document as element,document
null
as active property,
as base URL, if available, otherwise to thedocumentUrl
option from options, and thebase
and andframeExpansion
flags from options.ordered
NoteIf there is no remote document, then input is aJsonLdRecord
or asequence
of JsonLdRecords, which are implicitly already in the internal representation. - Resolve the promise with expanded output transforming expanded output from the internal representation to a JSON serialization.
- input
- The map, or array of maps to perform the expansion upon, or an IRI referencing the JSON-LD document to expand.
- options
- A set of options to configure the used algorithms.
This allows, e.g., to set the input document's base IRI.
The
type defines default option values.JsonLdOptions
- Create a new
flatten()
-
Flattens the given input and optionally compacts it using the provided context according to the steps in the Flattening algorithm:
- Create a new
Promise
promise and return it. The following steps are then deferred. - If the provided input
is a
RemoteDocument
, initialize remote document to input. - Otherwise, if the provided input
is a string representing the IRI of a remote document, await and dereference it as remote document
using
LoadDocumentCallback
, passing input for url, and the
option from options forextractAllScripts
extractAllScripts
. - Set expanded input to the result of
using the
expand()
method using either remote document or input if there is no remote document for input, and options with
set toordered
false
. - Initialize an empty identifier map.
- Set flattened output to the result of using the Flattening algorithm,
passing expanded input as element,
and the
flag from options.ordered
- If context is not
null
, set flattened output to the result of using thecompact()
method using flattened output for input, context, and options. Set the base IRI in active context to the
option from options, if set; otherwise, if thebase
compactToRelative
option is true, to the IRI of the currently being processed document, if available; otherwise tonull
.
- If context is not
- Resolve the promise with flattened output transforming flattened output from the internal representation to a JSON serialization, if necessary.
- input
- The map, or array of maps, or an IRI referencing the JSON-LD document to flatten.
- context
- The context to use when compacting the flattened expanded input;
it can be specified by using a map,
an IRI, or an array consisting of maps
and IRIs.
If
null
, the result will not be compacted but kept in expanded form. - options
- A set of options to configure the used algorithms.
This allows, e.g., to set the input document's base IRI.
The
type defines default option values.JsonLdOptions
- Create a new
fromRdf()
-
Transforms the given input into a JSON-LD document in expanded form according to the steps in the Serialize RDF as JSON-LD Algorithm:
NoteThis interface does not define a means of creating an
RdfDataset
from an arbitrary input, other than thetoRdf()
method.- Create a new
Promise
promise and return it. The following steps are then deferred. - Set expanded result to the result of invoking the Serialize RDF as JSON-LD Algorithm method using dataset and options.
- Resolve the promise with expanded result transforming expanded result from the internal representation to a JSON serialization.
- input
- The map, or array of maps, or an IRI referencing the JSON-LD document to flatten.
- options
- A set of options to configure the used algorithms.
This allows, e.g., to set the input document's base IRI.
The
type defines default option values.JsonLdOptions
- Create a new
toRdf()
-
Transforms the given input into an
RdfDataset
according to the steps in the Deserialize JSON-LD to RDF Algorithm:- Create a new
Promise
promise and return it. The following steps are then deferred. - Set expanded input to the result of using the
expand()
method using input and options with
set toordered
false
. - Create a new
RdfDataset
dataset. - Create a new map node map.
- Invoke the Node Map Generation algorithm, passing expanded input as element and node map.
- Invoke the Deserialize JSON-LD to RDF Algorithm
passing node map, dataset,
and the
flag from options.produceGeneralizedRdf
NoteThe use of blank node identifiers to label properties is obsolete, and may be removed in a future version of JSON-LD, as is the support for generalized RDF Datasets and thus the
option may be also be removed.produceGeneralizedRdf
- Resolve the promise with dataset.
- input
- The map, or array of maps, or an IRI referencing the JSON-LD document to flatten.
- options
- A set of options to configure the used algorithms.
This allows, e.g., to set the input document's base IRI.
The
type defines default option values.JsonLdOptions
- Create a new
WebIDLtypedef record<USVString, any> JsonLdRecord
;
The JsonLdRecord
is the definition of a map
used to contain arbitrary map entries
which are the result of parsing a JSON Object.
WebIDLtypedef (JsonLdRecord
or sequence<JsonLdRecord
> or USVString orRemoteDocument
)JsonLdInput
;
The JsonLdInput
interface is used to refer to an input value
that that may be a JsonLdRecord
,
a sequence
of JsonLdRecords,
a string representing an IRI,
which can be dereferenced to retrieve a valid JSON document,
or an already dereferenced RemoteDocument
.
When the value is a JsonLdRecord
or sequence of JsonLdRecords,
the values are taken as their equivalent internal representation values,
where a JsonLdRecord
is equivalent to a map,
and a sequence of JsonLdRecords is equivalent to an array
of maps. The map entries are converted to their equivalents
in [INFRA].
WebIDLtypedef (JsonLdRecord
or sequence<(JsonLdRecord
or USVString)> or USVString)JsonLdContext
;
The JsonLdContext
interface is used to refer to a value
that may be a JsonLdRecord
,
a sequence
of JsonLdRecords,
or a string representing an IRI,
which can be dereferenced to retrieve a valid JSON document.
When the value is a JsonLdRecord
or sequence of JsonLdRecords,
the values are taken as their equivalent internal representation values,
where a JsonLdRecord
is equivalent to a map,
and a sequence of JsonLdRecords is equivalent to an array
of maps. The map entries are converted to their equivalents
in [INFRA].
9.2 RDF Dataset Interfaces
The RdfDataset
interface describes operations on an RDF dataset
used by the fromRdf()
and toRdf()
methods
in the JsonLdProcessor
interface.
The interface may be used for constructing a new RDF dataset,
which has a default graph accessible via the defaultGraph
attribute.
WebIDL[Exposed=JsonLd
] interfaceRdfDataset
{constructor
(); readonly attributeRdfGraph
defaultGraph
; voidadd
(USVString graphName,RdfGraph
graph); iterable<USVString?,RdfGraph
>; };
add()
-
Adds an
RdfGraph
and its associated graph name to theRdfDataset
. Used by the Deserialize JSON-LD to RDF Algorithm.- graphName
- The graph name associated with graph.
graphName
MUST be a well-formed IRI or blank node identifier. - graph
- The
RdfGraph
to add to theRdfDataset
.
defaultGraph
- Provides access to the default graph associated with the RDF dataset.
iterable
- The value pairs to iterate over
are the list of graph name-graph pairs,
with the graph name being
null
(for the default graph), an IRI, or blank node identifier and graph anRdfGraph
instance.
The RdfGraph
interface describes operations on an RDF graph used by the fromRdf()
and toRdf()
methods
in the JsonLdProcessor
interface.
The interface may be used for constructing a new RDF graph,
which is composed of zero or more RdfTriple
instances.
WebIDL[Exposed=JsonLd
] interfaceRdfGraph
{constructor
(); voidadd
(RdfTriple
triple); iterable<RdfTriple
>; };
add()
-
Adds an
RdfTriple
to theRdfGraph
. Used by the Deserialize JSON-LD to RDF Algorithm. iterable
- A value iterator
over the
RdfTriple
instances associated with the graph. Note that a givenRdfTriple
instance may appear in more than one graph within a particularRdfDataset
instance.
The RdfTriple
interface describes an triple.
WebIDL[Exposed=JsonLd
] interfaceRdfTriple
{constructor
(); readonly attribute USVStringsubject
; readonly attribute USVStringpredicate
; readonly attribute (USVString orRdfLiteral
)_object
; };
subject
- An absolute IRI or blank node identifier denoting the subject of the triple.
predicate
- An absolute IRI denoting the predicate of the triple.
If used to represent a Generalized RDF Dataset,
it may also be a blank node identifier.
NoteThe use of blank node identifiers to label properties is obsolete, and may be removed in a future version of JSON-LD, as is the support for generalized RDF Datasets.
object
- An absolute IRI, blank node identifier, or literal denoting the object of the triple.
The RdfLiteral
interface describes an RDF Literal.
WebIDL[Exposed=JsonLd
] interfaceRdfLiteral
{constructor
(); readonly attribute USVStringvalue
; readonly attribute USVStringdatatype
; readonly attribute USVString?language
; };
value
- The lexical value of the literal.
datatype
- An absolute IRI denoting the datatype IRI of the literal.
If the value is
rdf:langString
,language
MUST be specified. language
- An optional language tag as defined by [BCP47].
If this value is specified,
datatype
MUST berdf:langString
.
9.3 The JsonLdOptions Type
The JsonLdOptions
type is used to pass various options to the
JsonLdProcessor
methods.
WebIDLdictionaryJsonLdOptions
{ USVString?base
= null; booleancompactArrays
= true; booleancompactToRelative
= true;LoadDocumentCallback
?documentLoader
= null; (JsonLdRecord
? or USVString)expandContext
= null; booleanextractAllScripts
= false; booleanframeExpansion
= false; booleanordered
= false; USVStringprocessingMode
= "json-ld-1.1"; booleanproduceGeneralizedRdf
= true; USVString?rdfDirection
= null; booleanuseNativeTypes
= false; booleanuseRdfType
= false; };
base
- The base IRI to use when expanding or compacting the document. If set, this overrides the input document's IRI.
compactArrays
- If set to
true
, the JSON-LD processor replaces arrays with just one element with that element during compaction. If set tofalse
, all arrays will remain arrays even if they have just one element. compactToRelative
- Determines if IRIs are compacted
relative to the
option or document location when compacting.base
documentLoader
- The callback of the loader to be used to retrieve remote documents and contexts,
implementing the
LoadDocumentCallback
. If specified, it is used to retrieve remote documents and contexts; otherwise, if not specified, the processor's built-in loader is used. expandContext
- A context that is used to initialize the active context when expanding a document.
extractAllScripts
- If set to
true
, when extracting JSON-LD script elements from HTML, unless a specific fragment identifier is targeted, extracts all encountered JSON-LD script elements using an array form, if necessary. frameExpansion
- Enables special frame processing rules for the Expansion Algorithm.
- Enables special rules for the Serialize RDF as JSON-LD Algorithm to use JSON-LD native types as values, where possible.
ordered
- If set to
true
, certain algorithm processing steps where indicated are ordered lexicographically. Iffalse
, order is not considered in processing. processingMode
- Sets the processing mode.
If set to
json-ld-1.0
orjson-ld-1.1
, the implementation must produce exactly the same results as the algorithms defined in this specification. If set to another value, the JSON-LD processor is allowed to extend or modify the algorithms defined in this specification to enable application-specific optimizations. The definition of such optimizations is beyond the scope of this specification and thus not defined. Consequently, different implementations may implement different optimizations. Developers must not define modes beginning withjson-ld
as they are reserved for future versions of this specification. produceGeneralizedRdf
- If set to
true
, the JSON-LD processor may emit blank nodes for triple predicates, otherwise they will be omitted. Generalized RDF Datasets are defined in [RDF11-CONCEPTS].NoteThe use of blank node identifiers to label properties is obsolete, and may be removed in a future version of JSON-LD, as is the support for generalized RDF Datasets and thus the
option may be also be removed.produceGeneralizedRdf
rdfDirection
- Determines how value objects containing a base direction
are transformed to and from RDF.
- If set to
i18n-datatype
, an RDF literal is generated using a datatype IRI based onhttps://www.w3.org/ns/i18n#
with both the language tag (if present) and base direction encoded. When transforming from RDF, this datatype is decoded to create a value object containing@language
(if present) and@direction
. - If set to
compound-literal
, a blank node is emitted instead of a literal, where the blank node is the subject ofrdf:value
,rdf:direction
, andrdf:language
(if present) properties. When transforming from RDF, this object is decoded to create a value object containing@language
(if present) and@direction
.
- If set to
useNativeTypes
- Causes the Serialize RDF as JSON-LD Algorithm
to use native JSON values in value objects avoiding the need for an explicitly
@type
. useRdfType
- Enables special rules for the Serialize RDF as JSON-LD Algorithm
causing
rdf:type
properties to be kept as IRIs in the output, rather than use@type
.
9.4 Remote Document and Context Retrieval
Users of an API implementation can utilize a callback to control how remote documents and contexts are retrieved. This section details the parameters of that callback and the data structure used to return the retrieved context.
9.4.1 LoadDocumentCallback
The LoadDocumentCallback
defines a callback that custom document loaders
have to implement to be used to retrieve remote documents and contexts.
The callback returns a Promise
resolving to a RemoteDocument
.
On failure, the Promise
with a JsonLdError
having an appropriate error code
.
WebIDLcallbackLoadDocumentCallback
= Promise<RemoteDocument
> ( USVString url, optionalLoadDocumentOptions
? options );
- url
- The URL of the remote document or context to load.
- options
- A set of options to determine the behavior of the callback. See § 9.4.2 LoadDocumentOptions.
The following algorithm describes the default callback and places requirements on implementations of the callback.
- Create a new
Promise
promise and return it. The following steps are then deferred. - Set document to the body retrieved from
the resource identified by url,
or by otherwise locating a resource associated with url.
When requesting remote documents the request MUST prefer Content-Type
application/ld+json
followed byapplication/json
.If
requestProfile
is set, it MUST be added as a profile onapplication/ld+json
.Processors MAY include other media types using a
+json
suffix as defined in [RFC6839]. - Set documentUrl to the location of the retrieved resource
considering redirections (exclusive of HTTP status
303
"See Other" redirects as discussed in [cooluris]). - If the retrieved resource's Content-Type is not
application/json
nor any media type with a+json
suffix as defined in [RFC6839], and the response has an HTTP Link Header [RFC8288] using thealternate
link relation with typeapplication/ld+json
, set url to the associatedhref
relative to the previous url and restart the algorithm from step 2. - If the retrieved resource's Content-Type is
application/json
or any media type with a+json
suffix as defined in [RFC6839] exceptapplication/ld+json
, and the response has an HTTP Link Header [RFC8288] using thehttps://www.w3.org/ns/json-ld#context
link relation, set contextUrl to the associatedhref
.If multiple HTTP Link Headers using the
https://www.w3.org/ns/json-ld#context
link relation are found, the promise is rejected with aJsonLdError
whose
is set tocode
multiple context link headers
and processing is terminated.Processors MAY transform document to the internal representation.
NoteThe HTTP Link Header is ignored for documents served as
application/ld+json
,text/html
, orapplication/xhtml+xml
. - Otherwise, the retrieved document's Content-Type is neither
application/json
,application/ld+json
, nor any other media type using a+json
suffix as defined in [RFC6839]. Reject the promise passing aloading document failed
error. - Create a new
RemoteDocument
remote document using url as
, document asdocumentUrl
, the returned Content-Type (without parameters) asdocument
, any returnedcontentType
profile
parameter, ornull
as
, and contextUrl, orprofile
null
as
.contextUrl
- Resolve the promise with remote document.
A custom LoadDocumentCallback
set via the
documentLoader
option might be used
to maintain a local cache of well-known context documents or to implement
application-specific URL protocols.
9.4.2 LoadDocumentOptions
The LoadDocumentOptions
type is used to pass various options
to the LoadDocumentCallback
.
WebIDLdictionaryLoadDocumentOptions
{ booleanextractAllScripts
= false; USVStringprofile
= null; (USVString or sequence<USVString>)requestProfile
= null; };
extractAllScripts
- If set to
true
, when extracting JSON-LD script elements from HTML, unless a specific fragment identifier is targeted, extracts all encountered JSON-LD script elements using an array form, if necessary. profile
- When the resulting
iscontentType
text/html
orapplication/xhtml+xml
, this option determines the profile to use for selecting JSON-LD script elements. requestProfile
- One or more IRIs to use in the request as a
profile
parameter. (See IANA Considerations in [JSON-LD11]).
9.4.3 RemoteDocument
The RemoteDocument
type is used by a LoadDocumentCallback
to return information about a remote document or context.
WebIDL[Exposed=JsonLd
] interfaceRemoteDocument
{constructor
(); readonly attribute USVStringcontentType
; readonly attribute USVStringcontextUrl
; attribute anydocument
; readonly attribute USVStringdocumentUrl
; readonly attribute USVStringprofile
; };
contentType
- The Content-Type of the loaded document, exclusive of any optional parameters.
contextUrl
- If available, the value of the HTTP Link Header [RFC8288]
using the
https://www.w3.org/ns/json-ld#context
link relation in the response. If the response's Content-Type isapplication/ld+json
, the HTTP Link Header is ignored. If multiple HTTP Link Headers using thehttps://www.w3.org/ns/json-ld#context
link relation are found, thePromise
of theLoadDocumentCallback
is rejected with aJsonLdError
whose
is set tocode
multiple context link headers
. document
- The retrieved document. This can either be the raw payload or the already parsed document.
documentUrl
- The final URL of the loaded document. This is important to handle HTTP redirects properly.
profile
- The value of any
profile
parameter retrieved as part of the original
.contentType
9.5 HTML Content Algorithms
This section describes optional features available
with a documentLoader
supporting HTML script extraction.
Implementations of a documentLoader
MAY support extracting JSON-LD from
script elements contained within an HTML [HTML] document.
This section describes the normative behavior of such processors.
Such a processor supports HTML script extraction.
9.5.1 Process HTML
This sections describe an extension to the algorithm specified
in LoadDocumentCallback
to support extracting JSON-LD from HTML.
Step 2 is updated to add the following: A processor supporting HTML script extraction MUST include text/html
at any preference level
and MAY include application/xhtml+xml
at any preference level,
unless requestProfile
is https://www.w3.org/ns/json-ld#context
.
After step 5, add the following processing step:
Otherwise, if the retrieved resource's Content-Type is either text/html
or application/xhtml+xml
:
- Set documentUrl to the Document Base URL of url, as defined in [HTML], using the existing documentUrl as the document's URL.
- If the url parameter
contains a fragment identifier,
set source to the textContent
of the script element in document
having an id attribute
that matches the fragment identifier, after decoding percent encoded sequences.
If no such element is found, or the located element is not a JSON-LD script element, the promise is rejected with a
JsonLdError
whose
is set tocode
loading document failed
and processing is terminated. - Otherwise, if the
profile
option is specified, set source to the result of transforming the textContent of the first script element in document having an type attribute ofapplication/ld+json
along with the value of theprofile
option, if found. - If source is still undefined and the
extractAllScripts
option is not present, orfalse
, set source to the textContent of the first JSON-LD script element in document.If no such element is found, or the located element is not a JSON-LD script element, the promise is rejected with a
JsonLdError
whose
is set tocode
loading document failed
and processing is terminated. - If source is defined,
set document to the result of the
Extract Script Content algorithm,
using source, rejecting promise
with a
JsonLdError
whose code set from the result, if an error is detected and processing is terminated. - Otherwise, source is undefined.
- If the
extractAllScripts
option is not present, orfalse
, the promise is rejected with aJsonLdError
whose
is set tocode
loading document failed
and processing is terminated. - Otherwise, the
extractAllScripts
option istrue
. Set document to a new empty array. For each JSON-LD script element in input:- Set source to its textContent.
- Set script content to the result of the Extract Script Content algorithm,
using source, rejecting promise
with a
JsonLdError
whose code set from the result, if an error is detected and processing is terminated. - If script content is an array, merge it to the end of document.
- Otherwise, append script content to document.
- If the
9.5.2 Extract Script Content Algorithm
The algorithm extracts the text content a
JSON-LD script element into a map or array of maps.
A JSON-LD script element is a script element
within an HTML [HTML] document with the type attribute set to
application/ld+json
.
The algorithm takes a single required input variable: source, the textContent of an HTML script element.
- If source is not a valid JSON document,
an
invalid script element
has been detected, and processing is aborted. - Return the result of transforming source into the internal representation.
9.6 Error Handling
This section describes the datatype definitions used within the JSON-LD API for error handling.
9.6.1 JsonLdError
The JsonLdError
type is used to report processing errors.
WebIDLdictionaryJsonLdError
{JsonLdErrorCode
code
; USVString?message
= null; };
code
- A string representing the particular error type, as described in the various algorithms in this document.
message
- An optional error message containing additional debugging information. The specific contents of error messages are outside the scope of this specification.
9.6.2 JsonLdErrorCode
The JsonLdErrorCode
represents the collection of valid JSON-LD error codes.
WebIDLenumJsonLdErrorCode
{ "colliding keywords
", "conflicting indexes
", "context overflow
", "cyclic IRI mapping
", "invalid @id value
", "invalid @import value
", "invalid @included value
", "invalid @index value
", "invalid @nest value
", "invalid @prefix value
", "invalid @propagate value
", "invalid @protected value
", "invalid @reverse value
", "invalid @version value
", "invalid base direction
", "invalid base IRI
", "invalid container mapping
", "invalid context entry
", "invalid context nullification
", "invalid default language
", "invalid IRI mapping
", "invalid JSON literal
", "invalid keyword alias
", "invalid language map value
", "invalid language mapping
", "invalid language-tagged string
", "invalid language-tagged value
", "invalid local context
", "invalid remote context
", "invalid reverse property map
", "invalid reverse property value
", "invalid reverse property
", "invalid scoped context
", "invalid script element
", "invalid set or list object
", "invalid term definition
", "invalid type mapping
", "invalid type value
", "invalid typed value
", "invalid value object value
", "invalid value object
", "invalid vocab mapping
", "IRI confused with prefix
", "keyword redefinition
", "loading document failed
", "loading remote context failed
", "multiple context link headers
", "processing mode conflict
", "protected term redefinition
" };
colliding keywords
- Two properties which expand to the same keyword have been detected. This might occur if a keyword and an alias thereof are used at the same time.
conflicting indexes
- Multiple conflicting indexes have been found for the same node.
context overflow
- Maximum number of
@context
URLs exceeded. cyclic IRI mapping
- A cycle in IRI mappings has been detected.
invalid @id value
- An
@id
entry was encountered whose value was not a string. invalid @import value
- An invalid value for
@import
has been found. invalid @included value
- An included block contains an invalid value.
invalid @index value
- An
@index
entry was encountered whose value was not a string. invalid @nest value
- An invalid value for
@nest
has been found. invalid @prefix value
- An invalid value for
@prefix
has been found. invalid @propagate value
- An invalid value for
@propagate
has been found. invalid @protected value
- An invalid value for
@protected
has been found. invalid @reverse value
- An invalid value for an
@reverse
entry has been detected, i.e., the value was not a map. invalid @version value
- The
@version
entry was used in a context with an out of range value. invalid base direction
- The value of
@direction
is not"ltr"
,"rtl"
, ornull
and thus invalid. invalid base IRI
- An invalid base IRI has been detected, i.e.,
it is neither an IRI nor
null
. invalid container mapping
- An
@container
entry was encountered whose value was not one of the following strings:@list
,@set
,@language
,@index
,@id
,@graph
, or@type
. invalid context entry
- An entry in a context is invalid due to processing mode incompatibility.
invalid context nullification
- An attempt was made to nullify a context containing protected term definitions.
invalid default language
- The value of the default language is not a string
or
null
and thus invalid. invalid IRI mapping
- A local context contains a term that has an invalid or missing IRI mapping.
invalid JSON literal
- An invalid JSON literal was detected.
invalid keyword alias
- An invalid keyword alias definition has been encountered.
invalid language map value
- An invalid value in a language map has been detected. It MUST be a string or an array of strings.
invalid language mapping
- An
@language
entry in a term definition was encountered whose value was neither a string nornull
and thus invalid. invalid language-tagged string
- A language-tagged string with an invalid language value was detected.
invalid language-tagged value
- A number,
true
, orfalse
with an associated language tag was detected. invalid local context
- In invalid local context was detected.
invalid remote context
- No valid context document has been found for a referenced remote context.
invalid reverse property
- An invalid reverse property definition has been detected.
invalid reverse property map
- An invalid reverse property map has been detected.
No keywords apart from
@context
are allowed in reverse property maps. invalid reverse property value
- An invalid value for a reverse property has been detected. The value of an inverse property must be a node object.
invalid scoped context
- The local context defined within a term definition is invalid.
invalid script element
- A script element in HTML input which is the target of a fragment identifier does not have an appropriate type attribute.
invalid set or list object
- A set object or list object with disallowed entries has been detected.
invalid term definition
- An invalid term definition has been detected.
invalid type mapping
- An
@type
entry in a term definition was encountered whose value could not be expanded to an IRI. invalid type value
- An invalid value for an
@type
entry has been detected, i.e., the value was neither a string nor an array of strings. invalid typed value
- A typed value with an invalid type was detected.
invalid value object
- A value object with disallowed entries has been detected.
invalid value object value
- An invalid value for the
@value
entry of a value object has been detected, i.e., it is neither a scalar nornull
. invalid vocab mapping
- An invalid vocabulary mapping has been detected,
i.e., it is neither an IRI nor
null
. IRI confused with prefix
- When compacting an IRI would result in an IRI which could be confused with a compact IRI (because its IRI scheme matches a term definition and it has no IRI authority).
keyword redefinition
- A keyword redefinition has been detected.
loading document failed
- The document could not be loaded or parsed as JSON.
loading remote context failed
- There was a problem encountered loading a remote context.
multiple context link headers
- Multiple HTTP Link Headers [RFC8288]
using the
https://www.w3.org/ns/json-ld#context
link relation have been detected. processing mode conflict
- An attempt was made to change the processing mode which is incompatible with the previous specified version.
protected term redefinition
- An attempt was made to redefine a protected term.
10. Security Considerations
See, Security Considerations in [JSON-LD11].
11. Privacy Considerations
See, Privacy Considerations in [JSON-LD11].
12. Internationalization Considerations
See, Internationalization Considerations in [JSON-LD11].
A. IDL Index
This section is non-normative.
WebIDL/* * The JsonLd interface is created to expose the JsonLdProcessor interface. */ [Global=JsonLd, Exposed=JsonLd
] interfaceJsonLd
{}; [Exposed=JsonLd
] interfaceJsonLdProcessor
{constructor
(); static Promise<JsonLdRecord
>compact
(JsonLdInput
input, optionalJsonLdContext
context = null, optionalJsonLdOptions
options = {}); static Promise<sequence<JsonLdRecord
>>expand
(JsonLdInput
input, optionalJsonLdOptions
options = {}); static Promise<JsonLdRecord
>flatten
(JsonLdInput
input, optionalJsonLdContext
context = null, optionalJsonLdOptions
options = {}); static Promise<sequence<JsonLdRecord
>>fromRdf
(RdfDataset
input, optionalJsonLdOptions
options = {}); static Promise<RdfDataset
>toRdf
(JsonLdInput
input, optionalJsonLdOptions
options = {}); }; typedef record<USVString, any>JsonLdRecord
; typedef (JsonLdRecord
or sequence<JsonLdRecord
> or USVString orRemoteDocument
)JsonLdInput
; typedef (JsonLdRecord
or sequence<(JsonLdRecord
or USVString)> or USVString)JsonLdContext
; [Exposed=JsonLd
] interfaceRdfDataset
{constructor
(); readonly attributeRdfGraph
defaultGraph
; voidadd
(USVString graphName,RdfGraph
graph); iterable<USVString?,RdfGraph
>; }; [Exposed=JsonLd
] interfaceRdfGraph
{constructor
(); voidadd
(RdfTriple
triple); iterable<RdfTriple
>; }; [Exposed=JsonLd
] interfaceRdfTriple
{constructor
(); readonly attribute USVStringsubject
; readonly attribute USVStringpredicate
; readonly attribute (USVString orRdfLiteral
)_object
; }; [Exposed=JsonLd
] interfaceRdfLiteral
{constructor
(); readonly attribute USVStringvalue
; readonly attribute USVStringdatatype
; readonly attribute USVString?language
; }; dictionaryJsonLdOptions
{ USVString?base
= null; booleancompactArrays
= true; booleancompactToRelative
= true;LoadDocumentCallback
?documentLoader
= null; (JsonLdRecord
? or USVString)expandContext
= null; booleanextractAllScripts
= false; booleanframeExpansion
= false; booleanordered
= false; USVStringprocessingMode
= "json-ld-1.1"; booleanproduceGeneralizedRdf
= true; USVString?rdfDirection
= null; booleanuseNativeTypes
= false; booleanuseRdfType
= false; }; callbackLoadDocumentCallback
= Promise<RemoteDocument
> ( USVString url, optionalLoadDocumentOptions
? options ); dictionaryLoadDocumentOptions
{ booleanextractAllScripts
= false; USVStringprofile
= null; (USVString or sequence<USVString>)requestProfile
= null; }; [Exposed=JsonLd
] interfaceRemoteDocument
{constructor
(); readonly attribute USVStringcontentType
; readonly attribute USVStringcontextUrl
; attribute anydocument
; readonly attribute USVStringdocumentUrl
; readonly attribute USVStringprofile
; }; dictionaryJsonLdError
{JsonLdErrorCode
code
; USVString?message
= null; }; enumJsonLdErrorCode
{ "colliding keywords
", "conflicting indexes
", "context overflow
", "cyclic IRI mapping
", "invalid @id value
", "invalid @import value
", "invalid @included value
", "invalid @index value
", "invalid @nest value
", "invalid @prefix value
", "invalid @propagate value
", "invalid @protected value
", "invalid @reverse value
", "invalid @version value
", "invalid base direction
", "invalid base IRI
", "invalid container mapping
", "invalid context entry
", "invalid context nullification
", "invalid default language
", "invalid IRI mapping
", "invalid JSON literal
", "invalid keyword alias
", "invalid language map value
", "invalid language mapping
", "invalid language-tagged string
", "invalid language-tagged value
", "invalid local context
", "invalid remote context
", "invalid reverse property map
", "invalid reverse property value
", "invalid reverse property
", "invalid scoped context
", "invalid script element
", "invalid set or list object
", "invalid term definition
", "invalid type mapping
", "invalid type value
", "invalid typed value
", "invalid value object value
", "invalid value object
", "invalid vocab mapping
", "IRI confused with prefix
", "keyword redefinition
", "loading document failed
", "loading remote context failed
", "multiple context link headers
", "processing mode conflict
", "protected term redefinition
" };
B. Open Issues
This section is non-normative.
The following is a list of issues open at the time of publication.
More compact @prefix.
Expansion concept "key's term definition" is unclear with compact IRI keys.
Relationship to the RDF/JS Dataset interface(s).
Expansion does not take property-scoped contexts for nested properties into account.
Recursively nested properties and compaction.
relative iri compaction.
C. Changes since 1.0 Recommendation of 16 January 2014
This section is non-normative.
- The Expansion Algorithm
has a special processing mode, based on
the
flag, to enable content associated with JSON-LD frames, which may not otherwise be valid JSON-LD documents.frameExpansion
- An expanded term definition can now have an
@context
entry, which defines a context used for values of a property identified with such a term. This context is used in both the Expansion Algorithm and Compaction Algorithm. - A new § 7.3 Merge Node Maps is required for framing, to create a single graph from the default and named graphs.
- An expanded term definition can now have an
@nest
entry, which identifies a term expanding to@nest
which is used for containing properties using the same@nest
mapping. When expanding, the values of an entry expanding to@nest
are treated as if they were contained within the enclosing node object directly. @container
values within an expanded term definition may now include@id
and@type
, corresponding to id maps and type maps.- Both language maps and index maps may legitimately have an
@none
value, but JSON-LD 1.0 only allowed string values. This has been updated to allow (and ignore)@none
values. - The JSON syntax has been abstracted into an internal representation to allow for other serialization formats that are functionally equivalent to JSON.
- Preserved values are compacted using the properties of the referencing term.
- The value for
@container
in an expanded term definition can also be an array containing any appropriate container keyword along with@set
(other than@list
). This allows a way to ensure that such entry values will always be expressed in array form. - Added support for the
compactToRelative
option to allow IRI compaction (§ 6.2 IRI Compaction) to document-relative IRIs to be disabled. - In JSON-LD 1.1, terms will be used as compact IRI prefixes
when compacting only if
a simple term definition is used where the value ends with a URI gen-delim character,
or if their expanded term definition contains
an
@prefix
entry with the valuetrue
. The 1.0 algorithm has been updated to only consider terms that map to a value that ends with a URI gen-delim character. - Term definitions now allow
@container
to include@graph
, along with@id
,@index
and@set
. In the Expansion Algorithm, this is used to create a named graph from either a node object, or objects which are values of entries in an id map or index map. The Compaction Algorithm allows specific forms of graph objects to be compacted back to a set of node objects, or maps of node objects. - Value Expansion will not turn native values into node objects.
- The Term Selection algorithm has been
updated to allow uses of containers for values which would otherwise not
match. This is used in the Compaction
Algorithm to use the
@none
keyword, or an alias, for values of maps for which there is no natural index. The Expansion Algorithm removes this indexing transparently.
Additionally, see § D. Changes since JSON-LD Community Group Final Report.
D. Changes since JSON-LD Community Group Final Report
This section is non-normative.
- Lists may now have items which are themselves lists.
- The Deserialize JSON-LD to RDF Algorithm has been updated to ensure that only well-formed triples are emitted; previously, it only ensured that triples containing relative IRI references were excluded.
- The API now adds an
option, defaulting toordered
false
This is used in algorithms to control iteration of map entry keys. Previously, the algorithms always required such an order. The instructions for evaluating test results have been updated accordingly. - The Generate Blank Node Identifier algorithm has been updated to remove the specifics of how new blank node identifiers are created.
- Values of
@type
, or an alias of@type
, may now have their@container
set to@set
to ensure that@type
entries are always represented as an array. This also allows a term to be defined for@type
, where the value MUST be a map with@container
set to@set
. - Updated the IRI Expansion algorithm so that
if value contains a colon (
:
), but prefix is not a term, to only return value if it has the form of an IRI, otherwise fall through to the rest of the algorithm. - The use of blank node identifiers to label properties is obsolete,
and may be removed in a future version of JSON-LD,
as is the support for generalized RDF Datasets
and thus the
option may be also be removed.produceGeneralizedRdf
- Added API steps to accept
text/html
as input, extracting either a specifically targeted script element, the first found JSON-LD script element, or all JSON-LD script elements. - Added
field tocontentType
RemoteDocument
. - Added support for protected contexts and term definitions.
- Because scoped contexts can lead to contexts being reloaded, replace the
recursive context inclusion error with a
context overflow
error. - Added support for
"@type": "@none"
in a term definition to prevent value compaction. - Added support for JSON literals.
- Term definitions with keys which are of the form of an IRI or a compact IRI MUST NOT expand to an IRI other than the expansion of the key itself.
- Consolidate
RemoteDocument
processing into theLoadDocumentCallback
including variations on HTML processing. - The IRI Compaction algorithm may generate an error if the result is an IRI which could be confused with a compact IRI in the active context.
- By default, all contexts are propagated when traversing node objects, other than
type-scoped contexts. This can be controlled using the
@propagate
entry in a local context. - A context may contain a
@import
entry used to reference a remote context within a context, allowingJSON-LD 1.1
features to be added to contexts originally authored forJSON-LD 1.0
. - The
colliding keywords
error is not issued for@type
; instead, previous values of@type
are prepended to any new values, when expanding. - A node object may include an included block, which is used to contain a set of node objects which are treated exactly as if they were node objects defined in an array including the containing node object. This allows the use of the object form of a JSON-LD document when there is more than one node object being defined, and where those node objects are not embedded as values of the containing node object.
- A relative IRI reference has been added as a possible value for
@vocab
in a context. When this is set, vocabulary-relative IRI references, such as the entries of node objects, are expanded or compacted relative to the base IRI and the vocabulary mapping using string concatenation. - In the
LoadDocumentCallback
, if the retrieved content is not any JSON media type and there is a link header withrel=alternate
andtype=application/ld+json
, redirect to that content. - Value objects, and associated context and term definitions have been updated to
support
@direction
for setting the base direction of strings. - It is no longer required that language tags be normalized to lower case, other than for testing considerations. Language tags that are not valid according to [BCP47] are rejected.
- The processing mode is now implicitly
json-ld-1.1
, unless set explicitly tojson-ld-1.0
. - Improve notation using IRI, IRI reference, and relative IRI reference.
- Ignore terms and IRIs that have the form of a keyword (
"@"1*ALPHA
).
E. Changes since Candidate Release of 12 December 2019
This section is non-normative.
All changes are editorial and do not affect the observable behavior of the API nor the expected test results.
- Add
application/xhtml+xml
as an allowed media type in § 9.5.1 Process HTML, in the note in § 9.4.1 LoadDocumentCallback, and as a use of the
API option.profile
- Added add value, IRI expanding, and IRI compacting macros to reduce boilerplate in algorithmic language.
- Improved algorithms in § 4.1 Context Processing Algorithm, § 4.2 Create Term Definition, § 2.1 Expansion, § 2.2 Compaction, § 6.3 Value Compaction, § 7.2 Node Map Generation, and § 8.1 Deserialize JSON-LD to RDF Algorithm.
- When creating an
i18n
datatype orrdf:CompoundLiteral
, language tags are normalized to lower case to improve interoperability between implementations. - Moved non-recursive portions algorithms
into the
processing steps.JsonLdProcessor
- Fix some
initializers where defaults areJsonLdOption
null
. Set default value forprocessingMode
tojson-ld-1.1
. - Remove normative text for canonicalizing
rdf:JSON
literals and reference therdf:JSON
datatype of the syntax document for the conversion of the JSON Literals in § 8.6 Data Round Tripping. - Updated interfaces in § 9. The Application Programming Interface
to use record,
instead of dictionary,
and to allow
RemoteDocument
to be used as a direct input, which resolves aPromise
boundary issue.
F. Changes since Candidate Release of 05 March 2020
This section is non-normative.
All changes are editorial and do not affect the observable behavior of the API nor the expected test results.
- The inverse context is not passed explicitly as a parameter to the Term Selection, IRI compaction, and Value Compaction algorithms, but is retrieved from the inverse context field within an active context, and initialized as necessary. This simplifies calling sequences and better represents actual implementation experience.
- Updated step 5.13 of the Context Processing algorithm to pass override protected and not pass validate scoped context to the Create Term Definition algorithm.
- Move step 5.2.2 of the Context Processing algorithm to run before the subsequent step for checking remote contexts.
- Updated step 11 of the
Create Term Definition algorithm
to use any boolean value of
@protected
, not justtrue
. - Updated step 4.5 of the IRI Compaction algorithm
to use
@index
for any value with an@index
entry. - Update step 13.4.6.2 of the
Expansion algorithm to pass
null
for active property, as included blocks do not define a relationship to a referencing node. - Update step 13.8.3.6 of the
Expansion algorithm to pass
true
for the from map parameter to properly manage reverting active contexts. - Update step 11.1 of the
Compaction Algorithm
to pass
false
for propagate when calling the Context Processing algorithm. - Updated step 12.2.4 of the
Compaction Algorithm
to only look for
@set
if processing mode is json-ld-1.1. - Update step 12.8.6 of the Compaction Algorithm to clarify the value passed for element.
- Update steps 12.8.9.6.3 and 12.8.9.2.2 of the Compaction Algorithm to invoke the add value macro for adding remaining values back to compacted item.
- Update step 12.8.10 of the Compaction Algorithm to add values to nest result instead of result as was originally intended.
- Update step 2.2.1
of § 7.3 Merge Node Maps to
exclude
@type
, leaving it to the next step. This could cause type values from a node to be left out of the merge. - Added step 5.2.3
to the Context Processing algorithm,
which is added validate scoped context as a new
optional argument, and passed to the
Create Term Definition algorithm,
which in turn uses it with the value
false
when recursively calling the Context Processing algorithm when validating a scoped context. - Added missing values for
@container
in the description ofinvalid container mapping
. - Clarified step 3.13 in the Inverse Context Creation algorithm by moving the preceding step to 3.9.
- Update substeps of 6.1.6 in the Serialize RDF as JSON-LD Algorithm to update cl reference and not node.
- Added § 1.4.2 Syntax Tokens and Keywords to describe
the
preserve
keyword, which is only used for framing.
G. Changes since Proposed Recommendation Release of 7 May 2020
This section is non-normative.
- Removed remaining "at-risk" notes.
- Update bibliographic reference for JCS to [RFC8785].
- Changed
[Exposed=(Window,Worker)]
to[Exposed=JsonLd]
, which is declared as a global interface in order to expose the
interface for non-browser usage to address review suggestions.JsonLdProcessor
H. Acknowledgements
This section is non-normative.
The editors would like to specially thank the following individuals for making significant contributions to the authoring and editing of this specification:
- Timothy Cole (University of Illinois at Urbana-Champaign)
- Gregory Todd Williams (J. Paul Getty Trust)
- Ivan Herman (W3C Staff)
- Jeff Mixter (OCLC (Online Computer Library Center, Inc.))
- David Lehn (Digital Bazaar)
- David Newbury (J. Paul Getty Trust)
- Robert Sanderson (J. Paul Getty Trust, chair)
- Harold Solbrig (Johns Hopkins Institute for Clinical and Translational Research)
- Simon Steyskal (WU (Wirschaftsuniversität Wien) - Vienna University of Economics and Business)
- A Soroka (Apache Software Foundation)
- Ruben Taelman (Imec vzw)
- Benjamin Young (Wiley, chair)
Additionally, the following people were members of the Working Group at the time of publication:
- Steve Blackmon (Apache Software Foundation)
- Dan Brickley (Google, Inc.)
- Newton Calegari (NIC.br - Brazilian Network Information Center)
- Victor Charpenay (Siemens AG)
- Sebastian Käbisch (Siemens AG)
- Axel Polleres (WU (Wirschaftsuniversität Wien) - Vienna University of Economics and Business)
- Leonard Rosenthol (Adobe)
- Jean-Yves ROSSI (CANTON CONSULTING)
- Antoine Roulin (CANTON CONSULTING)
- Manu Sporny (Digital Bazaar)
- Clément Warnier de Wailly (CANTON CONSULTING)
A large amount of thanks goes out to the JSON-LD Community Group participants who worked through many of the technical issues on the mailing list and the weekly telecons: Chris Webber, David Wood, Drummond Reed, Eleanor Joslin, Fabien Gandon, Herm Fisher, Jamie Pitts, Kim Hamilton Duffy, Niklas Lindström, Paolo Ciccarese, Paul Frazze, Paul Warren, Reto Gmür, Rob Trainer, Ted Thibodeau Jr., and Victor Charpenay.
I. References
I.1 Normative references
- [BCP47]
- Tags for Identifying Languages. A. Phillips; M. Davis. IETF. September 2009. IETF Best Current Practice. URL: https://tools.ietf.org/html/bcp47
- [DOM]
- DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
- [ECMASCRIPT]
- ECMAScript Language Specification. Ecma International. URL: https://tc39.es/ecma262/
- [HTML]
- HTML Standard. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
- [IEEE-754-2008]
- IEEE 754-2008 Standard for Floating-Point Arithmetic. Institute of Electrical and Electronics Engineers. 2008. URL: https://standards.ieee.org/findstds/standard/754-2008.html
- [INFRA]
- Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
- [JSON-LD10]
- JSON-LD 1.0. Manu Sporny; Gregg Kellogg; Marcus Langhaler. W3C. 16 January 2014. W3C Recommendation. URL: https://www.w3.org/TR/2014/REC-json-ld-20140116/
- [JSON-LD11]
- JSON-LD 1.1. Gregg Kellogg; Pierre-Antoine Champin; Dave Longley. W3C. 7 May 2020. W3C Proposed Recommendation. URL: https://www.w3.org/TR/json-ld11/
- [JSON-LD11-FRAMING]
- JSON-LD 1.1 Framing. Dave Longley; Gregg Kellogg; Pierre-Antoine Champin. W3C. 7 May 2020. W3C Proposed 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
- [promises-guide]
- Writing Promise-Using Specifications. Domenic Denicola. W3C. 9 November 2018. TAG Finding. URL: https://www.w3.org/2001/tag/doc/promises-guide
- [RDF-SCHEMA]
- RDF Schema 1.1. Dan Brickley; Ramanathan Guha. W3C. 25 February 2014. W3C Recommendation. URL: https://www.w3.org/TR/rdf-schema/
- [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/
- [RDF11-MT]
- RDF 1.1 Semantics. Patrick Hayes; Peter Patel-Schneider. W3C. 25 February 2014. W3C Recommendation. URL: https://www.w3.org/TR/rdf11-mt/
- [RFC2045]
- Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies. N. Freed; N. Borenstein. IETF. November 1996. Draft Standard. URL: https://tools.ietf.org/html/rfc2045
- [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
- [RFC3986]
- Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter. IETF. January 2005. Internet Standard. URL: https://tools.ietf.org/html/rfc3986
- [RFC3987]
- Internationalized Resource Identifiers (IRIs). M. Duerst; M. Suignard. IETF. January 2005. Proposed Standard. URL: https://tools.ietf.org/html/rfc3987
- [RFC5234]
- Augmented BNF for Syntax Specifications: ABNF. D. Crocker, Ed.; P. Overell. IETF. January 2008. Internet Standard. URL: https://tools.ietf.org/html/rfc5234
- [RFC6839]
- Additional Media Type Structured Syntax Suffixes. T. Hansen; A. Melnikov. IETF. January 2013. Informational. URL: https://tools.ietf.org/html/rfc6839
- [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
- [RFC8259]
- The JavaScript Object Notation (JSON) Data Interchange Format. T. Bray, Ed.. IETF. December 2017. Internet Standard. URL: https://tools.ietf.org/html/rfc8259
- [RFC8288]
- Web Linking. M. Nottingham. October 2017. Proposed Standard. URL: https://tools.ietf.org/html/rfc8288
- [Turtle]
- RDF 1.1 Turtle. Eric Prud'hommeaux; Gavin Carothers. W3C. 25 February 2014. W3C Recommendation. URL: https://www.w3.org/TR/turtle/
- [WEBIDL]
- Web IDL. Boris Zbarsky. W3C. 15 December 2016. W3C Editor's Draft. URL: https://heycam.github.io/webidl/
- [XMLSCHEMA11-2]
- W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes. David Peterson; Sandy Gao; Ashok Malhotra; Michael Sperberg-McQueen; Henry Thompson; Paul V. Biron et al. W3C. 5 April 2012. W3C Recommendation. URL: https://www.w3.org/TR/xmlschema11-2/
I.2 Informative references
- [cooluris]
- Cool URIs for the Semantic Web. Leo Sauermann; Richard Cyganiak. W3C. 3 December 2008. W3C Note. URL: https://www.w3.org/TR/cooluris/
- [JSON-LD10-API]
- JSON-LD 1.0 Processing Algorithms And API. Marcus Langhaler; Gregg Kellogg; Manu Sporny. W3C. 16 January 2014. W3C Recommendation. URL: https://www.w3.org/TR/2014/REC-json-ld-api-20140116/
- [RFC8785]
- JSON Canonicalization Scheme (JCS). A. Rundgren; B. Jordan; S. Erdtman. Network Working Group. June 2020. Informational. URL: https://www.rfc-editor.org/rfc/rfc8785