JSON-LD 1.1 Processing Algorithms and API
JSON-LD 1.1 Processing Algorithms and API
W3C Recommendation
16 July 2020
This version:
Latest published version:
Latest editor's draft:
Test suite:
Implementation report:
Previous version:
Previous Recommendation:
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
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
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
JSON-LD 1.1
JSON-LD 1.1 Processing Algorithms and API
JSON-LD 1.1 Framing
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
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
Note
Notes are in light green boxes with a green left border and with a "Note" header in green.
Notes are always informative.
Example
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
list
(also called an
array
) is an
ordered
collection of zero or more values.
While JSON-LD uses the same array representation as JSON,
the collection is
unordered
by default.
While order is preserved in regular JSON arrays,
it is not in regular JSON-LD arrays unless specifically defined
(see the
Sets and Lists
section of JSON-LD 1.1.
boolean
The values
true
and
false
that are used
to express one of two possible states.
JSON object
In the JSON serialization,
an
object
structure
is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members).
A name is a
string
A single colon comes after each name,
separating the name from the value.
A single comma separates a value from a following name.
In JSON-LD the names in an object must be unique.
In the
internal representation
JSON object
is described as a
map
(see [
INFRA
]),
composed of
entries
with key/value pairs.
In the
Application Programming Interface
map
is described using a [
WEBIDL
record
null
The use of the
null
value within JSON-LD
is used to ignore or reset values.
map entry
in the
@context
where the value,
or the
@id
of the value, is
null
explicitly decouples a term's association with an
IRI
map entry
in the body of a
JSON-LD document
whose value is
null
has the same meaning as if the
map entry
was not defined.
If
@value
@list
, or
@set
is set to
null
in expanded form,
then the entire
JSON object
is ignored.
number
In the JSON serialization, a
number
is similar to that used in most programming languages,
except that the octal and hexadecimal formats are not used and that leading zeros are not allowed.
In the
internal representation
number
is equivalent to either a
long
or
double
depending on if the number has a non-zero fractional part (see [
WEBIDL
]).
scalar
A scalar is either a
string
number
true
, or
false
string
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
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
node
in a
graph
that is neither an
IRI
nor a
literal
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
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
dataset
representing a collection of
RDF graphs
including exactly one
default graph
and zero or more
named graphs
datatype
IRI
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
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
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
named graph
is a
linked data graph
that is identified by an
IRI
or
blank node
node
node
in an
RDF graph
, either the
subject
and
object
of at least one
triple
Note that a
node
can play both roles (
subject
and
object
) in a
graph
, even in the same
triple
object
An
object
is a
node
in a
linked data graph
with at least one incoming edge.
property
The name of a directed-arc in a
linked data graph
Every
property
is directional
and is labeled with an
IRI
or a
blank node identifier
Whenever possible, a
property
should be labeled with an
IRI
Note
The use of
blank node identifiers
to label properties is obsolete,
and may be removed in a future version of JSON-LD.
Also, see
predicate
in [
RDF11-CONCEPTS
].
RDF graph
A labeled directed
graph
i.e., a set of
nodes
connected by directed-arcs.
Also called
linked data graph
resource
resource
denoted by an
IRI
, a
blank node
or
literal
representing something in the world (the "universe of discourse").
subject
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
context
that is used to resolve
while the processing algorithm is running.
base direction
The
base direction
is the direction used when a string does not have a direction associated with it directly.
It can be set in the
context
using the
@direction
key
whose value must be one of the strings
"ltr"
"rtl"
, or
null
See the
Context Definitions
section of JSON-LD 1.1 for a normative description.
compact
IRI
A compact
IRI
has the form of
prefix
suffix
and is used as a way of expressing an
IRI
without needing to define separate
term
definitions
for each
IRI
contained within a common vocabulary identified by
prefix
context
A set of rules for interpreting a
JSON-LD document
as described in the
The Context
section of JSON-LD 1.1,
and normatively specified in the
Context Definitions
section of JSON-LD 1.1.
default language
The
default language
is the language used when a string does not have a language associated with it directly.
It can be set in the
context
using the
@language
key
whose value must be a
string
representing a [
BCP47
] language code or
null
See the
Context Definitions
section of JSON-LD 1.1 for a normative description.
default object
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
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
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
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
JSON literal
is a
literal
where the associated
datatype
IRI
is
rdf:JSON
In the
value object
representation, the value of
@type
is
@json
JSON literals represent values which are valid JSON [
RFC8259
].
See the
The
rdf:JSON
Datatype
section in JSON-LD 1.1 for a normative description.
JSON-LD document
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
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
JSON-LD value
is a
string
number
true
or
false
typed value
or a
language-tagged string
It represents an
RDF literal
keyword
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
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
context
that is specified with a
map
specified via the
@context
keyword
node object
node object
represents zero or more
properties
of a
node
in the
graph
serialized by the
JSON-LD document
map
is a
node object
if it exists outside of the JSON-LD
context
and:
it does not contain the
@value
@list
, or
@set
keywords, or
it is not the top-most
map
in the JSON-LD document
consisting of no other
entries
than
@graph
and
@context
The
entries
of a
node object
whose keys are not keywords are also called
properties
of the
node object
See the
Node Objects
section of JSON-LD 1.1 for a normative description.
prefix
prefix
is the first component of a
compact
IRI
which comes from a
term
that maps to a string that,
when prepended to the suffix of the
compact
IRI
results in an
IRI
processing mode
The
processing mode
defines how a
JSON-LD document
is processed.
By default, all documents are assumed to be conformant with this specification.
By defining a different version using the
@version
entry
in a
context
publishers can ensure that processors conformant with
JSON-LD 1.0
JSON-LD10
will not accidentally process JSON-LD 1.1 documents, possibly creating a different output.
The API provides an option for setting the
processing mode
to
json-ld-1.0
which will prevent JSON-LD 1.1 features from being activated,
or error if
@version
entry
in a
context
is explicitly set to
1.1
This specification extends
JSON-LD 1.0
via the
json-ld-1.1
processing mode
scoped context
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
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
term
is a short word defined in a
context
that may be expanded to an
IRI
See the
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
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
typed value
consists of a value,
which is a
string
and a type,
which is an
IRI
value object
value object
is a
map
that has an
@value
entry
See the
Value Objects
section of JSON-LD 1.1 for a normative description.
vocabulary mapping
The vocabulary mapping is set in the
context
using the
@vocab
key
whose value must be an
IRI
, a
compact
IRI
, a
term
, or
null
See the
Context Definitions
section of JSON-LD 1.1 for a normative description.
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
If
as array
is
true
and the value of
key
in
object
does not exist
or is not an
array
, set it to a new
array
containing any original value.
If
value
is an
array
then for each element
in
value
use
add value
recursively to add
to
key
in
entry
Otherwise:
If
key
is not an entry in
object
add
value
as the value of
key
in
object
Otherwise
If the value of the
key
entry
in
object
is not an
array
set it to a new
array
containing the original value.
Append
value
to the value of the
key
entry
in
object
IRI
compacting
Used as a macro within various algorithms as to reduce the language used to describe
the process of compacting a
string
var
representing an
IRI
or
keyword
using an
active context
either specified directly, or coming from the scope of
the algorithm step using this term.
An optional
value
is used, if explicitly provided.
Unless specified, the
vocab
flag defaults to
true
and the
reverse
flag defaults to
false
Return the result of using the
IRI
Compaction algorithm
passing
active context
var
value
(if supplied),
vocab
and
result
IRI
expanding
Used as a macro within various algorithms as to reduce the language used to describe
the process of expanding a
string
value
representing an
IRI
or
keyword
using an
active context
either specified directly, or coming from the scope of
the algorithm step using this term.
Optional
defined
and
local context
arguments are used, if explicitly provided.
Unless specified,
the
document relative
flag defaults to
false
and the
vocab
flag defaults to
true
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
Example
: Sample JSON-LD document
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"knows": "http://xmlns.com/foaf/0.1/knows"
},
"@id": "http://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
and is fairly compact:
Example
: JSON-LD document using only terms
Open in playground
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"homepage": {
"@id": "http://xmlns.com/foaf/0.1/homepage",
"@type": "@id"
},
"@id": "http://me.markus-lanthaler.com/",
"name": "Markus Lanthaler",
"homepage": "http://www.markus-lanthaler.com/"
[{
"@id": "http://me.markus-lanthaler.com/",
"http://xmlns.com/foaf/0.1/name": [
{"@value": "Markus Lanthaler"}
],
"http://xmlns.com/foaf/0.1/homepage": [
{"@id": "http://www.markus-lanthaler.com/"}
}]
Subject
Property
Value
foaf:name
Markus Lanthaler
@prefix foaf:
foaf:homepage
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.
Example
: Sample JSON-LD document using an IRI instead of a term to express a property
Open in playground
"@context": {
"website": "http://xmlns.com/foaf/0.1/homepage"
},
"@id": "http://me.markus-lanthaler.com/",
": "Markus Lanthaler",
"website"
{ "@id":
"http://www.markus-lanthaler.com/"
[{
"@id": "http://me.markus-lanthaler.com/",
"http://xmlns.com/foaf/0.1/name": [
{"@value": "Markus Lanthaler"}
],
"http://xmlns.com/foaf/0.1/homepage": [
{"@id": "http://www.markus-lanthaler.com/"}
}]
Subject
Property
Value
foaf:name
Markus Lanthaler
@prefix foaf:
foaf:homepage
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:
Example
: Expanded JSON-LD document using an IRI
"@id": "http://me.markus-lanthaler.com/",
": [
{ "@value": "Markus Lanthaler" }
],
": [
{ "@id": "http://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
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
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:
Example
: Expanded sample document
"@id": "http://me.markus-lanthaler.com/",
"http://xmlns.com/foaf/0.1/name": [
{ "@value": "Markus Lanthaler" }
],
"http://xmlns.com/foaf/0.1/homepage": [
{ "@id": "http://www.markus-lanthaler.com/" }
Additionally, assume the following developer-supplied JSON-LD
context
Example
: JSON-LD context
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"homepage": {
"@id": "http://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:
Example
: Compacted sample document
Open in playground
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"homepage": {
"@id": "http://xmlns.com/foaf/0.1/homepage",
"@type": "@id"
},
"@id": "http://me.markus-lanthaler.com/",
"name": "Markus Lanthaler",
"homepage": "http://www.markus-lanthaler.com/"
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
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
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:
Example
: JSON-LD document in compact form
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"knows": "http://xmlns.com/foaf/0.1/knows"
},
"@id": "http://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:
Example
10
: Flattened sample document
Open in playground
[{
"@id": "http://me.markus-lanthaler.com/",
"http://xmlns.com/foaf/0.1/name": [
{ "@value": "Markus Lanthaler" }
],
"http://xmlns.com/foaf/0.1/knows": [
{ "@id": "_:b0" }
}, {
"@id": "_:b0",
"http://xmlns.com/foaf/0.1/name": [
{ "@value": "Dave Longley" }
}]
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:
Example
11
: Flattened and compacted sample document
Open in playground
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"knows": "http://xmlns.com/foaf/0.1/knows"
},
"@graph": [{
"@id": "http://me.markus-lanthaler.com/",
"name": "Markus Lanthaler",
"knows": { "@id": "_:b0" }
}, {
"@id": "_:b0",
"name": "Dave Longley"
}]
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
]:
Example
12
: Sample Turtle document
@prefix foaf:
foaf:name "Markus Lanthaler" ;
foaf:homepage
Using the
Serialize RDF as JSON-LD Algorithm
a developer could transform this document into expanded JSON-LD:
Example
13
: Sample Turtle document converted to JSON-LD
"@id": "http://me.markus-lanthaler.com/",
"http://xmlns.com/foaf/0.1/name": [
{ "@value": "Markus Lanthaler" }
],
"http://xmlns.com/foaf/0.1/homepage": [
{ "@id": "http://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,
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
Note
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
xsd
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
),
prefix flag
boolean
),
protected
flag (
boolean
),
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
).
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
documentUrl
of the document containing the initial
context
, if available,
otherwise from the
base
API option.
This is necessary when resetting the
active context
by setting it to
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
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
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
boolean
true
or
false
set
propagate
to that value.
Note
Error 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
an
invalid 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
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
loading document failed
error
has been detected and processing is aborted.
Note
base URL
is often not the same as
base
or the
base
IRI
of the
active context
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
Note
Only the
@context
entry
need be retained.
Otherwise, set
context document
to the
RemoteDocument
obtained
by dereferencing
context
using
the
LoadDocumentCallback
, passing
context
for
url
and
for
profile
and for
requestProfile
If
context
cannot be dereferenced,
or the
document
from
context document
cannot be transformed into the
internal representation
loading remote context failed
error has been detected and processing is aborted.
If the
document
has no
top-level
map
with an
@context
entry
, an
invalid remote context
has been detected and processing is aborted.
Set
loaded context
to the value of that
entry
Set
result
to the result of recursively calling this algorithm,
passing
result
for
active context
loaded context
for
local context
the
documentUrl
of
context document
for
base URL
a copy of
remote contexts
and
validate scoped context
Note
If
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
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
an
invalid @version value
has been detected, and processing is aborted.
Note
The use of
1.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
processing mode conflict
error has been detected and processing is aborted.
If
context
has an
@import
entry
If
processing mode
is
json-ld-1.0
an
invalid context entry
error has been detected and processing is aborted.
Otherwise, if the value of
@import
is not a
string
an
invalid @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
and
for
profile
and for
requestProfile
If
import
cannot be dereferenced,
or cannot be transformed into the
internal representation
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
),
an
invalid 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
an
invalid 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
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.
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
, an
invalid vocab mapping
error has been detected and processing is aborted.
Note
The use of
blank node identifiers
to value for
@vocab
is obsolete,
and may be removed in a future version of JSON-LD.
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.
Note
Processors
MAY
normalize
language tags
to lower case.
If
context
has an
@direction
entry
If
processing mode
is
json-ld-1.0
an
invalid 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"
, an
invalid base direction
error has been detected and processing is aborted.
If
context
has an
@propagate
entry
If
processing mode
is
json-ld-1.0
an
invalid context entry
error has been detected and processing is aborted.
Otherwise, if the value of
@propagate
is not
boolean
true
or
false
an
invalid @propagate value
error has been detected and processing is aborted.
Note
The
previous context
is actually set earlier in this algorithm;
the previous two steps exist for error checking only.
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
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
local context
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 is
false
, a
cyclic
IRI
mapping
error has been detected and processing is aborted.
If
term
is the empty string (
""
),
an
invalid term definition
error has been detected and processing is aborted.
Otherwise, set the value associated with
defined
's
term
entry
to
false
. 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
is
json-ld-1.0
keyword 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
Any other value means that a
keyword redefinition
error has
been detected and processing is aborted.
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 is
null
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
to
true
Otherwise,
value
MUST
be a
map
, if not, an
invalid term definition
error has been detected and processing is aborted.
Set
simple term
to
false
Create a new
term definition
definition
initializing
prefix flag
to
false
protected
to
protected
and
reverse property
to
false
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
an
invalid @protected value
error has been detected and processing is aborted.
If
processing mode
is
json-ld-1.0
an
invalid 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, an
invalid 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
is
json-ld-1.0
an
invalid 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
an
invalid type mapping
error has been detected and processing is aborted.
Set the
type mapping
for
definition
to
type
If
value
contains the
entry
@reverse
If
value
contains
@id
or
@nest
entries
, an
invalid reverse property
error has been detected and processing is aborted.
If the value associated with the
@reverse
entry
is not a
string
, an
invalid
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
an
invalid
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
, nor
null
, an
invalid 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 the
entry
@id
and its value
does not equal
term
If the
@id
entry
of
value
is
null
, 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
, an
invalid
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
, an
invalid
IRI
mapping
error has been detected and processing is aborted; if it equals
@context
, an
invalid 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.
If
term
contains neither a colon (
) nor a slash (
),
simple term
is
true
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
to
true
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, an
invalid 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 an
invalid container mapping
error and abort processing if
processing mode
is
json-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
an
invalid type mapping
error has been detected and processing is aborted.
If
value
contains the
entry
@index
If
processing mode
is
json-ld-1.0
or
container mapping
does not include
@index
an
invalid 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
an
invalid term definition
has been detected and processing is aborted.
Set the
index mapping
of
definition
to
index
If
value
contains the
entry
@context
If
processing mode
is
json-ld-1.0
, an
invalid 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
and
false
for
validate scoped context
If any error is detected, an
invalid scoped context
error
has been detected and processing is aborted.
Note
The 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
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 either
null
or a
string
If
language
is not
well-formed
according to
section 2.2.9
of [
BCP47
],
processors
SHOULD
issue a warning.
Otherwise, an
invalid language mapping
error has been detected and processing is aborted.
Set the
language mapping
of
definition
to
language
Note
Processors
MAY
normalize
language tags
to lower case.
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 either
null
"ltr"
, or
"rtl"
. Otherwise, an
invalid base direction
error has been detected and processing is aborted.
Set the
direction mapping
of
definition
to
direction
If
value
contains the
entry
@nest
If
processing mode
is
json-ld-1.0
, an
invalid 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, an
invalid @nest value
error has been detected and processing is aborted.
If
value
contains the
entry
@prefix
If
processing mode
is
json-ld-1.0
, or if
term
contains a colon (
) or slash (
), an
invalid 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, an
invalid @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
an
invalid term definition
has been detected and processing is aborted.
If
value
contains any
entry
other than
@id
@reverse
@container
@context
@direction
@index
@language
@nest
@prefix
@protected
or
@type
an
invalid 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
),
protected term redefinition
error has been detected,
and processing is aborted.
Set
definition
to
previous definition
to retain the value
of
protected
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
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
If
type map
does not have an
@reverse
entry
, create one and set its value to the
term
being processed.
Otherwise, if
term definition
has a
type mapping
which is
@none
If
language map
does not have an
@any
entry
, create one and set its value to the
term
being processed.
If
type map
does not have an
@any
entry
, create one and set its value to the
term
being processed.
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
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.
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.
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.
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.
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
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
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
keyword
or
IRI
var
an
array
containers
that represents an
ordered list of preferred
container mapping
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
Example
14
: Term definition with language map
"@context"
: {
"t"
: {
"@id"
"http://example.org/t"
"@container"
"@language"
}}
The inverse context will contain the following:
"@language"
: {
"@language"
: {
"@none"
"t"
},
"@type"
: {
"@none"
"t"
},
"@any"
: {
"@none"
"t"
Example
15
: Language map term with language value
Given the
entry
{"http://example.org/t": {"@value": "foo", "@type": "http:/example.org/type"}}
The algorithm will be invoked as follows:
containers
["@language", "@language@set", "@set", "@none", "@index", "@index@set"]
type/language
@language
preferred values
["en", "@none"]
The
value map
will be set to
{"@none": "t"}
as
preferred values
contains
"@none"
the algorithm returns
"t"
as the term to use for compaction.
Datatyped Term
If the term definition has a datatype, it will only match a
value object
having a matching datatype.
Example
16
: Term definition with datatype
"@context"
: {
"t"
: {
"@id"
"http://example.org/t"
"@type"
"http:/example.org/type"
}}
The inverse context will contain the following:
"@none"
: {
"@language"
: {},
"@type"
: {
"http:/example.org/type"
"t"
},
"@any"
: {
"@none"
"t"
Example
17
: Datatyped term with datatyped value
Given the
entry
{"http://example.org/t": {"@value": "foo", "@type": "http:/example.org/type"}}
The algorithm will be invoked as follows:
containers
["@set", "@none", "@index", "@index@set"]
type/language
@type
preferred values
["http:/example.org/type", "@none"]
The
value map
will be set to
{"http:/example.org/type": "t"}
as
preferred values
contains
"http:/example.org/type"
the algorithm returns
"t"
as the term to use for compaction.
Example
18
: Datatyped term with simple value
Given the
entry
{"http://example.org/t": {"@value": "foo"}}
The algorithm will be invoked as follows:
containers
["@set", "@none", "@index", "@index@set", "@language", "@language@set"]
type/language
@language
preferred values
["@null", "@none"]
The
value map
will be set to
{"@none": "t"}
as no key in
preferred values
matches a key in
value map
the algorithm returns
null
and no term is found.
Example
19
: Datatyped term with object value
Given the
entry
{"http://example.org/t": {"@id": "http://example.org/id"}}
The algorithm will be invoked as follows:
containers
["@id", "@id@set", "@type", "@set@type", "@set", "@none", "@index", "@index@set"]
type/language
@type
preferred values
["@id", "@vocab", "@none"]
The
value map
will be set to
{"http:/example.org/type": "t"}
as no key in
preferred values
matches a key in
value map
the algorithm returns
null
and no term is found.
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
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
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
Note
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
documentUrl
of the original
document to expand
The optional inputs are the
frameExpansion
flag allowing special forms of input used for
frame expansion
the
ordered
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
false
The algorithm also performs processing steps specific to expanding
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
frameExpansion
flag is set to
true
Note
As mentioned in
JSON-LD11
],
to avoid forward-compatibility issues,
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.
Note
The use of empty
""
) 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.
Note
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
, return
null
If
active property
is
@default
initialize the
frameExpansion
flag to
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 returning
null
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
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
ordered
and
from map
flags.
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
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
ordered
is
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
, an
invalid 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
is
json-ld-1.0
colliding 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
frameExpansion
flag is set,
value
MAY
be an empty
map
, or an
array
of one
or more
strings
Otherwise,
set
expanded value
to the result of
IRI
expanding
value
using
true
for
document relative
and
false
for
vocab
When the
frameExpansion
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.
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
frameExpansion
flag is set,
value
MAY
be an empty
map
, or a
default object
where the value of
@default
is restricted to be
an
IRI
All other values mean that
invalid 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
and
true
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.
Note
No transformation from a
string
value
to an
array
expanded value
is implied, and the form or
value
should be preserved in
expanded value
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
frameExpansion
and
ordered
flags
ensuring that
expanded value
is an
array
of one or more
maps
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
frameExpansion
and
ordered
flags,
ensuring that the result is an
array
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
expanded property
is
@value
If
input type
is
@json
set
expanded value
to
value
If
processing mode
is
json-ld-1.0
an
invalid value object value
error has been detected and processing is aborted.
Otherwise, if
value
is not a
scalar
or
null
an
invalid value object value
error has been detected and processing is aborted.
When the
frameExpansion
flag is set,
value
MAY
be an empty
map
or an array of
scalar
values.
Otherwise, set
expanded value
to
value
When the
frameExpansion
flag is set,
expanded value
will be an
array
of one or more
string
values
or an
array
containing an empty
map
If
expanded value
is
null
, set the
@value
entry
of
result
to
null
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
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
frameExpansion
flag is set,
value
MAY
be an empty
map
or an array of zero or more
strings
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
frameExpansion
flag is set,
expanded value
will be an
array
of one or more
string
values
or an
array
containing an empty
map
Note
Processors
MAY
normalize
language tags
to lower case.
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"
, an
invalid base direction
error has been detected and processing is aborted.
When the
frameExpansion
flag is set,
value
MAY
be an empty
map
or an array of zero or more
strings
Otherwise, set
expanded value
to
value
When the
frameExpansion
flag is set,
expanded value
will be an
array
of one or more
string
values
or an
array
containing an empty
map
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
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
frameExpansion
and
ordered
flags,
ensuring that the result is an
array
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
frameExpansion
and
ordered
flags
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
frameExpansion
and
ordered
flags
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:
Use
add value
to add
item
to the
property
entry
in
result
using
true
for
as array
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
Continue with the next
key
from
element
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
frameExpansion
flag is set,
if
expanded property
is any other
framing keyword (
@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
frameExpansion
and
ordered
flags
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
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
ordered
is
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
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.
Note
Processors
MAY
normalize
language tags
to lower case.
If
language
is
@none
or expands to
@none
, remove
@language
from
If
direction
is not
null
add an
entry
for
@direction
to
with
direction
Append
to
expanded value
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
ordered
is
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
frameExpansion
and
ordered
flags
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
expanding
index
using
true
for
document relative
and
false
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
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
frameExpansion
and
ordered
flags
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
graph object
by creating a
map
containing the key-value
pair
@graph
ev
where
ev
is represented as an
array
Note
This may lead to a
graph object
including another
graph object
if
ev
was already in the form of a
graph object
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
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
For each key
nesting-key
in
nests
ordered lexicographically if
ordered
is
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
, an
invalid @nest value
error
has been detected and processing is aborted.
Recursively repeat steps
13
and
14
using
nested value
for
element
Note
By invoking steps
13
and
14
on
nested value
we are able to unfold arbitrary levels of nesting, with results being merged into
result
Step
13
iterates through each
entry in
nested value
and expands it, while collecting new
nested values
found at each level, until all nesting has been extracted.
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, an
invalid 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
is
null
, or an empty
array
, return
null
Otherwise, if the value of
result
's
@value
entry
is not a
string
and
result
contains the
entry
@language
, an
invalid 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
, an
invalid typed value
error has been detected and processing is aborted.
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, an
invalid 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.
If
result
is a
map
that contains only the
entry
@language
return
null
If
active property
is
null
or
@graph
drop free-floating values as follows:
If
result
is a
map
which is empty,
or contains only the
entries
@value
or
@list
set
result
to
null
Otherwise, if
result
is a
map
whose only
entry
is
@id
, set
result
to
null
When the
frameExpansion
flag is set, a
map
containing only the
@id
entry
is retained.
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
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
have already been defined or are
in the process of being defined. We create a
term definition
by using the
Create Term Definition algorithm
Note
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
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 return
null
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 not
true
invoke the
Create Term Definition algorithm
passing
active context
local context
value
as
term
, and
defined
. This will ensure that
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 not
true
, 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
is
true
return the result of concatenating the
IRI
mapping
associated with
prefix
and
suffix
If
value
has the
form
of an
IRI
return
value
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
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
using
true
for
document relative
and
false
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
using
true
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
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
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
compactArrays
flag
and the
ordered
flag, used to order
map entry
keys lexicographically, where noted.
If not passed, both flags are set to
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
compactArrays
and
ordered
flags
If
compacted item
is not
null
, then append
it to
result
If
result
is empty or contains more than one value,
or
compactArrays
is
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
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
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
compactArrays
and
ordered
flags
Initialize
inside reverse
to
true
if
active property
equals
@reverse
otherwise to
false
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
For each key
expanded property
and value
expanded value
in
element
, ordered lexicographically by
expanded property
if
ordered
is
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 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
is
json-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
compactArrays
and
ordered
flags
For each
property
and
value
in
compacted value
If the
term definition
for
property
in the
active context
indicates that
property
is
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
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
Continue with the next
expanded property
from
element
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
compactArrays
and
ordered
flags
Add
compacted value
as the value of
@preserve
in
result
unless
expanded value
is an empty
array
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
an
invalid @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
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
an
invalid @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
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
compactArrays
and
ordered
flags
If
expanded item
is a
list object
or a
graph object
use the value of the
@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
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 to
false
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
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
using
false
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
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
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,
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
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
, return
null
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
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
Note
Algorithm 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
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
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.
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
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
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
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
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 which
null
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
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
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
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
true
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
is
null
set
compact
IRI
to
candidate
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 (
//
),
an
IRI
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
using
false
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
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
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
Otherwise, if
value
has an
@language
entry
whose value exactly matches
language
using a case-insensitive comparison
if it is not
null
, or is not present, if
language
is
null
and the
value
has an
@direction
entry
whose value exactly matches
direction
if it is not
null
, or is not present, if
direction
is
null
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
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
ordered
flag, used to order
map entry
keys lexicographically, where noted.
If not passed, the
ordered
flag is set to
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
ordered
is
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
ordered
is
true
add
node
to the
@graph
entry
of
entry
unless the only
entry
of
node
is
@id
Initialize an empty
array
flattened
For each
id
node
pair in
default graph
ordered lexicographically by
id
if
ordered
is
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
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
to
null
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
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
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
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, a
conflicting 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.
Remove the
@reverse
entry
from
element
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
Note
The 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
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
Initialize
merged node
to the value for
id
in
result
, initializing it
with a new
map
consisting of a single
entry
@id
whose value is
id
, if it does not exist.
For each
property
and
values
in
node
If
property
is a
keyword
other than
@type
, add
property
and values to
merged node
Otherwise, merge each element from
values
into the values for
property
in
merged node
, initializing it to an empty
array
if necessary.
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
Note
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.
Note
The use of
blank node identifiers
to label properties is obsolete,
and may be removed in a future version of JSON-LD.
If the
rdfDirection
option is not
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
].
blank node identifier
is
well-formed
if it matches the
EBNF for
BLANK_NODE_LABEL
as described in [
Turtle
].
Note
When 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.
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 an
RDF 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
produceGeneralizedRdf
and
rdfDirection
Unless the
produceGeneralizedRdf
option
is set to
true
triple
containing a
blank node
predicate
are excluded from output.
Note
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
produceGeneralizedRdf
option may be also be removed.
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 the
defaultGraph
attribute of
dataset
Otherwise, initialize
triples
as an empty
RdfGraph
and add to
dataset
using its
add
method along with
graph name
for
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 new
RdfTriple
composed of
subject
rdf:type
for
predicate
and
type
for
object
and add to
triples
using its
add
method,
unless
type
is not
well-formed
Otherwise, if
property
is a
keyword
continue with the next
property
values
pair.
Otherwise, if
property
is a
blank node identifier
and
the
produceGeneralizedRdf
option is not
true
continue with the next
property
values
pair.
Note
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
produceGeneralizedRdf
option may be also be removed.
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
item
is a
value object
list object
or a
node object
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
add
method,
unless the result is
null
indicating a
non-
well-formed
resource
that has to be ignored.
Add all
RdfTriple
instances from
list triples
to
triples
using
its
add
method.
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
, return
null
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
or
null
if
item
does not have such an
entry
If
datatype
is not
null
and neither a
well-formed
IRI
nor
@json
return
null
If
item
has an
@language
entry
which is not
well-formed
, return
null
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
to
rdf:JSON
Issue
The 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
or
false
, set
value
to the
string
true
or
false
which is the
canonical lexical form
as described in
8.6
Data Round Tripping
If
datatype
is
null
set
datatype
to
xsd: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 10
21
or
value
is a
number
and
datatype
equals
xsd:double
, convert
value
to a
string
in
canonical lexical form
of
an
xsd:double
as defined in [
XMLSCHEMA11-2
and described in
8.6
Data Round Tripping
If
datatype
is
null
set
datatype
to
xsd: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
is
null
set
datatype
to
xsd:integer
Note
It follows from the previous step that
value
has no non-zero fractional part.
Otherwise, if
datatype
is
null
set
datatype
to
xsd:string
or
rdf:langString
depending on if item has an
@language
entry
If
item
contains an
@direction
entry
and
rdfDirection
is not
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 (
""
) if there is no such entry.
Note
Generally, language tags are not normalized,
but when creating an
i18n-datatype
or
compound-literal
values are normalized to lower case for improved interoperability.
If
rdfDirection
is
i18n-datatype
set
datatype
to the result of appending
language
and the value of
@direction
in
item
separated by an underscore (
"_"
to
Initialize
literal
as an
RDF literal
using
value
and
datatype
Note
Processors
MAY
normalize
language tags
to lower case.
Note
As
@direction
may be used without
@language
it is possible, and legitimate, to create a datatype
IRI
such as
, which does not encode a language tag.
Otherwise, if
rdfDirection
is
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
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
rdfDirection
option is not
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
ordered
flag, defaulting to
false
, used to order
map entry
keys lexicographically, where noted
rdfDirection
defaulting to
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
rdfDirection
option
is
compound-literal
and
predicate
is
rdf:direction
add an entry in
compound map
for
subject
with the value
true
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
, the
useRdfType
flag is not
true
, 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
rdfDirection
and
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
Reference the
usages
entry
of the
object
entry
of
node map
using the variable
usages
Append a new
map
consisting of three
entries
node
property
, and
value
to the
usages
array
. The
node
entry
is set to a reference to
node
property
to
predicate
and
value
to a reference to
value
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:
Set the
object
entry
of
referenced once
to a new
map
consisting of three
entries
node
property
, and
value
to the
usages
array
. The
node
entry
is set to a reference to
node
property
to
predicate
and
value
to a reference to
value
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 the
rdf:value
entry in
cl node
Add an
entry
to
cl reference
for
@language
with the value taken
from the
rdf:language
entry in
cl node
, if any.
If that value is not
well-formed
according to
section 2.2.9
of [
BCP47
],
an
invalid language-tagged string
error has been detected and processing is aborted.
Add an
entry
to
cl reference
for
@direction
with the value taken
from the
rdf:direction
entry in
cl node
, if any.
If that value is not
"ltr"
or
"rtl"
, an
invalid base direction
error has been detected and processing is aborted.
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 the
property
entry
of
usage
and
head
to the value of the
value
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
of
node
is a
map
node
has
rdf:first
and
rdf: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 to
rdf: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
of
node
Set
node
to the value of the
node
entry
of
node usage
property
to the value of the
property
entry
of
node usage
, and
head
to the value of the
value
entry
of
node usage
If the
@id
entry
of
node
is an
IRI
instead of a
blank node identifier
exit the while loop.
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 an empty
array
result
For each
subject
and
node
in
default graph
ordered lexicographically by
subject
if
ordered
is
true
If
graph map
has a
subject
entry
Add an
@graph
entry
to
node
and initialize
its value to an empty
array
For each key-value pair
in the
subject
entry
of
graph map
ordered lexicographically by
if
ordered
is
true
append
to the
@graph
entry
of
node
after
removing its
usages
entry
, unless the only
remaining
entry
of
is
@id
Append
node
to
result
after removing its
usages
entry
, unless the only remaining
entry
of
node
is
@id
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
rdfDirection
option set to
i18n-datatype
literals with datatype starting with
are transformed into a
value object
by decoding
the
language tag
and
base direction
from the datatype.
With the
rdfDirection
option set to
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:
value
to be converted to a
map
rdfDirection
and a flag
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
is
true
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
to
true
if the
lexical form
of
value
matches
true
, or
false
if it matches
false
. If it matches neither,
set
type
to
xsd:boolean
Otherwise, if the
datatype
IRI
of
value
equals
xsd:integer
or
xsd:double
and its
lexical form
is a valid
xsd:integer
or
xsd:double
according [
XMLSCHEMA11-2
], set
converted value
to the result of converting the
lexical form
to a JSON
number
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
],
an
invalid JSON literal
error has been detected and processing is aborted.
Otherwise, if the
datatype
IRI
of
value
starts with
and
rdfDirection
is
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.
Note
As
@direction
may be used without
@language
it is possible, and legitimate, to create a datatype
IRI
such as
, 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 10
21
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
Example
20
: Sample integer serialization implementation in JavaScript
(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 10
21
or a
number
coerced to
xsd:double
, consists of a mantissa followed by the
character
, 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
Example
21
: Sample floating point number serialization implementation in JavaScript
(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
].
Example
22
: Canonicalized JSON literal
"@context": {
"@version": 1.1,
"e": {"@id": "http://example.org/vocab#json",
"@type": "@json"
},
"e":
56.0,
"d": true,
"10": null,
"1": [ ]
The example shows the value of "e" as a native JSON array including
unnecessary whitespace, a number and an object. The result
eliminates the whitespace, uses a canonical number representation,
and reorders the
map entries
lexicographically:
@prefix ex:
@prefix rdf:
[ex:json
"""[56,{"1":[],"10":null,"d":true}]"""^^rdf:JSON
] .
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
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
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.
Note
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
code
and processing is stopped.
If the
documentLoader
option is specified, it is used to dereference remote documents and contexts.
The
documentUrl
in the returned
RemoteDocument
is used as
base
IRI
and the
contextUrl
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.
WebIDL
/*
* The JsonLd interface is created to expose the JsonLdProcessor interface.
*/
Global
=JsonLd
Exposed
JsonLd
interface
JsonLd
{};
Exposed
JsonLd
interface
JsonLdProcessor
constructor
();
static
Promise
JsonLdRecord
compact
JsonLdInput
input
optional
JsonLdContext
context
= null,
optional
JsonLdOptions
options
= {});
static
Promise
sequence
JsonLdRecord
>>
expand
JsonLdInput
input
optional
JsonLdOptions
options
= {});
static
Promise
JsonLdRecord
flatten
JsonLdInput
input
optional
JsonLdContext
context
= null,
optional
JsonLdOptions
options
= {});
static
Promise
sequence
JsonLdRecord
>>
fromRdf
RdfDataset
input
optional
JsonLdOptions
options
= {});
static
Promise
RdfDataset
toRdf
JsonLdInput
input
optional
JsonLdOptions
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
not
null
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
extractAllScripts
option from
options
for
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
ordered
set to
false
and
extractAllScripts
defaulting to
false
Set
context base
to the
documentUrl
from
remote document
, if available, otherwise to the
base
option
from
options
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
base
option from
options
, if set;
otherwise, if the
compactToRelative
option is
true
to the
IRI
of the currently being processed document, if available;
otherwise to
null
Set
compacted output
to the result of using the
Compaction algorithm
using
active context
null
for
active property
expanded input
as
element
and the
compactArrays
and
ordered
flags from
options
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
IRI
s.
options
A set of options to configure the algorithms.
This allows, e.g., to set the input document's base
IRI
The
JsonLdOptions
type defines default option values.
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
extractAllScripts
option from
options
for
extractAllScripts
If
document
from
remote document
is a
string
, transform into the
internal representation
If
document
cannot be transformed to the
internal representation
reject
promise
passing a
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
documentUrl
from
remote document
, if available;
otherwise to the
base
option from
options
If set, the
base
option from
options
overrides the
base
IRI
If the
expandContext
option in
options
is set,
update the
active context
using the
Context Processing algorithm
passing the
expandContext
as
local context
and the
original base URL
from
active context
as
base URL
If
expandContext
is a
map
having an
@context
entry
pass that
entry's
value instead for
local context
If
remote document
has a
contextUrl
update the
active context
using the
Context Processing algorithm
passing the
contextUrl
as
local context
and
contextUrl
as
base URL
Set
expanded output
to the result of using the
Expansion algorithm
passing the
active context
document
from
remote document
or
input
if there is no
remote document
as
element
null
as
active property
documentUrl
as
base URL
, if available,
otherwise to the
base
option
from
options
and the
frameExpansion
and
and
ordered
flags from
options
Note
If there is no
remote document
then
input
is
JsonLdRecord
or a
sequence
of
JsonLdRecords
, which are implicitly already in the
internal representation
If
expanded output
is a
map
that contains only an
@graph
entry
set
expanded output
that value.
If
expanded output
is
null
set
expanded output
to an empty
array
If
expanded output
is not an
array
set
expanded output
to an
array
containing only
expanded output
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
JsonLdOptions
type defines default option values.
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
extractAllScripts
option from
options
for
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
ordered
set to
false
Initialize an empty
identifier map
Set
flattened output
to the result of using the
Flattening algorithm
passing
expanded input
as
element
and the
ordered
flag
from
options
If
context
is not
null
set
flattened output
to the result of
using the
compact()
method
using
flattened output
for
input
context
and
options
Set the
base
IRI
in
active context
to the
base
option
from
options
, if set;
otherwise, if the
compactToRelative
option is
true
to the
IRI
of the currently being processed document, if available;
otherwise to
null
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
IRI
s.
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
JsonLdOptions
type defines default option values.
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
Note
This interface does not define a means of creating an
RdfDataset
from an arbitrary input, other than the
toRdf()
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
JsonLdOptions
type defines default option values.
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
ordered
set to
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
produceGeneralizedRdf
flag from
options
Note
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
produceGeneralizedRdf
option may be also be removed.
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
JsonLdOptions
type defines default option values.
WebIDL
typedef
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
WebIDL
typedef
JsonLdRecord
or
sequence
JsonLdRecord
> or
USVString
or
RemoteDocument
JsonLdInput
The
JsonLdInput
interface is used to refer to an input value
that that may be a
JsonLdRecord
sequence
of
JsonLdRecords
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
].
WebIDL
typedef
JsonLdRecord
or
sequence
<(
JsonLdRecord
or
USVString
)> or
USVString
JsonLdContext
The
JsonLdContext
interface is used to refer to a value
that may be a
JsonLdRecord
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
interface
RdfDataset
constructor
();
readonly attribute
RdfGraph
defaultGraph
void
add
USVString
graphName
RdfGraph
graph
);
iterable
USVString
?,
RdfGraph
>;
};
add()
Adds an
RdfGraph
and its associated
graph name
to the
RdfDataset
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 the
RdfDataset
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 an
RdfGraph
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
interface
RdfGraph
constructor
();
void
add
RdfTriple
triple
);
iterable
RdfTriple
>;
};
add()
Adds an
RdfTriple
to the
RdfGraph
Used by the
Deserialize JSON-LD to RDF Algorithm
triple
The
RdfTriple
to add to the
RdfGraph
iterable
value iterator
over the
RdfTriple
instances associated with the graph.
Note that a given
RdfTriple
instance may appear in more than one graph
within a particular
RdfDataset
instance.
The
RdfTriple
interface describes an
triple
WebIDL
Exposed
JsonLd
interface
RdfTriple
constructor
();
readonly attribute
USVString
subject
readonly attribute
USVString
predicate
readonly attribute
USVString
or
RdfLiteral
_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
Note
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
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
interface
RdfLiteral
constructor
();
readonly attribute
USVString
value
readonly attribute
USVString
datatype
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
be
rdf:langString
9.3
The JsonLdOptions Type
The
JsonLdOptions
type is used to pass various options to the
JsonLdProcessor
methods.
WebIDL
dictionary
JsonLdOptions
USVString
base
= null;
boolean
compactArrays
= true;
boolean
compactToRelative
= true;
LoadDocumentCallback
documentLoader
= null;
JsonLdRecord
? or
USVString
expandContext
= null;
boolean
extractAllScripts
= false;
boolean
frameExpansion
= false;
boolean
ordered
= false;
USVString
processingMode
= "json-ld-1.1";
boolean
produceGeneralizedRdf
= true;
USVString
rdfDirection
= null;
boolean
useNativeTypes
= false;
boolean
useRdfType
= 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 to
false
all arrays will remain arrays even if they have just one element.
compactToRelative
Determines if IRIs are compacted
relative to the
base
option
or document location when
compacting
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.
If
false
, order is not considered in processing.
processingMode
Sets the
processing mode
If set to
json-ld-1.0
or
json-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 with
json-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
].
Note
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
produceGeneralizedRdf
option may be also be removed.
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 on
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 of
rdf:value
rdf:direction
, and
rdf:language
(if present)
properties.
When transforming from RDF, this object is decoded to create a
value object
containing
@language
(if present) and
@direction
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
WebIDL
callback
LoadDocumentCallback
Promise
RemoteDocument
USVString
url
optional
LoadDocumentOptions
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 by
application/json
If
requestProfile
is set,
it
MUST
be added as a profile on
application/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 the
alternate
link relation
with type
application/ld+json
set
url
to the associated
href
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
except
application/ld+json
and the response has an HTTP Link Header [
RFC8288
] using the
link relation,
set
contextUrl
to the associated
href
If multiple HTTP Link Headers using the
link relation are found,
the
promise
is rejected with a
JsonLdError
whose
code
is set to
multiple context link headers
and processing is terminated.
Processors
MAY
transform
document
to the
internal representation
Note
The HTTP Link Header is ignored for documents served as
application/ld+json
text/html
, or
application/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 a
loading document failed
error.
Create a new
RemoteDocument
remote document
using
url
as
documentUrl
document
as
document
the returned
Content-Type
(without parameters) as
contentType
any returned
profile
parameter, or
null
as
profile
and
contextUrl
, or
null
as
contextUrl
Resolve the
promise
with
remote document
Note
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
WebIDL
dictionary
LoadDocumentOptions
boolean
extractAllScripts
= false;
USVString
profile
= 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
contentType
is
text/html
or
application/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
interface
RemoteDocument
constructor
();
readonly attribute
USVString
contentType
readonly attribute
USVString
contextUrl
attribute
any
document
readonly attribute
USVString
documentUrl
readonly attribute
USVString
profile
};
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
link relation
in the response.
If the response's
Content-Type
is
application/ld+json
the HTTP Link Header is ignored.
If multiple HTTP Link Headers using the
link relation are found,
the
Promise
of the
LoadDocumentCallback
is rejected
with a
JsonLdError
whose
code
is set to
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
Note
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
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
code
is set to
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
of
application/ld+json
along with the value of the
profile
option, if found.
If
source
is still undefined and the
extractAllScripts
option is not present, or
false
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
code
is set to
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, or
false
the
promise
is rejected with a
JsonLdError
whose
code
is set to
loading document failed
and processing is terminated.
Otherwise, the
extractAllScripts
option is
true
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
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
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.
WebIDL
dictionary
JsonLdError
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.
WebIDL
enum
JsonLdErrorCode
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"
or
null
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
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
nor
null
and thus invalid.
invalid language-tagged string
language-tagged string
with an invalid language value was detected.
invalid language-tagged value
number
true
, or
false
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
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
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
typed value
with an invalid type was detected.
invalid value object
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
nor
null
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
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
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
interface
JsonLd
{};
Exposed
JsonLd
interface
JsonLdProcessor
constructor
();
static
Promise
JsonLdRecord
compact
JsonLdInput
input
optional
JsonLdContext
context
= null,
optional
JsonLdOptions
options
= {});
static
Promise
sequence
JsonLdRecord
>>
expand
JsonLdInput
input
optional
JsonLdOptions
options
= {});
static
Promise
JsonLdRecord
flatten
JsonLdInput
input
optional
JsonLdContext
context
= null,
optional
JsonLdOptions
options
= {});
static
Promise
sequence
JsonLdRecord
>>
fromRdf
RdfDataset
input
optional
JsonLdOptions
options
= {});
static
Promise
RdfDataset
toRdf
JsonLdInput
input
optional
JsonLdOptions
options
= {});
};
typedef
record
USVString
any
JsonLdRecord
typedef
JsonLdRecord
or
sequence
JsonLdRecord
> or
USVString
or
RemoteDocument
JsonLdInput
typedef
JsonLdRecord
or
sequence
<(
JsonLdRecord
or
USVString
)> or
USVString
JsonLdContext
Exposed
JsonLd
interface
RdfDataset
constructor
();
readonly attribute
RdfGraph
defaultGraph
void
add
USVString
graphName
RdfGraph
graph
);
iterable
USVString
?,
RdfGraph
>;
};
Exposed
JsonLd
interface
RdfGraph
constructor
();
void
add
RdfTriple
triple
);
iterable
RdfTriple
>;
};
Exposed
JsonLd
interface
RdfTriple
constructor
();
readonly attribute
USVString
subject
readonly attribute
USVString
predicate
readonly attribute
USVString
or
RdfLiteral
_object
};
Exposed
JsonLd
interface
RdfLiteral
constructor
();
readonly attribute
USVString
value
readonly attribute
USVString
datatype
readonly attribute
USVString
language
};
dictionary
JsonLdOptions
USVString
base
= null;
boolean
compactArrays
= true;
boolean
compactToRelative
= true;
LoadDocumentCallback
documentLoader
= null;
JsonLdRecord
? or
USVString
expandContext
= null;
boolean
extractAllScripts
= false;
boolean
frameExpansion
= false;
boolean
ordered
= false;
USVString
processingMode
= "json-ld-1.1";
boolean
produceGeneralizedRdf
= true;
USVString
rdfDirection
= null;
boolean
useNativeTypes
= false;
boolean
useRdfType
= false;
};
callback
LoadDocumentCallback
Promise
RemoteDocument
USVString
url
optional
LoadDocumentOptions
options
);
dictionary
LoadDocumentOptions
boolean
extractAllScripts
= false;
USVString
profile
= null;
USVString
or
sequence
USVString
>)
requestProfile
= null;
};
Exposed
JsonLd
interface
RemoteDocument
constructor
();
readonly attribute
USVString
contentType
readonly attribute
USVString
contextUrl
attribute
any
document
readonly attribute
USVString
documentUrl
readonly attribute
USVString
profile
};
dictionary
JsonLdError
JsonLdErrorCode
code
USVString
message
= null;
};
enum
JsonLdErrorCode
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.
Issue 76
: More compact @prefix
defer-future-version
More compact @prefix.
Issue 94
: Expansion concept "key's term definition" is unclear with compact IRI keys
defer-future-version
Expansion concept "key's term definition" is unclear with compact
IRI
keys.
Issue 166
: Relationship to the RDF/JS Dataset interface(s)
defer-future-version
Relationship to the RDF/JS Dataset interface(s).
Issue 380
: Expansion does not take property-scoped contexts for nested properties into account
defer-future-version
spec:editorial
test:needs tests
wr:spec-updated-partial
Expansion does not take property-scoped contexts for nested properties into account.
Issue 391
: Recursively nested properties and compaction
defer-future-version
Recursively nested properties and compaction.
Issue 435
: relative iri compaction
defer-future-version
spec:wontfix
wr:pending
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
frameExpansion
flag, to enable content associated with JSON-LD
frames, which may not otherwise be valid
JSON-LD documents
An
expanded term definition
can now have an
@context
entry
, which defines a context used for values of
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
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 value
true
. 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
ordered
option, defaulting to
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
produceGeneralizedRdf
option may be also be removed.
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
contentType
field to
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 the
LoadDocumentCallback
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, allowing
JSON-LD 1.1
features to be added to contexts originally
authored for
JSON-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.
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
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 with
rel=alternate
and
type=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 to
json-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.
Note
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
profile
API option.
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 or
rdf:CompoundLiteral
language tags
are
normalized to lower case to improve interoperability between implementations.
Moved non-recursive portions algorithms
into the
JsonLdProcessor
processing steps.
Fix some
JsonLdOption
initializers where defaults are
null
Set default value for
processingMode
to
json-ld-1.1
Remove normative text for canonicalizing
rdf:JSON
literals and
reference the
rdf: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 a
Promise
boundary issue.
F.
Changes since Candidate Release of 05 March 2020
This section is non-normative.
Note
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 just
true
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 of
invalid 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
JsonLdProcessor
interface
for non-browser usage to address review suggestions.
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:
[DOM]
DOM Standard
. Anne van Kesteren. WHATWG. Living Standard. URL:
[ECMASCRIPT]
ECMAScript Language Specification
. Ecma International. URL:
[HTML]
HTML Standard
. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL:
[IEEE-754-2008]
IEEE 754-2008 Standard for Floating-Point Arithmetic
. Institute of Electrical and Electronics Engineers. 2008. URL:
[INFRA]
Infra Standard
. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL:
[JSON-LD10]
JSON-LD 1.0
. Manu Sporny; Gregg Kellogg; Marcus Langhaler. W3C. 16 January 2014. W3C Recommendation. URL:
[JSON-LD11]
JSON-LD 1.1
. Gregg Kellogg; Pierre-Antoine Champin; Dave Longley. W3C. 7 May 2020. W3C Proposed Recommendation. URL:
[JSON-LD11-FRAMING]
JSON-LD 1.1 Framing
. Dave Longley; Gregg Kellogg; Pierre-Antoine Champin. W3C. 7 May 2020. W3C Proposed Recommendation. URL:
[LINKED-DATA]
Linked Data Design Issues
. Tim Berners-Lee. W3C. 27 July 2006. W3C-Internal Document. URL:
[promises-guide]
Writing Promise-Using Specifications
. Domenic Denicola. W3C. 9 November 2018. TAG Finding. URL:
[RDF-SCHEMA]
RDF Schema 1.1
. Dan Brickley; Ramanathan Guha. W3C. 25 February 2014. W3C Recommendation. URL:
[RDF11-CONCEPTS]
RDF 1.1 Concepts and Abstract Syntax
. Richard Cyganiak; David Wood; Markus Lanthaler. W3C. 25 February 2014. W3C Recommendation. URL:
[RDF11-MT]
RDF 1.1 Semantics
. Patrick Hayes; Peter Patel-Schneider. W3C. 25 February 2014. W3C Recommendation. URL:
[RFC2045]
Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
. N. Freed; N. Borenstein. IETF. November 1996. Draft Standard. URL:
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels
. S. Bradner. IETF. March 1997. Best Current Practice. URL:
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax
. T. Berners-Lee; R. Fielding; L. Masinter. IETF. January 2005. Internet Standard. URL:
[RFC3987]
Internationalized Resource Identifiers (IRIs)
. M. Duerst; M. Suignard. IETF. January 2005. Proposed Standard. URL:
[RFC5234]
Augmented BNF for Syntax Specifications: ABNF
. D. Crocker, Ed.; P. Overell. IETF. January 2008. Internet Standard. URL:
[RFC6839]
Additional Media Type Structured Syntax Suffixes
. T. Hansen; A. Melnikov. IETF. January 2013. Informational. URL:
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words
. B. Leiba. IETF. May 2017. Best Current Practice. URL:
[RFC8259]
The JavaScript Object Notation (JSON) Data Interchange Format
. T. Bray, Ed.. IETF. December 2017. Internet Standard. URL:
[RFC8288]
Web Linking
. M. Nottingham. October 2017. Proposed Standard. URL:
[Turtle]
RDF 1.1 Turtle
. Eric Prud'hommeaux; Gavin Carothers. W3C. 25 February 2014. W3C Recommendation. URL:
[WEBIDL]
Web IDL
. Boris Zbarsky. W3C. 15 December 2016. W3C Editor's Draft. URL:
[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:
I.2
Informative references
[cooluris]
Cool URIs for the Semantic Web
. Leo Sauermann; Richard Cyganiak. W3C. 3 December 2008. W3C Note. URL:
[JSON-LD10-API]
JSON-LD 1.0 Processing Algorithms And API
. Marcus Langhaler; Gregg Kellogg; Manu Sporny. W3C. 16 January 2014. W3C Recommendation. URL:
[RFC8785]
JSON Canonicalization Scheme (JCS)
. A. Rundgren; B. Jordan; S. Erdtman. Network Working Group. June 2020. Informational. URL: