diff --git a/common/algorithm-terms.html b/common/algorithm-terms.html new file mode 100644 index 00000000..e9968d2e --- /dev/null +++ b/common/algorithm-terms.html @@ -0,0 +1,58 @@ +
+
active graph
+ The name of the currently active graph that the processor should use when + processing.
+
active object
+ The currently active object that the processor should use when + processing.
+
active property
+ The currently active property or keyword that the processor + should use when processing. The active property is represented in + the original lexical form, which is used for finding coercion mappings in + the active context.
+
active subject
+ The currently active subject that the processor should use when + processing.
+
explicit inclusion flag
+ A flag specifying that for properties to be included in the output, they + must be explicitly declared in the matching frame.
+
framing state
+ A dictionary containing values for the + object embed flag, the + require all flag, the + explicit inclusion flag, and the + omit default flag.
+
input frame
+ The initial Frame provided to the framing algorithm.
+
JSON-LD input
+ The JSON-LD data structure that is provided as input to the algorithm.
+
JSON-LD output
+ The JSON-LD data structure that is produced as output by the algorithm.
+
map of flattened subjects
+ A map of subjects that is the result of the + Node Map Generation algorithm.
+
object embed flag
+ A flag specifying that node objects should be directly embedded in the output, + instead of being referred to by their IRI.
+
omit default flag
+ A flag specifying that properties that are missing from the + JSON-LD input, but present in the input frame + should be omitted from the output.
+
omit graph flag
+ A flag that determines if framing output is always contained within a + @graph member, or only if required to represent multiple node objects.
+
processor state
+ The processor state, which includes the active + context, active subject, and + active property. The processor state is managed + as a stack with elements from the previous processor state + copied into a new processor state when entering a new + JSON object.
+
promise
+ A promise is an object that represents the eventual result of a single asynchronous operation. + Promises are defined in [[ECMASCRIPT-6.0]].
+
require all flag
+ A flag specifying that all properties present in the input frame + MUST either have a default value or be present in the JSON-LD + input for the frame to match.
+
diff --git a/common/common.js b/common/common.js new file mode 100644 index 00000000..bbcddb8e --- /dev/null +++ b/common/common.js @@ -0,0 +1,194 @@ +/* Web Payments Community Group common spec JavaScript */ +var jsonld = { + // Add as the respecConfig localBiblio variable + // Extend or override global respec references + localBiblio: { + "JSON-LD11": { + title: "JSON-LD 1.1", + href: "https://w3c.github.io/json-ld-syntax/", + authors: ["Gregg Kellogg"], + publisher: "W3C", + status: 'ED' + }, + "JSON-LD11-API": { + title: "JSON-LD 1.1 Processing Algorithms and API", + href: "https://w3c.github.io/json-ld-api/", + authors: ["Gregg Kellogg"], + publisher: "W3C", + status: 'ED' + }, + "JSON-LD11-FRAMING": { + title: "JSON-LD 1.1 Framing", + href: "https://w3c.github.io/json-ld-framing/", + authors: ["Gregg Kellogg"], + publisher: "W3C", + status: 'ED' + }, + "JSON-LD-TESTS": { + title: "JSON-LD 1.1 Test Suite", + href: "https://json-ld.org/test-suite/", + authors: ["Gregg Kellogg"], + publisher: "Linking Data in JSON Community Group" + }, + // aliases to known references + "IEEE-754-2008": { + title: "IEEE 754-2008 Standard for Floating-Point Arithmetic", + href: "http://standards.ieee.org/findstds/standard/754-2008.html", + publisher: "Institute of Electrical and Electronics Engineers", + date: "2008" + }, + "PROMISES": { + title: 'Promise Objects', + href: 'https://github.com/domenic/promises-unwrapping', + authors: ['Domenic Denicola'], + status: 'unofficial', + date: 'January 2014' + }, + "MICROFORMATS": { + title: "Microformats", + href: "http://microformats.org" + } + } +}; + +// We should be able to remove terms that are not actually +// referenced from the common definitions +// +// Add class "preserve" to a definition to ensure it is not removed. +// +// the termlist is in a block of class "termlist", so make sure that +// has an ID and put that ID into the termLists array so we can +// interrogate all of the included termlists later. +var termNames = [] ; +var termLists = [] ; +var termsReferencedByTerms = [] ; + +function restrictReferences(utils, content) { + var base = document.createElement("div"); + base.innerHTML = content; + + // New new logic: + // + // 1. build a list of all term-internal references + // 2. When ready to process, for each reference INTO the terms, + // remove any terms they reference from the termNames array too. + $.each(base.querySelectorAll("dfn:not(.preserve)"), function(i, item) { + var $t = $(item) ; + var titles = $t.getDfnTitles(); + var n = $t.makeID("dfn", titles[0]); + if (n) { + termNames[n] = $t.parent() ; + } + }); + + var $container = $(".termlist", base) ; + var containerID = $container.makeID("", "terms") ; + termLists.push(containerID) ; + return (base.innerHTML); +} + +// add a handler to come in after all the definitions are resolved +// +// New logic: If the reference is within a 'dl' element of +// class 'termlist', and if the target of that reference is +// also within a 'dl' element of class 'termlist', then +// consider it an internal reference and ignore it. + +function internalizeTermListReferences() { + // all definitions are linked; find any internal references + $(".termlist a.internalDFN").each(function() { + var $r = $(this); + var id = $r.attr('href'); + var idref = id.replace(/^#/,"") ; + if (termNames[idref]) { + // this is a reference to another term + // what is the idref of THIS term? + var $def = $r.closest('dd') ; + if ($def.length) { + var $p = $def.prev('dt').find('dfn') ; + var tid = $p.attr('id') ; + if (tid) { + if (termsReferencedByTerms[tid]) { + termsReferencedByTerms[tid].push(idref); + } else { + termsReferencedByTerms[tid] = [] ; + termsReferencedByTerms[tid].push(idref); + } + } + } + } + }); + + // clearRefs is recursive. Walk down the tree of + // references to ensure that all references are resolved. + var clearRefs = function(theTerm) { + if ( termsReferencedByTerms[theTerm] ) { + $.each(termsReferencedByTerms[theTerm], function(i, item) { + if (termNames[item]) { + delete termNames[item]; + clearRefs(item); + } + }); + }; + // make sure this term doesn't get removed + if (termNames[theTerm]) { + delete termNames[theTerm]; + } + }; + + // now termsReferencedByTerms has ALL terms that + // reference other terms, and a list of the + // terms that they reference + $("a.internalDFN").each(function () { + var $item = $(this) ; + var t = $item.attr('href'); + var r = t.replace(/^#/,"") ; + if (r === 'dictionary') { + var rr = r; + } + // if the item is outside the term list + if ( ! $item.closest('dl.termlist').length ) { + clearRefs(r); + } + }); + + // delete any terms that were not referenced. + Object.keys(termNames).forEach(function(term) { + var $p = $("#"+term) ; + if ($p) { + var tList = $p.getDfnTitles(); + $p.parent().next().remove(); + $p.remove() ; + tList.forEach(function( item ) { + if (respecConfig.definitionMap[item]) { + delete respecConfig.definitionMap[item]; + } + }); + } + }); +} + +function _esc(s) { + s = s.replace(/&/g,'&'); + s = s.replace(/>/g,'>'); + s = s.replace(/"/g,'"'); + s = s.replace(/$1'); + content = content.replace(/####([^#]*)####/g, '$1'); + return content ; +} + + +function unComment(doc, content) { + // perform transformations to make it render and prettier + content = content.replace(//, ''); + return content ; +} diff --git a/common/terms.html b/common/terms.html new file mode 100644 index 00000000..e01e86b5 --- /dev/null +++ b/common/terms.html @@ -0,0 +1,295 @@ +
+
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, 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 + Sets and Lists in + the JSON-LD Syntax specification [[JSON-LD11]]).
+
JSON object
+ In the JSON serialization, an object structure is represented as a pair of curly brackets surrounding zero or + more key-value pairs. A key is a string. A single colon comes after + each key, separating the key from the value. A single comma separates a value + from a following key. In JSON-LD the keys in an object MUST be unique. + In the internal representation a JSON object is equivalent to a + dictionary (see [[WEBIDL]]).
+
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, dictionaries, + strings, numbers, booleans, and null.
+
null
+ The use of the null value within JSON-LD is used to + ignore or reset values. A key-value pair in the @context where + the value, or the @id of the value, is null + explicitly decouples a term's association with an IRI. A key-value pair in + the body of a JSON-LD document whose value is null has the + same meaning as if the key-value pair was not defined. If + @value, @list, or @set is set to + null in expanded form, then the entire JSON + object is ignored.
+
number
+ In the JSON serialization, a number is similar to that used in most programming languages, except + that the octal and hexadecimal formats are not used and that leading + zeros are not allowed. + In the internal representation, a number is equivalent to either + a long + or double, depending + on if the number has a non-zero fractional part (see [[WEBIDL]]).
+
scalar
+ A scalar is either a JSON string, number, true, + or false.
+
string
+ A string is a sequence of zero or more Unicode (UTF-8) characters, + wrapped in double quotes, using backslash escapes (if necessary). A + character is represented as a single character string.
+
true and false
+ Values that are used to express one of two possible + boolean states.
+
+ +

Furthermore, the following terminology is used throughout this document:

+ +
+
absolute IRI
+ An absolute IRI is defined in [[!RFC3987]] containing a scheme along with a path and + optional query and fragment segments.
+
active context
+ A context that is used to resolve terms while the processing + algorithm is running.
+
base IRI
+ The base IRI is an absolute IRI established in the context, + or is based on the JSON-LD document location. The base IRI is used to turn + relative IRIs into absolute IRIs.
+
blank node
+ A node in a graph that is neither an + IRI, nor a JSON-LD value, nor a list. + A blank node does not contain a de-referenceable + identifier because it is either ephemeral in nature or does not contain information that needs to be + linked to from outside of the linked data graph. A blank node is assigned an identifier starting with + the prefix _:.
+
blank node identifier
+ A blank node identifier is a string that can be used as an identifier for a + blank node within the scope of a JSON-LD document. Blank node identifiers + begin with _:.
+
compact IRI
+ A compact IRI is 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 specified in + The Context of the JSON-LD Syntax specification [[JSON-LD11]].
+
datatype IRI
+ A datatype IRI + as specified by [[RDF11-CONCEPTS]].
+
default graph
+ The default graph is the only graph in a JSON-LD document which has no graph name. + When executing an algorithm, the graph where data should be placed + if a named graph is not specified.
+
default language
+ The default language is set in the context using the @language key whose + value MUST be a string representing a [[!BCP47]] language code or null.
+
default object
+ A default object is a JSON object that has a @default member.
+
edge
+ Every edge has a direction associated with it and is labeled with + an IRI or a blank node identifier. Within the JSON-LD syntax + these edge labels are called properties. Whenever possible, an + edge should be labeled with an IRI.
+
expanded term definition
+ An expanded term definition, is a term definition where the value is a JSON object + containing one or more keyword properties to define the associated absolute IRI, + if this is a reverse property, the type associated with string values, and a container mapping.
+
Frame
+ A JSON-LD document, which describes the form for transforming + another JSON-LD document using matching and embedding rules. + A frame document allows additional keywords and certain property values + to describe the matching and transforming process.
+
JSON-LD Processor
+ A JSON-LD Processor is a system which can perform the algorithms defined in [[JSON-LD11-API]].
+
frame object
+ A frame object is a dictionary element within a frame + which represents a specific portion of the frame matching either a + node object or a value object in the input.
+
graph name
+ The IRI identifying a named graph.
+
id map
+ An id map is a JSON object value of a term defined with + @container set to @id, who's keys are + interpreted as IRIs representing the @id + of the associated node object; value MUST be a node object. + If the value contains a property expanding to @id, it's value MUST + be equivalent to the referencing key.
+
graph object
+ A graph object represents a named graph represented as the + value of a property within a node object. When expanded, a + graph object MUST have an @graph member, and may also have + @id, and @index members. + A simple graph object is a + graph object which does not have an @id member. Note + that node objects may have a @graph member, but are + not considered graph objects if they include any other properties. + A top-level object consisting of @graph is also not a graph object.
+
index map
+ An index map is a JSON object 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. +
+
IRI
+ An Internationalized Resource Identifier as described in [[!RFC3987]].
+
JSON-LD document
+ A JSON-LD document is a serialization of a collection of + graphs and comprises exactly one + default graph and zero or more named graphs.
+
JSON-LD value
+ A JSON-LD value is a string, a number, + true or false, a typed value, or a + language-tagged string.
+
keyword
+ A JSON key that is specific to JSON-LD, specified in the JSON-LD Syntax specification [[JSON-LD11]] + in the section titled Syntax Tokens and Keywords.
+
language map
+ An language map is a JSON object 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. +
+
language-tagged string
+ A language-tagged string consists of a string and a non-empty language + tag as defined by [[!BCP47]]. The language tag MUST be well-formed according to + section 2.2.9 Classes of Conformance + of [[!BCP47]], and is normalized to lowercase.
+
Linked Data
+ A set of documents, each containing a representation of a linked data graph.
+
linked data graph
+ A labeled directed graph, i.e., a set of nodes + connected by edges, + as specified in the Data Model + section of the JSON-LD specification [[JSON-LD11]]. + A linked data graph is a generalized representation of an + RDF graph + as defined in [[!RDF-CONCEPTS]].
+
list
+ A list is an ordered sequence of IRIs, + blank nodes, and JSON-LD values. + See RDF collection + in [[RDF-SCHEMA]].
+
list object
+ A list object is a JSON object that has an @list + member.
+
literal
+ An object expressed as a value such as a string, number or in expanded form.
+
local context
+ A context that is specified within a JSON object, + specified via the @context keyword.
+
named graph
+ A named graph is a linked data graph that is identified by an IRI or blank node.
+
implicitly named graph
+ A named graph created from the value of a property having an + expanded term definition where @container is set to @graph.
+
nested property
+ A nested property is a property which is contained within an object referenced by + a semantically meaningless nesting property. +
+
node
+ Every node is an IRI, a blank node, + a JSON-LD value, or a list. + A piece of information that is represented in a linked data graph.
+
node object
+ A node object represents zero or more properties of a + node in the graph serialized by the + JSON-LD document. A JSON object is a node object + if it exists outside of the JSON-LD context and: + +
+
node reference
+ A node object used to reference a node having only the + @id key.
+
object
+ An object is a node in a linked data graph with at least one incoming edge. + See RDF objectin [[RDF11-CONCEPTS]].
+
prefix
+ A prefix is the first component of a compact IRI which comes from a + term that maps to a string that, when prepended to the suffix of the compact IRI + results in an absolute IRI.
+
processing mode
+ The processing mode defines how a JSON-LD document is processed. + By default, all documents are assumed to be conformant with + JSON-LD 1.0 [[!JSON-LD]]. By defining + a different version using the @version member in a + context, or via explicit API option, other processing modes + can be accessed. This specification defines extensions for the + json-ld-1.1 processing mode.
+
property
+ The IRI label of an edge in a linked data graph. + See RDF predicate in [[RDF11-CONCEPTS]].
+
quad
+ A piece of information that contains four items; a subject, a property, + an object, and a graph name.
+
RDF dataset
+ A dataset as specified by [[RDF11-CONCEPTS]] representing a collection of + RDF graphs.
+
RDF resource
+ A resource as specified by [[RDF11-CONCEPTS]].
+
RDF triple
+ A triple as specified by [[RDF11-CONCEPTS]].
+
relative IRI
+ A relative IRI is an IRI that is relative to some other absolute IRI, + typically the base IRI of the document. Note that + properties, values of @type, and values of terms defined to be vocabulary relative + are resolved relative to the vocabulary mapping, not the base IRI.
+
set object
+ A set object is a JSON object that has an @set + member.
+
subject
+ A subject is anode in a linked data graph with at least one outgoing edge, related to an object node through a property. + See RDF subject in [[RDF11-CONCEPTS]].
+
term
+ A term is a short word defined in a context that MAY be expanded to an IRI +
+
term definition
+ A term definition is an entry in a context, where the key defines a term which may be used within + a JSON object as a property, type, or elsewhere that a string is interpreted as a vocabulary item. + Its value is either a string (simple term definition), expanding to an absolute IRI, or an expanded term definition. +
+
type map
+ An type map is a JSON object value of a term defined with + @container set to @type, who's keys are + interpreted as IRIs representing the @type + of the associated node object; + value MUST be a node object, or array of node objects. + If the value contains a property expanding to @type, it's values + are merged with the map value when expanding.
+
typed literal
+ A typed literal is a literal with an associated IRI + which indicates the literal's datatype. + See RDF literal in [[!RDF-CONCEPTS]].
+
typed value
+ A typed value consists of a value, which is a string, and a type, + which is an IRI.
+
value object
+ A value object is a JSON object that has an @value + member.
+
vocabulary mapping
+ The vocabulary mapping is set in the context using the @vocab key whose + value MUST be an absolute IRI null.
+
diff --git a/common/typographical-conventions.html b/common/typographical-conventions.html new file mode 100644 index 00000000..e2a2fcf7 --- /dev/null +++ b/common/typographical-conventions.html @@ -0,0 +1,31 @@ +

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 are highlighted.
+
+ +

Notes are in light green boxes with a green left border and with a "Note" header in green. Notes are normative or informative depending on the whether they are in a normative or informative section, respectively.

+ +
+  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.
diff --git a/index.html b/index.html index a29593f3..e99fdea7 100644 --- a/index.html +++ b/index.html @@ -1,38 +1,5055 @@ - + - - - Spec proposal - - + + + + + + +
+

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 document has been developed by the + JSON-LD Working Group.

+ + + +
+

Set of Documents

+

This document is one of three JSON-LD 1.1 Recommendations produced by the + JSON-LD Working Group:

+ + +
+
+ + +
+

Introduction

+ +

This document is a detailed specification of the JSON-LD processing algorithms. + The document is primarily intended for the following audiences:

+ + + +

To understand the basics in this specification you must first be familiar with + JSON, which is detailed in [[!RFC7159]]. 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-6.0]] and + WebIDL [[WEBIDL]]. To understand how JSON-LD maps to RDF, it is helpful to be + familiar with the basic RDF concepts [[RDF11-CONCEPTS]].

+ +
+

Contributing

+ +

There are a number of ways that one may participate in the development of + this specification:

+ + + +
+ +
+

Terminology

+ +

This document uses the following terms as defined in JSON [[!RFC7159]]. Refer + to the JSON Grammar section in [[!RFC7159]] for formal definitions.

+ +
+
+ +
+

Algorithm Terms

+ +

The Following terms are used within specific algorithms.

+ +
+
+
+ +
+ +
+

Typographical conventions

+
+
+ +
+

Example Conventions

+

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 dictionaries are represented using + JSON objects.

+ +
+    
+    
+

In the internal representation, the example above would be of a + dictionary containing @context, @id, name, and knows keys, + with either dictionaries, strings, or arrays of + dictionaries or strings values. In the JSON serialization, JSON objects are used + for dictionaries, while arrays and strings are serialized using a + convention common to many programming languages.

+
+ +
+ + +
+

Features

+ +

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, dictionaries, + 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-LD]], + but if processed by a JSON-LD 1.0 processor may produce different results. + In order to detect this JSON-LD 1.1 requires that the processing + mode be explicitly set to json-ld-1.1, either through the + processingMode API option, or using the + @version member within a context.

+ +

There are four major types of transformation that are discussed in this + document: expansion, compaction, flattening, and RDF serialization/deserialization.

+ +
+

Expansion

+ +

The algorithm that removes context is + called expansion. Before performing any other + transformations on a JSON-LD document, it is easiest to + remove any context from it and to make data structures + more regular.

+ +

To get an idea of how context and data structuring affects the same data, + here is an example of JSON-LD that uses only terms + and is fairly compact:

+ +
+    
+    
+ + - - -
-

- This specification does neat stuff. -

-
-
-

- This is an unofficial proposal. -

-
- -
-

Introduction

-

- See ReSpec's user guide - for how toget started! -

-
- + +

The next input example uses one IRI to express a property + and an array to encapsulate another, but + leaves the rest of the information untouched.

+ +
+    
+    
+ +

Note that both inputs are valid JSON-LD and both represent the same + information. The difference is in their context information + and in the data structures used. A JSON-LD processor can remove + context and ensure that the data is more regular by employing + expansion.

+ +

Expansion has two important goals: removing any contextual + information from the document, and ensuring all values are represented + in a regular form. These goals are accomplished by expanding all properties + to absolute 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:

+ +
+    
+    
+ +

The example above is the JSON-LD serialization of the output of the + expansion algorithm, + where the algorithm's use of dictionaries are replaced with JSON objects.

+ +

Note that in the output above all context definitions have + been removed, all terms and + compact IRIs have been expanded to absolute + IRIs, and all + JSON-LD values are expressed in + arrays in expanded form. While the + output is more verbose and difficult for a human to read, it establishes a + baseline that makes JSON-LD processing easier because of its very regular + structure.

+
+ +
+

Compaction

+ +

While expansion removes context from a given + input, compaction's primary function is to + perform the opposite operation: to express a given input according to + a particular context. Compaction applies a + context that specifically tailors the way information is + expressed for a particular person or application. This simplifies applications + that consume JSON or JSON-LD by expressing the data in application-specific + terms, and it makes the data easier to read by humans.

+ +

Compaction uses a developer-supplied context to + shorten IRIs to terms or + compact IRIs and + JSON-LD values expressed in + expanded form to simple values such as strings + or numbers.

+ +

For example, assume the following expanded JSON-LD input document:

+ +
+    
+    
+ +

Additionally, assume the following developer-supplied JSON-LD + context:

+ +
+    
+    
+ +

Running the Compaction Algorithm + (compact) + operation) given the context supplied above against the JSON-LD input + document provided above would result in the following output:

+ +
+    
+    
+ +

The example above is the JSON-LD serialization of the output of the + compaction algorithm, + where the algorithm's use of dictionaries are replaced with JSON objects.

+ +

Note that all IRIs have been compacted to + terms as specified in the context, + which has been injected into the output. While compacted output is + useful to humans, it is also used to generate structures that are easy to + program against. Compaction enables developers to map any expanded document + into an application-specific compacted document. While the context provided + above mapped http://xmlns.com/foaf/0.1/name to name, it + could also have been mapped to any other term provided by the developer.

+
+ +
+

Flattening

+ +

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 + dictionaries. By flattening a + document, all properties of a node are collected in a single + dictionary 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:

+ +
+    
+    
+ +

Running the Flattening Algorithm + (flatten) + operation) with a context set to null to prevent compaction + returns the following document:

+ +
+    
+    
+ +

The example above is the JSON-LD serialization of the output of the + flattening algorithm, + where the algorithm's use of dictionaries are replaced with JSON objects.

+ +

Note how in the output above all properties of a node are collected in a + single dictionary and how the blank node representing + "Dave Longley" has been assigned the blank node identifier + _:t0.

+ +

To make it easier for humans to read or for certain applications to + process it, a flattened document can be compacted by passing a context. Using + the same context as the input document, the flattened and compacted document + looks as follows:

+ +
+    
+    
+ +

Please note that the result of flattening and compacting a document + is always a dictionary, + (represented as a JSON object when serialized), + which contains an @graph + member that represents the default graph.

+
+ +
+

RDF Serialization/Deserialization

+ +

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]]:

+ +
+    
+    
+ +

Using the Serialize RDF as JSON-LD algorithm + a developer could transform this document into expanded JSON-LD:

+ +
+    
+    
+ +

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

+
+
+ + +
+

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

+ +

The algorithms in this specification are generally written with more concern for clarity + than efficiency. Thus, JSON-LD Processors may + implement the algorithms given in this specification in any way desired, + so long as the end result is indistinguishable from the result that would + be obtained by the specification's algorithms.

+ +

In algorithm steps that describe operations on keywords, those steps + also apply to keyword aliases.

+ +

Implementers can partially check their level of conformance to + this specification by successfully passing the test cases of the JSON-LD test + suite [[JSON-LD-TESTS]]. 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.

+
+ +
+

Context Processing Algorithms

+ +
+

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 contains the active + term definitions which specify how + properties and values have to be interpreted as well as the current base IRI, + the vocabulary mapping and the default language. Each + term definition consists of an IRI mapping, a boolean + flag reverse property, an optional type mapping + or language mapping, + an optional context, + an optional nest value, + an optional prefix flag, + and an optional container mapping. + A term definition can not only be used to map a term + to an IRI, but also to map a term to a keyword, + in which case it is referred to as a keyword alias.

+ +

When processing, active context is initialized + without any term definitions, + vocabulary mapping, 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.

+ +
+

Overview

+ +

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 + dictionary, a string, or an array containing + a combination of the two. Finally we process each context contained + in the local context array as follows.

+ +

Unless specified using + processingMode API option, + the processing mode is set using the @version member + in a local context and + affects the behavior of algorithms including expansion and compaction.

+ +

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 key of the top-level object in the + retrieved JSON-LD document. If there's no such key, 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 dictionary, we first update the + base IRI, the vocabulary mapping, processing mode, and the + default language by processing three specific keywords: + @base, @vocab, @version, and @language. + These are handled before any other keys in the local context because + they affect how the other keys are processed. Please note that @base is + ignored when processing remote contexts.

+ +

Then, for every other key in local context, we update + the term definition in result. Since + term definitions in a local context + may themselves contain terms or + compact IRIs, we may need to recurse. + When doing so, we must ensure that there is no cyclical dependency, + which is an error. After we have processed any + term definition dependencies, + we update the current term definition, + which may be a keyword alias.

+ +

Finally, we return result as the new active context.

+
+ +
+

Algorithm

+ +

This algorithm specifies how a new active context is updated + with a local context. The algorithm takes three input variables: + an active context, a local context, and an array + remote contexts which is used to detect cyclical context inclusions. + If remote contexts is not passed, it is initialized to an empty + array.

+ +
    +
  1. Initialize result to the result of cloning + active context.
  2. +
  3. If local context is not an array, + set it to an array containing only + local context.
  4. +
  5. + For each item context in local context: +
      +
    1. If context is null, set result to a + newly-initialized active context and continue with the + next context. + In JSON-LD 1.0, the base IRI was given + a default value here; this is now described conditionally + in .
    2. +
    3. If context is a string, +
        +
      1. Set context to the result of resolving value against + the base IRI which is established as specified in + section 5.1 Establishing a Base URI + of [[!RFC3986]]. 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]].
      2. +
      3. If context is in the remote contexts array, a + recursive context inclusion + error has been detected and processing is aborted; + otherwise, add context to remote contexts.
      4. +
      5. If context was previously dereferenced, + then the processor MUST NOT do a further dereference, and + context is set to the + previously established internal representation.
      6. +
      7. Otherwise, dereference context, transforming into the internal representation. + If context cannot be dereferenced, + or cannot be transformed into the internal representation, + a loading remote context failed + error has been detected and processing is aborted. If the dereferenced document has no + top-level dictionary with an @context member, an + invalid remote context + has been detected and processing is aborted; otherwise, + set context to the value of that member.
      8. +
      9. Set result to the result of recursively calling this algorithm, + passing result for active context, + context for local context, and a copy of remote contexts.
      10. +
      11. Continue with the next context.
      12. +
      +
    4. +
    5. If context is not a dictionary, an + invalid local context + error has been detected and processing is aborted.
    6. +
    7. If context has an @base key and remote contexts is empty, i.e., the currently + being processed context is not a remote context: +
        +
      1. Initialize value to the value associated with the + @base key.
      2. +
      3. If value is null, remove the + base IRI of result.
      4. +
      5. Otherwise, if value is an absolute IRI, + the base IRI of result is set to value.
      6. +
      7. Otherwise, if value is a relative IRI 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.
      8. +
      9. Otherwise, an + invalid base IRI + error has been detected and processing is aborted.
      10. +
      +
    8. +
    9. If context has an @version key: +
        +
      1. If the associated value is not 1.1, + an invalid @version value + has been detected, and processing is aborted.
      2. +
      3. If processing mode + is set to json-ld-1.0, + a processing mode conflict + error has been detected and processing is aborted.
      4. +
      5. Set processing mode, + to json-ld-1.1, if not already set.
      6. +
      +
    10. +
    11. If context has an @vocab key: +
        +
      1. Initialize value to the value associated with the + @vocab key.
      2. +
      3. If value is null, remove + any vocabulary mapping from result.
      4. +
      5. Otherewise, if value + the empty string (""), + the effective value is the current base IRI.
      6. +
      7. Otherwise, if value is + an absolute IRI + or blank node identifier, the vocabulary mapping + of result is set to value. If it is not + an absolute IRI, or a blank node identifier, an + invalid vocab mapping + error has been detected and processing is aborted.
      8. +
      +
    12. +
    13. If context has an @language key: +
        +
      1. Initialize value to the value associated with the + @language key.
      2. +
      3. If value is null, remove + any default language from result.
      4. +
      5. Otherwise, if value is string, the + default language of result is set to + lowercased value. If it is not a string, an + invalid default language + error has been detected and processing is aborted.
      6. +
      +
    14. +
    15. Create a dictionary defined to use to keep + track of whether or not a term has already been defined + or currently being defined during recursion.
    16. +
    17. For each key-value pair in context where + key is not @base, @vocab, or + @language, invoke the + Create Term Definition algorithm, + passing result for active context, + context for local context, key, + and defined.
    18. +
    +
  6. +
  7. Return result.
  8. +
+
+
+ +
+

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.

+ +
+

Overview

+ +

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 + a key 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 or language mapping for the + term.

+
+ +
+

Algorithm

+ +

The algorithm has four required inputs which are: + an active context, a local context, + a term, and a map defined.

+ +
    +
  1. If defined contains the key 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.
  2. +
  3. Set the value associated with defined's term key to + false. This indicates that the term definition + is now being created but is not yet complete.
  4. +
  5. Since keywords cannot be overridden, + term must not be a keyword. Otherwise, a + keyword redefinition + error has been detected and processing is aborted.
  6. +
  7. Remove any existing term definition for term in + active context.
  8. +
  9. Initialize value to a copy of the value associated with the key + term in local context.
  10. +
  11. If value is null or value + is a dictionary containing the key-value pair + @id-null, set the + term definition in active context to + null, set the value associated with defined's + key term to true, and return.
  12. +
  13. Otherwise, if value is a string, convert it + to a dictionary consisting of a single member whose + key is @id and whose value is value. + Set simple term to true.
  14. +
  15. Otherwise, value must be a dictionary, if not, an + invalid term definition + error has been detected and processing is aborted. + Set simple term to false.
  16. +
  17. Create a new term definition, definition.
  18. +
  19. If value contains the key @type: +
      +
    1. Initialize type to the value associated with the + @type key, which must be a string. Otherwise, an + invalid type mapping + error has been detected and processing is aborted.
    2. +
    3. Set type to the result of using the + IRI Expansion algorithm, passing + active context, type for value, + true for vocab, + local context, and defined. If the expanded type is + neither @id, nor @vocab, nor an absolute IRI, an + invalid type mapping + error has been detected and processing is aborted.
    4. +
    5. Set the type mapping for definition to type.
    6. +
    +
  20. +
  21. If value contains the key @reverse: +
      +
    1. If value contains @id or @nest, members, an + invalid reverse property + error has been detected and processing is aborted.
    2. +
    3. If the value associated with the @reverse key + is not a string, an + invalid IRI mapping + error has been detected and processing is aborted.
    4. +
    5. Otherwise, set the IRI mapping of definition to the + result of using the IRI Expansion algorithm, + passing active context, the value associated with + the @reverse key for value, true + for vocab, + local context, and defined. If the result + is neither an absolute IRI nor a blank node identifier, + i.e., it contains no colon (:), an + invalid IRI mapping + error has been detected and processing is aborted.
    6. +
    7. If value contains an @container member, + set the container mapping of definition + to 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.
    8. +
    9. Set the reverse property flag of definition + to true.
    10. +
    11. Set the term definition of term in + active context to definition and the + value associated with defined's key term to + true and return.
    12. +
    +
  22. +
  23. Set the reverse property flag of definition + to false.
  24. +
  25. If value contains the key @id and its value + does not equal term: +
      +
    1. If the value associated with the @id key is not a string, an + invalid IRI mapping + error has been detected and processing is aborted.
    2. +
    3. Otherwise, set the IRI mapping of definition to the + result of using the IRI Expansion algorithm, passing + active context, the value associated with the @id key for + value, true for vocab, + local context, and defined. If the resulting + IRI mapping is neither a keyword, nor an + absolute 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.
    4. +
    5. If term does not contain a colon (:), + simple term is true, and the, + IRI mapping of definition ends with a URI + gen-delim character, + set the prefix flag in definition to true.
    6. +
    +
  26. +
  27. + Otherwise if the term contains a colon (:): +
      +
    1. If term is a compact IRI with a + prefix that is a key in local context + a dependency has been found. Use this algorithm recursively passing + active context, local context, the + prefix as term, and defined.
    2. +
    3. 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.
    4. +
    5. Otherwise, term is an absolute IRI or + blank node identifier. Set the IRI mapping + of definition to term.
    6. +
    +
  28. +
  29. 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.
  30. +
  31. If value contains the key @container: +
      +
    1. Initialize container to the value associated with the + @container key, which must be either + @graph, + @id, + @index, + @language, + @list, + @set, or + @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, @id, @type, + @language in any order + . + Otherwise, an + invalid container mapping + has been detected and processing is aborted.
    2. +
    3. If processingMode + is json-ld-1.0 and the container value + is @graph, @id, or @type, or is otherwise not a string, an + invalid container mapping + has been detected and processing is aborted.
    4. +
    5. Set the container mapping of definition to + container.
    6. +
    +
  32. +
  33. If value contains the key @context: +
      +
    1. If processingMode is json-ld-1.0, an + invalid term definition + has been detected and processing is aborted.
    2. +
    3. Initialize context to the value associated with the + @context key, which is treated as a local context.
    4. +
    5. Invoke the Context Processing algorithm + using the active context and context as local context. + If any error is detected, an + invalid scoped context error + has been detected and processing is aborted.
    6. +
    7. Set the local context of definition to context.
    8. +
    +
  34. +
  35. If value contains the key @language and + does not contain the key @type: +
      +
    1. Initialize language to the value associated with the + @language key, which must be either null + or a string. Otherwise, an + invalid language mapping + error has been detected and processing is aborted.
    2. +
    3. If language is a string set it to + lowercased language. Set the language mapping + of definition to language.
    4. +
    +
  36. +
  37. If value contains the key @nest: +
      +
    1. If processingMode is json-ld-1.0, an + invalid term definition + has been detected and processing is aborted.
    2. +
    3. Initialize nest value in defined to the value associated with the + @nest key, 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.
    4. +
    +
  38. +
  39. If value contains the key @prefix: +
      +
    1. If processingMode is json-ld-1.0, or if + term contains a colon (:), an + invalid term definition + has been detected and processing is aborted.
    2. +
    3. Initialize the prefix flag to the value associated with the + @prefix key, which must be a boolean. Otherwise, an + invalid @prefix value + error has been detected and processing is aborted.
    4. +
    +
  40. +
  41. If the value contains any key other than @id, + @reverse, @container, + @context, @nest, + @prefix, or @type, an + invalid term definition error has + been detected and processing is aborted.
  42. +
  43. Set the term definition of term in + active context to definition and set the value + associated with defined's key term to + true.
  44. +
+
+
+ +
+

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.

+ +
+

Overview

+ +

In order to expand value to an absolute IRI, we must + first determine if it is null, a term, a + keyword alias, or some form of IRI. Based on what + we find, we handle the specific kind of expansion; for example, we expand + a keyword alias to a keyword and a term + to an absolute 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 + a key in the local context and the defined map + does not have a key for value with an associated value of + true. The defined map is used during + Context Processing to keep track of + which terms have already been defined or are + in the process of being defined. We create a + term definition by using the + Create Term Definition algorithm.

+
+ +
+

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 + against the document's base IRI or the + active context's + vocabulary mapping, respectively, and + a local context and a map defined to be used when + this algorithm is used during Context Processing. + If not passed, the two flags are set to false and + local context and defined are initialized to null.

+ +
    +
  1. If value is a keyword or null, + return value as is.
  2. +
  3. If local context is not null, it contains + a key that equals value, and the value associated with the key + that equals 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 + a term definition is created for value in + active context during Context Processing. +
  4. +
  5. If active context has a term definition for + value, and the associated IRI mapping is a keyword, + return that keyword.
  6. +
  7. If vocab is true and the + active context has a term definition for + value, return the associated IRI mapping.
  8. +
  9. If value contains a colon (:), it is either + an absolute IRI, a compact IRI, or a + blank node identifier: +
      +
    1. Split value into a prefix and suffix + at the first occurrence of a colon (:).
    2. +
    3. If prefix is underscore (_) + or suffix begins with double-forward-slash + (//), return value as it is already an + absolute IRI or a blank node identifier.
    4. +
    5. If local context is not null, it + contains a key that equals prefix, and the value + associated with the key that equals prefix 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.
    6. +
    7. If active context contains a term definition + for prefix, return the result of concatenating + the IRI mapping associated with prefix and + suffix.
    8. +
    9. Return value as it is already an absolute IRI.
    10. +
    +
  10. +
  11. If vocab is true, and + active context has a vocabulary mapping, + return the result of concatenating the vocabulary mapping + with value.
  12. +
  13. Otherwise, if document relative is true + set value to the result of resolving value against + the base IRI. 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]].
  14. +
  15. Return value as is.
  16. +
+
+
+
+ + +
+

Expansion Algorithms

+ +
+

Expansion Algorithm

+ +

This algorithm expands a JSON-LD document, such that all context + definitions are removed, all terms and + compact IRIs are expanded to + absolute IRIs, + blank node identifiers, or + keywords and all + JSON-LD values are expressed in + arrays in expanded form.

+ +
+

Overview

+ +

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:

+ +
    +
  1. If the element is null, there is nothing + to expand.
  2. +
  3. Otherwise, if element is a scalar, we expand it + according to the Value Expansion algorithm.
  4. +
  5. Otherwise, if the element is an array, then we expand + each of its items recursively and return them in a new + array.
  6. +
  7. Otherwise, element is a dictionary. We expand + each of its keys, adding them to our result, and then we expand + each value for each key recursively. Some of the keys will be + terms or + compact IRIs and others will be + keywords or simply ignored because + they do not have definitions in the context. Any + IRIs will be expanded using the + IRI Expansion algorithm. +
  8. +
+ +

Finally, after ensuring result is in an array, + we return result.

+
+ +
+

Algorithm

+ +

The algorithm takes three required and one optional input variables. + The required inputs are an active context, + an active property, and an element to be expanded. + The optional input is the flag frame expansion the allows + special forms of input used for frame expansion. + To begin, the active property is set to null, + and element is set to the JSON-LD input. + If not passed, the frame expansion flag is set to false.

+ +

The algorithm also performs processing steps specific to expanding + a JSON-LD Frame. For a frame, the @id and + @type properties can accept an array of IRIs or + an empty dictionary. The properties of a value object can also + accept an array of strings, or an empty dictionary. + Framing also uses additional keyword properties: + (@explicit, @default, + @embed, @explicit, @omitDefault, or + @requireAll) which are preserved through expansion. + Special processing for a JSON-LD Frame is invoked when the + frame expansion flag is set to true.

+ +
    +
  1. If element is null, return null.
  2. +
  3. If active property is @default, + set the frame expansion flag to false.
  4. +
  5. If element is a scalar, +
      +
    1. If active property is null or @graph, + drop the free-floating scalar by returning null.
    2. +
    3. Return the result of the + Value Expansion algorithm, passing the + active context, active property, and + element as value.
    4. +
    +
  6. +
  7. If element is an array, +
      +
    1. Initialize an empty array, result.
    2. +
    3. For each item in element: +
        +
      1. Initialize expanded item to the result of using this + algorithm recursively, passing active context, + active property, item as element, + and the frame expansion flag.
      2. +
      3. If the active property is @list or its + container mapping includes @list, the + expanded item must not be an array or a + list object, otherwise a + list of lists + error has been detected and processing is aborted.
      4. +
      5. If expanded item is an array, append each + of its items to result. Otherwise, if + expanded item is not null, append it to result.
      6. +
      +
    4. +
    5. Return result.
    6. +
    +
  8. +
  9. Otherwise element is a dictionary.
  10. +
  11. If element contains the key @context, set + active context to the result of the + Context Processing algorithm, + passing active context and the value of the + @context key as local context.
  12. +
  13. For each key/value pair in element + where key expands to @type using the + IRI Expansion algorithm, + passing active context, key for + value, and true for vocab: +
      +
    1. For each term which is a value of value ordered lexicographically, + if term's term definition in active context + has a local context, set active context to the result + to the result of the + Context Processing algorithm, + passing active context and the value of the + term's local context as local context.
    2. +
    +
  14. +
  15. Initialize an empty dictionary, result.
  16. +
  17. For each key and value in element, + ordered lexicographically by key: +
      +
    1. If key is @context, continue to + the next key.
    2. +
    3. Set expanded property to the result of + using the IRI Expansion algorithm, + passing active context, key for + value, and true for vocab.
    4. +
    5. If expanded property is null or it neither + contains a colon (:) nor it is a keyword, + drop key by continuing to the next key.
    6. +
    7. If expanded property is a keyword: +
        +
      1. If active property equals @reverse, an + invalid reverse property map + error has been detected and processing is aborted.
      2. +
      3. If result has already an expanded property member, a + colliding keywords + error has been detected and processing is aborted.
      4. +
      5. If expanded property is @id and + value is not a string, an + invalid @id value + error has been detected and processing is aborted. Otherwise, + set expanded value to the result of using the + IRI Expansion algorithm, + passing active context, value, and true + for document relative. + + When the frame expansion flag is set, value + may be an empty dictionary, or an array of one + or more strings. expanded value will be + an array of one or more of these, with string + values expanded using the IRI Expansion Algorithm.
      6. +
      7. If expanded property is @type and value + is neither a string nor an array of + strings, an + invalid type value + error has been detected and processing is aborted. Otherwise, + set expanded value to the result of using the + IRI Expansion algorithm, passing + active context, true for vocab, + and true for document relative to expand the value + or each of its items. + + When the frame expansion flag is set, value + may also be an empty dictionary.
      8. +
      9. 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, + and the frame expansion flag, + + ensuring that expanded value is an array of one or more dictionaries.
      10. +
      11. If expanded property is @value and + value is not a scalar or null, an + invalid value object value + error has been detected and processing is aborted. Otherwise, + set expanded value to value. If expanded value + is null, set the @value + member 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 member depends + on the existence of an @value member. + + When the frame expansion flag is set, value + may also be an empty dictionary or an array of + scalar values. expanded value will be null, or an + array of one or more scalar values.
      12. +
      13. If expanded property is @language and + value is not a string, an + invalid language-tagged string + error has been detected and processing is aborted. + + Otherwise, set expanded value to lowercased value. + When the frame expansion flag is set, value + may also be an empty dictionary or an array of zero or + strings. expanded value will be an + array of one or more string values converted to lower case.
      14. +
      15. If expanded property is @index and + value is not a string, an + invalid @index value + error has been detected and processing is aborted. Otherwise, + set expanded value to value.
      16. +
      17. If expanded property is @list: +
          +
        1. If active property is null or + @graph, continue with the next key + from element to remove the free-floating list.
        2. +
        3. Otherwise, initialize expanded value to the result of using + this algorithm recursively passing active context, + active property, value for element, + and the frame expansion flag.
        4. +
        5. If expanded value is a list object, a + list of lists + error has been detected and processing is aborted.
        6. +
        +
      18. +
      19. If expanded property is @set, set + expanded value to the result of using this algorithm + recursively, passing active context, + active property, value for element, + and the frame expansion flag.
      20. +
      21. If expanded property is @reverse and + value is not a dictionary, an + invalid @reverse value + error has been detected and processing is aborted. Otherwise +
          +
        1. Initialize expanded value to the result of using this + algorithm recursively, passing active context, + @reverse as active property, + value as element, + and the frame expansion flag.
        2. +
        3. If expanded value contains an @reverse member, + i.e., properties that are reversed twice, execute for each of its + property and item the following steps: +
            +
          1. If result does not have a property member, create + one and set its value to an empty array.
          2. +
          3. Append item to the value of the property member + of result.
          4. +
          +
        4. +
        5. If expanded value contains members other than @reverse: +
            +
          1. If result does not have an @reverse member, create + one and set its value to an empty dictionary.
          2. +
          3. Reference the value of the @reverse member in result + using the variable reverse map.
          4. +
          5. For each property and items in expanded value + other than @reverse: +
              +
            1. For each item in items: +
                +
              1. If item is a value object or list object, an + invalid reverse property value + has been detected and processing is aborted.
              2. +
              3. If reverse map has no property member, create one + and initialize its value to an empty array.
              4. +
              5. Append item to the value of the property + member in reverse map.
              6. +
              +
            2. +
            +
          6. +
          +
        6. +
        7. Continue with the next key from element.
        8. +
        +
      22. +
      23. If expanded property is @nest, + add key to nests, initializing it to an empty array, + if necessary. + Continue with the next key from element.
      24. +
      25. When the frame expansion flag is set, + if expanded property is any other + framing keyword (@explicit, @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, + and the frame expansion flag.
      26. +
      27. Unless expanded value is null, set + the expanded property member of result to + expanded value.
      28. +
      29. Continue with the next key from element.
      30. +
      +
    8. +
    9. If key's term definition in active context + has a local context, set term context to the result of the + Context Processing algorithm, + passing active context and the value of the + key's local context as local context. Otherwise, + set term context to active context.
    10. +
    11. Set container mapping to key's container mapping in + term context.
    12. +
    13. If container mapping includes @language and + value is a dictionary then value + is expanded from a language map + as follows: +
        +
      1. Initialize expanded value to an empty + array.
      2. +
      3. For each key-value pair language-language value + in value, ordered lexicographically by language: +
          +
        1. If language value is not an array + set it to an array containing only + language value.
        2. +
        3. For each item in language value: +
            +
          1. item must be a string + or null, + otherwise an + invalid language map value + error has been detected and processing is aborted.
          2. +
          3. Append a dictionary to + expanded value that consists of two + key-value pairs: (@value-item) + and (@language-lowercased + language), + unless item is null. + If language is @none, + or expands to @none, do not set the @language member. +
          +
        4. +
        +
      4. +
      +
    14. +
    15. Otherwise, if container mapping + includes @index, + @type, or @id and + value is a dictionary then value + is expanded from an map as follows: +
        +
      1. Initialize expanded value to an empty + array.
      2. +
      3. For each key-value pair index-index value + in value, ordered lexicographically by index: +
          +
        1. If container mapping includes @type, + and index's term definition in + term context has a local context, set + map context to the result of the Context Processing + algorithm, passing term context as active context and the + value of the index's local context as + local context. Otherwise, set map context + to term context.
        2. +
        3. Set expanded index to the result of using the + IRI Expansion algorithm, + passing active context, index, and true + for vocab.
        4. +
        5. If index value is not an array + set it to an array containing only + index value.
        6. +
        7. 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, + and the frame expansion flag.
        8. +
        9. For each item in index value: +
            +
          1. If container mapping includes + @graph and if item is not a + graph object, set item to a new + dictionary containing the key-value pair + @graph-item, ensuring that the + value is represented using an array.
          2. +
          3. If container mapping includes @index + and item does not have the key + @index and expanded index is not @none, + add the key-value pair + (@index-index) to item.
          4. +
          5. Otherwise, if container mapping includes @id + and item does not have the key + @id, add the key-value pair + (@id-expanded index) to + item, where expanded index is set to the result of + using the + IRI Expansion algorithm, + passing active context, index, and true + for document relative, unless expanded index + is already set to @none.
          6. +
          7. Otherwise, if container mapping includes @type + set types to the concatenation of + expanded index with any existing values of + @type in item. + If expanded index is @none, + do not concatenate expanded index to types. + Add the key-value pair + (@type-types) to + item.
          8. +
          9. Append item to expanded value.
          10. +
          +
        10. +
        +
      4. +
      +
    16. +
    17. Otherwise, initialize expanded value to the result of + using this algorithm recursively, passing term context as active context, + key for active property, value for element, + and the frame expansion flag.
    18. +
    19. If expanded value is null, ignore key + by continuing to the next key from element.
    20. +
    21. 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 dictionary containing + the key-value pair @list-expanded value.
    22. +
    23. If container mapping includes + @graph, convert expanded value into an array, if necessary, + then convert each value ev in expanded value into a + graph object: +
        +
      1. If ev is not a graph object, convert it into + one by creating a dictionary containing the key-value + pair @graph-ev + where ev is represented as an array.
      2. +
      +
    24. Otherwise, if the term definition associated to + key indicates that it is a reverse property +
        +
      1. If result has no @reverse member, create + one and initialize its value to an empty dictionary.
      2. +
      3. Reference the value of the @reverse member in result + using the variable reverse map.
      4. +
      5. If expanded value is not an array, set + it to an array containing expanded value.
      6. +
      7. For each item in expanded value +
          +
        1. If item is a value object or list object, an + invalid reverse property value + has been detected and processing is aborted.
        2. +
        3. If reverse map has no expanded property member, + create one and initialize its value to an empty array.
        4. +
        5. Append item to the value of the expanded property + member of reverse map.
        6. +
        +
      8. +
      +
    25. +
    26. Otherwise, if key is not a reverse property: +
        +
      1. If result does not have an expanded property + member, create one and initialize its value to an empty + array.
      2. +
      3. Append expanded value to value of the expanded property + member of result.
      4. +
      +
    27. +
    28. For each key nesting-key in nests +
        +
      1. Set nested values to the value of nesting-key + in element, ensuring that it is an array.
      2. +
      3. For each nested value in nested values: +
          +
        1. If nested value is not a dictionary, or any key within + nested value expands to @value, an + invalid @nest value error + has been detected and processing is aborted.
        2. +
        3. Recursively repeat step 7 + using nested value for element.
        4. +
        +
      4. +
      +
    29. +
    +
  18. +
  19. If result contains the key @value: +
      +
    1. The result must not contain any keys other than + @value, @language, @type, + and @index. It must not contain both the + @language key and the @type key. + Otherwise, an + invalid value object + error has been detected and processing is aborted.
    2. +
    3. If the value of result's @value key is + null, then set result to null.
    4. +
    5. Otherwise, if the value of result's @value member + is not a string and result contains the key + @language, an + invalid language-tagged value + error has been detected (only strings + can be language-tagged) and processing is aborted.
    6. +
    7. Otherwise, if the result has an @type member + and its value is not an IRI, an + invalid typed value + error has been detected and processing is aborted.
    8. +
    +
  20. +
  21. Otherwise, if result contains the key @type + and its associated value is not an array, set it to + an array containing only the associated value.
  22. +
  23. Otherwise, if result contains the key @set + or @list: +
      +
    1. The result must contain at most one other key and that + key must be @index. Otherwise, an + invalid set or list object + error has been detected and processing is aborted.
    2. +
    3. If result contains the key @set, then + set result to the key's associated value.
    4. +
    +
  24. +
  25. If result contains only the key + @language, set result to null.
  26. +
  27. If active property is null or @graph, + drop free-floating values as follows: +
      +
    1. If result is an empty dictionary or contains + the keys @value or @list, set result to + null.
    2. +
    3. Otherwise, if result is a dictionary whose only + key is @id, set result to null. + + When the frame expansion flag is set, a dictionary + containing only the @id key is retained.
    4. +
    +
  28. +
  29. Return result.
  30. +
+ +

If, after the above algorithm is run, the result is a + dictionary that contains only an @graph key, set the + result to the value of @graph's value. Otherwise, if the result + is null, set it to an empty array. Finally, if + the result is not an array, then set the result to an + array containing only the result.

+
+
+ + +
+

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.

+ +
+

Overview

+ +

If active property has a type mapping in the + active context set to @id or @vocab, + and the value is a string, + a dictionary with a single member @id whose + value is the result of using the + IRI Expansion algorithm on value + is returned.

+ +

Otherwise, the result will be a dictionary containing + an @value member whose value is the passed value. + Additionally, an @type member will be included if there is a + type mapping associated with the active property + or an @language member 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 absolute IRI using + the vocabulary mapping.

+
+ +
+

Algorithm

+ +

The algorithm takes three required inputs: an active context, + an active property, and a value to expand.

+ +
    +
  1. If the active property has a type mapping + in active context that is @id, + and the value is a string, + return a new + dictionary containing a single key-value pair where the + key is @id and the value is the result of using the + IRI Expansion algorithm, passing + active context, value, and true for + document relative.
  2. +
  3. If active property has a type mapping in + active context that is @vocab, + and the value is a string, + return a new + dictionary containing a single key-value pair where the + key is @id and the value is the result of using the + IRI Expansion algorithm, passing + active context, value, true for + vocab, and true for + document relative.
  4. +
  5. Otherwise, initialize result to a dictionary + with an @value member whose value is set to + value.
  6. +
  7. If active property has a type mapping in + active context, + other than @id or @vocab, + add an @type member to + result and set its value to the value associated with the + type mapping.
  8. +
  9. Otherwise, if value is a string: +
      +
    1. If a language mapping is associated with + active property in active context, + add an @language to result and set its + value to the language code associated with the + language mapping; unless the + language mapping is set to null in + which case no member is added.
    2. +
    3. Otherwise, if the active context has a + default language, add an @language + to result and set its value to the + default language.
    4. +
    +
  10. +
  11. Return result.
  12. +
+
+
+ +
+ + +
+

Compaction Algorithms

+ +
+

Compaction Algorithm

+ +

This algorithm compacts a JSON-LD document, such that the given + context is applied. This must result in shortening + any applicable IRIs to + terms or + compact IRIs, any applicable + keywords to + keyword aliases, and + any applicable JSON-LD values + expressed in expanded form to simple values such as + strings or + numbers.

+ +
+

Overview

+ +

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:

+ +
    +
  1. If the element is a scalar, it is + already in compacted form, so we simply return it.
  2. +
  3. If the element is an array, we compact + each of its items recursively and return them in a new + array.
  4. +
  5. Otherwise element is a dictionary. The value + of each key in element is compacted recursively. Some of the keys will be + compacted, using the IRI Compaction algorithm, + to terms or compact IRIs + and others will be compacted from keywords to + keyword aliases or simply left + unchanged because they do not have definitions in the context. + Values will be converted to compacted form via the + Value Compaction algorithm. Some data + will be reshaped based on container mapping + specified in the context such as @index or @language + maps.
  6. +
+ +

The final output is a dictionary with an @context + key, if a non-empty context was given, where the dictionary + is either result or a wrapper for it where result appears + as the value of an (aliased) @graph key because result + contained two or more items in an array.

+
+ +
+

Algorithm

+ +

The algorithm takes five required input variables: an active context, + an inverse context, an active property, an + element to be compacted, and a flag + compactArrays + To begin, the active context is set to the result of + performing Context Processing + on the passed context, the inverse context is + set to the result of performing the + Inverse Context Creation algorithm + on active context, the active property is + set to null, element is set to the result of + performing the Expansion algorithm + on the JSON-LD input, and, if not passed, + compactArrays + is set to true.

+ +
    +
  1. If the term definition for active property has a + local context: +
      +
    1. Set active context to the result of the + Context Processing algorithm, + passing active context and the value of the + active property's local context as local context.
    2. +
    3. Set inverse context using the + Inverse Context Creation algorithm + using active context.
    4. +
    +
  2. +
  3. If element is a scalar, it is already in its most + compact form, so simply return element.
  4. +
  5. If element is an array: +
      +
    1. Initialize result to an empty array.
    2. +
    3. For each item in element: +
        +
      1. Initialize compacted item to the result of using this + algorithm recursively, passing active context, + inverse context, active property, and + item for element.
      2. +
      3. If compacted item is not null, then append + it to result.
      4. +
      +
    4. +
    5. If result contains only one item (it has a length of + 1), + + active property is not @graph or @set, + or the container mapping for active property in + active context does not include @list or @set, + + and compactArrays + is true, set result to its only item.
    6. +
    7. Return result.
    8. +
    +
  6. +
  7. Otherwise element is a dictionary. + If element has an @value or @id + member and the result of using the + Value Compaction algorithm, + passing active context, inverse context, + active property,and element as value is + a scalar, return that result.
  8. +
  9. Initialize inside reverse to true if + active property equals @reverse, + otherwise to false.
  10. +
  11. Initialize result to an empty dictionary.
  12. +
  13. If element has a @type member, + create a new array compacted types initialized + by transforming each expanded type of that member + into it's compacted form using the IRI Compaction algorithm, + passing active context, inverse context, + expanded type for var, and + true for vocab. Then, for each term + in compacted types ordered lexicographically: +
      +
    1. If the term definition for term has a + local context: +
        +
      1. Set active context to the result of the + Context Processing algorithm, + passing active context and the value of term's + local context as local context.
      2. +
      3. Set inverse context using the + Inverse Context Creation algorithm + using active context.
      4. +
      +
    2. +
    +
  14. +
  15. For each key expanded property and value expanded value + in element, ordered lexicographically by expanded property: +
      +
    1. If expanded property is @id or + @type: +
        +
      1. If expanded value is a string, + then initialize compacted value to the result + of using the IRI Compaction algorithm, + passing active context, inverse context, + expanded value for var, + and true for vocab if + expanded property is @type, + false otherwise.
      2. +
      3. Otherwise, expanded value must be a + @type array: +
          +
        1. Initialize compacted value to an empty + array.
        2. +
        3. For each item expanded type in + expanded value: +
            +
          1. Set term to the result of + of using the IRI Compaction algorithm, + passing active context, inverse context, + expanded type for var, and + true for vocab.
          2. +
          3. Append term, to compacted value.
          4. +
          +
        4. +
        5. If compacted value contains only one + item (it has a length of 1), then + set compacted value to its only item.
        6. +
        +
      4. +
      5. Initialize alias to the result of using the + IRI Compaction algorithm, + passing active context, inverse context, + expanded property for var, + and true for vocab.
      6. +
      7. Add a member alias to result whose value is + set to compacted value and continue to the next + expanded property.
      8. +
      +
    2. +
    3. If expanded property is @reverse: +
        +
      1. Initialize compacted value to the result of using this + algorithm recursively, passing active context, + inverse context, @reverse for + active property, and expanded value + for element.
      2. +
      3. For each property and value in compacted value: +
          +
        1. If the term definition for property in the + active context indicates that property is + a reverse property +
            +
          1. If the term definition for property in + the active context has a + container mapping including @set or + compactArrays + is false, and value is not an + array, set value to a new + array containing only value.
          2. +
          3. If property is not a member of + result, add one and set its value to value.
          4. +
          5. Otherwise, if the value of the property member of + result is not an array, set it to a new + array containing only the value. Then + append value to its value if value + is not an array, otherwise append each + of its items.
          6. +
          7. Remove the property member from + compacted value.
          8. +
          +
        2. +
        +
      4. +
      5. If compacted value has some remaining members, i.e., + it is not an empty dictionary: +
          +
        1. Initialize alias to the result of using the + IRI Compaction algorithm, + passing active context, inverse context, + @reverse for var, + and true for vocab.
        2. +
        3. Set the value of the alias member of result to + compacted value.
        4. +
        +
      6. +
      7. Continue with the next expanded property from element.
      8. +
      +
    4. +
    5. If expanded property is @preserve + then: +
        +
      1. Initialize compacted value to the result of using this + algorithm recursively, passing active context, + inverse context, property for + active property, and expanded value + for element.
      2. +
      3. Add expanded value as the value of @preserve + in result unless expanded value is an empty array.
      4. +
      +
    6. +
    7. 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 property by continuing + to the next expanded property.
    8. +
    9. Otherwise, if expanded property is @index, + @value, or @language: +
        +
      1. Initialize alias to the result of using + the IRI Compaction algorithm, + passing active context, inverse context, + expanded property for var, + and true for vocab.
      2. +
      3. Add a member alias to result whose value is + set to expanded value and continue with the next + expanded property.
      4. +
      +
    10. +
    11. If expanded value is an empty array: +
        +
      1. Initialize item active property to the result of + using the IRI Compaction algorithm, + passing active context, inverse context, + expanded property for var, + expanded value for value, + true for vocab, and + inside reverse.
      2. +
      3. If the term definition for item active property + in the active context has a nest value, that value (nest term) must be + @nest, or a term in the + active context that expands to @nest, + otherwise an invalid @nest + value error has been detected, and processing is aborted. + If result does not have the key that equals nest + term, initialize it to an empty JSON object (nest + object). If nest object does not have the key + that equals item active property, set this key's + value in nest object to an empty + array.Otherwise, if the key's value is not an + array, then set it to one containing only the + value.
      4. +
      5. Otherwise, if result does not have the key that equals + item active property, set this key's value in + result to an empty array. Otherwise, if + the key's value is not an array, then set it + to one containing only the value.
      6. +
      +
    12. +
    13. + At this point, expanded value must be an + array due to the + Expansion algorithm. + For each item expanded item in expanded value: +
        +
      1. Initialize item active property to the result of using + the IRI Compaction algorithm, + passing active context, inverse context, + expanded property for var, + expanded item for value, + true for vocab, and + inside reverse.
      2. +
      3. If the term definition for item active property + in the active context has a nest value + member, that value (nest term) must be + @nest, or a term in the + active context that expands to @nest, + otherwise an invalid @nest + value error has been detected, and processing is aborted. + Set nest result to the value of nest term in result, + initializing it to a new dictionary, if necessary; otherwise + set nest result to result.
      4. +
      5. Initialize container to null. If there + is a container mapping for + item active property in active context, + set container to the first + such value other than @set.
      6. +
      7. Initialize as array to + true or false depending on if the container mapping for + item active property in active context + includes @set or if item active property + is @graph or @list.
      8. +
      9. Initialize compacted item to the result of using + this algorithm recursively, passing + active context, inverse context, + item active property for active property, + expanded item for element if it does + not contain the key @list + and is not a graph object containing @list, + otherwise pass the key's associated value for element.
      10. +
      11. + If expanded item is a list object: +
          +
        1. If compacted item is not an array, + then set it to an array containing only + compacted item.
        2. +
        3. If container is not @list: +
            +
          1. Convert compacted item to a + list object by setting it to a + dictionary containing key-value pair + where the key is the result of the + IRI Compaction algorithm, + passing active context, inverse context, + @list for var, and compacted item + for value and the value is the original compacted item.
          2. +
          3. If expanded item contains the key + @index, then add a key-value pair + to compacted item where the key is the + result of the IRI Compaction algorithm, + passing active context, inverse context, + @index as var, and the value associated with the + @index key in expanded item as value.
          4. +
          +
        4. +
        5. Otherwise, item active property must not be a key + in nest result because there cannot be two + list objects associated + with an active property that has a + container mapping; a + compaction to list of lists + error has been detected and processing is aborted.
        6. +
        +
      12. +
      13. + If expanded item is a graph object: +
          +
        1. If container includes @graph and @id: +
            +
          1. Initialize map object to the value of item active property + in nest result.
          2. +
          3. Initialize map key to the result of calling the + IRI Compaction algorithm + passing active context and the value of @id in expanded item + or @none if no such value exists as var, with vocab set to true + if there is no @id member in expanded item.
          4. +
          5. If compacted item is not an + array and as array is true, + set compacted item to an array containing that value.
          6. +
          7. If map key is not a key in map object, + then set this key's value in map object + to compacted item. Otherwise, if the value + is not an array, then set it to one + containing only the value and then append + compacted item to it.
          8. +
          +
        2. +
        3. Otherwise, if container includes @graph and @index + and expanded item is a simple graph object: +
            +
          1. Initialize map object to the value of item active property + in nest result.
          2. +
          3. Initialize map key the value of @index in + expanded item or @none, if no such + value exists.
          4. +
          5. If compacted item is not an + array and as array is true, + set compacted item to an array containing that value.
          6. +
          7. If map key is not a key in map object, + then set this key's value in map object + to compacted item. Otherwise, if the value + is not an array, then set it to one + containing only the value and then append + compacted item to it.
          8. +
          +
        4. +
        5. 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 not an array + and as array is true, set + compacted item to an array containing + that value. If the value associated with the key that + equals item active property in + nest result is not an array, + set it to a new array containing only the value. + Then append compacted item to the value if + compacted item is not an array, + otherwise, concatenate it. +
        6. +
        7. Otherwise, container does not include @graph + or otherwise does not match one of the previous cases, redo compacted item. +
            +
          1. Set compacted item to a new dictionary containing + the key resulting from calling the IRI Compaction algorithm + passing active context, @graph as + var, and true for + vocab using the original + compacted item as a value.
          2. +
          3. If expanded item contains the key @id, + add the key resulting from calling the IRI Compaction algorithm + passing active context, @id as + var, and true for + vocab using the value resulting from calling the IRI Compaction algorithm + passing active context, the value of @id + in expanded item as + var.
          4. +
          5. If expanded item contains the key @index, + add the key resulting from calling the IRI Compaction algorithm + passing active context, @index as + var, and true for + vocab using the value of @index + in expanded item.
          6. +
          7. If as array is true, + set compacted item to an array + containing that value.
          8. +
          9. Then append compacted item to the value if + compacted item is not an array, + otherwise, concatenate it.
          10. +
          +
        8. +
        +
      14. +
      15. + Otherwise, if container includes @language, + @index, @id, + or @type + and container does not include @graph: +
          +
        1. If item active property is not a key in + nest result, initialize it to an empty dictionary. + Initialize map object to the value of item active property + in nest result.
        2. +
        3. Set container key to the result of calling the + IRI Compaction algorithm + passing active context, + either @language, @index, @id, or @type + based on the contents of container, as var, and true + for vocab.
        4. +
        5. If container includes @language and + expanded item contains the key + @value, then set compacted item + to the value associated with its @value key. + Set map key to the value of @language in expanded item, if any.
        6. +
        7. If container includes @index set map key to the value of @index in expanded item, if any, + and remove container key from compacted item.
        8. +
        9. If container includes @id, set + map key to the value of container key in + compacted item and remove container key from compacted item.
        10. +
        11. If container is @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 compacted container, set the value of + compacted container in compacted value + to those remaining values. Otherwise, remove that + key-value pair from compacted item.
        12. +
        13. If compacted item is not an + array and as array is true, + set compacted item to an array containing that value.
        14. +
        15. If map key is null, set it to the result of calling the + IRI Compaction algorithm + passing active context, @none as + var, and true for + vocab.
        16. +
        17. If map key is not a key in map object, + then set this key's value in map object + to compacted item. Otherwise, if the value + is not an array, then set it to one + containing only the value and then append + compacted item to it.
        18. +
        +
      16. +
      17. + Otherwise, +
          +
        1. If + compactArrays + is false, as array is true and + compacted item is not an array, + set it to a new array + containing only compacted item.
        2. +
        3. If item active property is not a key in + result then add the key-value pair, + (item active property-compacted item), + to nest result.
        4. +
        5. Otherwise, if the value associated with the key that + equals item active property in nest result + is not an array, set it to a new + array containing only the value. Then + append compacted item to the value if + compacted item is not an array, + otherwise, concatenate it.
        6. +
        +
      18. +
      +
    14. +
    +
  16. +
  17. Return result.
  18. +
+ +

If, after the algorithm outlined above is run, result + is an empty array, replace it with a new dictionary. + Otherwise, if result is an array, replace it with a new + dictionary with a single member whose key is the result + of using the IRI Compaction algorithm, + passing active context, inverse context, and + @graph as var and whose value is the array + result.

+

Finally, if a non-empty context has been passed, + add an @context member to result and set its value + to the passed context.

+
+
+ +
+

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.

+ +
+

Overview

+ +

To create an inverse context for a given + active context, each term in the + active context is visited, ordered by length, shortest + first (ties are broken by choosing the lexicographically least + term). For each term, an entry is added to + the inverse context for each possible combination of + container mapping and type mapping + or language mapping that would legally match the + term. Illegal matches include differences between a + value's type mapping or language mapping and + that of the term. If a term has no + container mapping, type mapping, or + language mapping (or some combination of these), then it + will have an entry in the inverse context using the special + key @none. This allows the + Term Selection algorithm to fall back + to choosing more generic terms when a more + specifically-matching term is not available for a particular + IRI and value combination.

+
+ +
+

Algorithm

+ +

The algorithm takes one required input: the active context that + the inverse context is being created for.

+ +
    +
  1. Initialize result to an empty dictionary.
  2. +
  3. Initialize default language to @none. If the + active context has a default language, + set default language to it.
  4. +
  5. 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): +
      +
    1. If the term definition is null, + term cannot be selected during compaction, + so continue to the next term.
    2. +
    3. Initialize container to @none. + + If the container mapping is not empty, set container + to the concatenation of all values of the container mapping + in lexicographically order + .
    4. +
    5. Initialize var to the value of the IRI mapping + for the term definition.
    6. +
    7. If var is not a key in result, add + a key-value pair where the key is var and the value + is an empty dictionary to result.
    8. +
    9. Reference the value associated with the var member in + result using the variable container map.
    10. +
    11. If container map has no container member, + create one and set its value to a new + dictionary with three members. + The first member is @language and its value is a new empty + dictionary, the second member is @type + and its value is a new empty dictionary, + and the third member is @any + and its value is a new dictionary with the member + @none set to the term being processed.
    12. +
    13. Reference the value associated with the container member + in container map using the variable type/language map.
    14. +
    15. If the term definition indicates that the term + represents a reverse property: +
        +
      1. Reference the value associated with the @type + member in type/language map using the variable + type map.
      2. +
      3. If type map does not have an @reverse + member, create one and set its value to the term + being processed.
      4. +
      +
    16. +
    17. Otherwise, if term definition has a + type mapping: +
        +
      1. Reference the value associated with the @type + member in type/language map using the variable + type map.
      2. +
      3. If type map does not have a member corresponding + to the type mapping in term definition, + create one and set its value to the term + being processed.
      4. +
      +
    18. +
    19. Otherwise, if term definition has a + language mapping (might be null): +
        +
      1. Reference the value associated with the @language + member in type/language map using the variable + language map.
      2. +
      3. If the language mapping equals null, + set language to @null; otherwise set it + to the language code in language mapping.
      4. +
      5. If language map does not have a language member, + create one and set its value to the term + being processed.
      6. +
      +
    20. +
    21. Otherwise: +
        +
      1. Reference the value associated with the @language + member in type/language map using the variable + language map.
      2. +
      3. If language map does not have a default language + member, create one and set its value to the term + being processed.
      4. +
      5. If language map does not have an @none + member, create one and set its value to the term + being processed.
      6. +
      7. Reference the value associated with the @type + member in type/language map using the variable + type map.
      8. +
      9. If type map does not have an @none + member, create one and set its value to the term + being processed.
      10. +
      +
    22. +
    +
  6. +
  7. Return result.
  8. +
+
+
+ +
+

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.

+ +
+

Overview

+ +

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 which + container mapping + would be preferred for expressing the value, and what its + type mapping or language mapping is. 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 to use.

+ +

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 using the document's + base IRI. Finally, if the IRI or + keyword still could not be compacted, it is returned + as is.

+
+ +
+

Algorithm

+ +

This algorithm takes three required inputs and three optional inputs. + The required inputs are an active context, an inverse context, + and the var to be compacted. The optional inputs are a value associated + with the var, a vocab flag which specifies whether the + passed var should be compacted using the + active context's + vocabulary mapping, and a reverse flag which specifies whether + a reverse property is being compacted. If not passed, value is set to + null and vocab and reverse are both set to + false.

+ +
    +
  1. If var is null, return null.
  2. +
  3. If vocab is true and var is a + key in inverse context: +
      +
    1. Initialize default language to + active context's + default language, if it has one, otherwise to + @none.
    2. +
    3. If value is a dictionary containing + the property @preserve, use the first + element from the value of @preserve as value.
    4. +
    5. 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.
    6. +
    7. Initialize type/language to @language, + and type/language value to @null. These two + variables will keep track of the preferred + type mapping or language mapping for + a term, based on what is compatible with value.
    8. +
    9. If value is a dictionary, + that contains the key @index, + and value is not a graph object + then append the values @index and @index@set to containers.
    10. +
    11. If reverse is true, set type/language + to @type, type/language value to + @reverse, and append @set to containers.
    12. +
    13. 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: +
        +
      1. If @index is a not key in value, then + append @list to containers.
      2. +
      3. Initialize list to the array associated + with the key @list in value.
      4. +
      5. Initialize common type and common language to null. If + list is empty, set common language to + default language.
      6. +
      7. For each item in list: +
          +
        1. Initialize item language to @none and + item type to @none.
        2. +
        3. If item contains the key @value: +
            +
          1. If item contains the key @language, + then set item language to its associated + value.
          2. +
          3. Otherwise, if item contains the key + @type, set item type to its + associated value.
          4. +
          5. Otherwise, set item language to + @null.
          6. +
          +
        4. +
        5. Otherwise, set item type to @id.
        6. +
        7. If common language is null, set it + to item language.
        8. +
        9. Otherwise, if item language does not equal + common language and item contains the + key @value, then set common language + to @none because list items have conflicting + languages.
        10. +
        11. If common type is null, set it + to item type.
        12. +
        13. Otherwise, if item type does not equal + common type, then set common type + to @none because list items have conflicting + types.
        14. +
        15. 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.
        16. +
        +
      8. +
      9. If common language is null, set it to + @none.
      10. +
      11. If common type is null, set it to + @none.
      12. +
      13. If common type is not @none then set + type/language to @type and + type/language value to common type.
      14. +
      15. Otherwise, set type/language value to + common language.
      16. +
      +
    14. +
    15. Otherwise, if value is a graph object, + prefer a mapping most appropriate for the particular value. +
        +
      1. If value contains the key @index, + append the values @graph@index and @graph@index@set + to containers.
      2. +
      3. If the value contains the key @id, + append the values @graph@id and @graph@id@set + to containers.
      4. +
      5. Append the values @graph @graph@set, + and @set + to containers.
      6. +
      7. If value does not contain the key @index, + append the values @graph@index and @graph@index@set + to containers.
      8. +
      9. If the value does not contain the key @id, + append the values @graph@id and @graph@id@set + to containers.
      10. +
      11. Append the values @index and @index@set + to containers.
      12. +
      +
    16. +
    17. Otherwise: +
        +
      1. If value is a value object: +
          +
        1. If value contains the key @language + and does not contain the key @index, + then set type/language value to its associated + value and, append @language + and @language@set to + containers.
        2. +
        3. Otherwise, if value contains the key + @type, then set type/language value to + its associated value and set type/language to + @type.
        4. +
        +
      2. +
      3. Otherwise, set type/language to @type + and set type/language value to @id, + and append @id, @id@set, + @type, and @set@type, + to containers.
      4. +
      5. Append @set to containers.
      6. +
      +
    18. +
    19. 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.
    20. +
    21. + If processing mode is json-ld-1.1 and value does not contain the key @index, append + @index and @index@set to containers. +
    22. +
    23. + If processing mode is json-ld-1.1 and value contains only the key @value, append + @language and @language@set to containers. +
    24. +
    25. If type/language value is null, set it to + @null. This is the key under which null values + are stored in the inverse context entry.
    26. +
    27. Initialize preferred values to an empty array. + This array will indicate, in order, the preferred values for + a term's type mapping or + language mapping.
    28. +
    29. If type/language value is @reverse, append + @reverse to preferred values.
    30. +
    31. If type/language value is @id or @reverse + and value has an @id member: +
        +
      1. If the result of using the + IRI compaction algorithm, + passing active context, inverse context, + the value associated with the @id key in value for + var, and true for vocab has a + term definition in the active context + with an IRI mapping that equals the value associated + with the @id key in value, + then append @vocab, @id, and + @none, in that order, to preferred values.
      2. +
      3. Otherwise, append @id, @vocab, and + @none, in that order, to preferred values.
      4. +
      +
    32. +
    33. Otherwise, append type/language value and @none, in + that order, to preferred values. + If value is an empty list object, + set type/language to @any.
    34. +
    35. Initialize term to the result of the + Term Selection algorithm, passing + inverse context, var, containers, + type/language, and preferred values.
    36. +
    37. If term is not null, return term.
    38. +
    +
  4. +
  5. 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: +
      +
    1. 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.
    2. +
    +
  6. +
  7. 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 + tore the created compact IRI, if any.
  8. +
  9. For each key term and value term definition in + the active context: +
      +
    1. If the term definition is null, + its IRI mapping equals var, its + IRI mapping is not a substring at the beginning of + var, + or the term definition does not contain + the prefix flag having a value of true, + the term cannot be used as a prefix. + Continue with the next term.
    2. +
    3. Initialize candidate by concatenating term, + a colon (:), and the substring of var + that follows after the value of the + term definition's + IRI mapping.
    4. +
    5. 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 the + term definition has an IRI mapping + that equals var and value is null, + set compact IRI to candidate.
    6. +
    +
  10. +
  11. If compact IRI is not null, return compact IRI.
  12. +
  13. If vocab is false, + transform var to a relative IRI using + the base IRI from active context, if it exists.
  14. +
  15. Finally, return var as is.
  16. +
+
+
+ +
+

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.

+ +
+

Overview

+ +

The inverse context's entry for + the IRI will be first searched according to the preferred + container mapping, in the order + that they are given. Amongst terms with a matching + container mapping, preference will be given to those + with a matching type mapping or language mapping, + over those without a type mapping or + language mapping. If there is no term + with a matching container mapping then the term + without a container mapping that matches the given + type mapping or language mapping is selected. If + there is still no selected term, then a term + with no type mapping or language mapping will + be selected if available. No term will be selected that + has a conflicting type mapping or language mapping. + Ties between terms that have the same + mappings are resolved by first choosing the shortest terms, and then by + choosing the lexicographically least term. Note that these ties are + resolved automatically because they were previously resolved when the + Inverse Context Creation algorithm + was used to create the inverse context.

+
+ +
+

Algorithm

+ +

This algorithm has five required inputs. They are: + an inverse context, a keyword or IRI + var, an array containers that represents an + ordered list of preferred container mapping, + a string type/language that indicates whether + to look for a term with a matching type mapping + or language mapping, and an array representing + an ordered list of preferred values for the type mapping + or language mapping to look for.

+ +
    +
  1. Initialize container map to the value associated with + var in the inverse context.
  2. +
  3. For each item container in containers: +
      +
    1. If container is not a key in container map, then + there is no term with a matching + container mapping for it, so continue to the next + container.
    2. +
    3. Initialize type/language map to the value associated + with the container member in container map.
    4. +
    5. Initialize value map to the value associated + with type/language member in type/language map.
    6. +
    7. For each item in preferred values: +
        +
      1. If item is not a key in value map, + then there is no term with a matching + type mapping or language mapping, + so continue to the next item.
      2. +
      3. Otherwise, a matching term has been found, return the value + associated with the item member in + value map.
      4. +
      +
    8. +
    +
  4. +
  5. No matching term has been found. Return null.
  6. +
+
+ +
+

Examples

+

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.

+
+          {
+            "@context": {"t": {"@id": "http://example/t", "@container": "@language"}}
+          }
+        
+

The inverse context will contain the following:

+
+{
+  "@language": {
+    "@language": {"@none": "t"},
+    "@type": {"@none": "t"},
+    "@any": {"@none": "t"}
+  }
+}
+        
+ + +
+ +
+

Datatyped Term

+

If the term definition has a datatype, it will only match a + value object having a matching datatype.

+
+          {
+            "@context": {"t": {"@id": "http://example/t", "@type": "http:/example/type"}}
+          }
+        
+

The inverse context will contain the following:

+
+{
+  "@none": {
+    "@language": {},
+    "@type": {"http:/example/type": "t"},
+    "@any": {"@none": "t"}
+  }
+}
+        
+ + + + + + +
+
+
+ +
+

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.

+ +
+

Overview

+ +

The value to compact has either an @id or an + @value member.

+ +

For the former case, if the type mapping of + active property is set to @id or @vocab + and value consists of only an @id member and, if + the container mapping of active property + includes @index, an @index member, 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 member. + 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 member. + This can be done if the active property has a matching + type mapping or language mapping and there + is either no @index member or the container mapping + of active property includes @index. It can + also be done if @value is the only member in value + (apart an @index member 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.

+
+ +
+

Algorithm

+ +

This algorithm has four required inputs: an active context, an + inverse context, an active property, and a value + to be compacted.

+ +
    +
  1. Initialize number members to the number of members + value contains.
  2. +
  3. If value has an @index member and the + container mapping associated to active property + includes @index, decrease number members by + 1.
  4. +
  5. If number members is greater than 2, return + value as it cannot be compacted.
  6. +
  7. If value has an @id member: +
      +
    1. If number members is 1 and + the type mapping of active property + is set to @id, return the result of using the + IRI compaction algorithm, + passing active context, inverse context, + and the value of the @id member for var.
    2. +
    3. Otherwise, if number members is 1 and + the type mapping of active property + is set to @vocab, return the result of using the + IRI compaction algorithm, + passing active context, inverse context, + the value of the @id member for var, and + true for vocab.
    4. +
    5. Otherwise, return value as is.
    6. +
    +
  8. +
  9. Otherwise, if value has an @type member whose + value matches the type mapping of active property, + return the value associated with the @value member + of value.
  10. +
  11. Otherwise, if value has an @language member whose + value matches the language mapping of + active property, return the value associated with the + @value member of value.
  12. +
  13. Otherwise, if number members equals 1 and either + the value of the @value member is not a string, + or the active context has no default language, + or the language mapping of active property + is set to null,, return the value associated with the + @value member.
  14. +
  15. Otherwise, return value as is.
  16. +
+
+
+
+ + +
+

Flattening Algorithms

+ +
+

Flattening Algorithm

+ +

This algorithm flattens an expanded JSON-LD document by collecting all + properties of a node in a single dictionary + 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.

+ +
+

Overview

+ +

First, a node map is generated using the + Node Map Generation algorithm + which collects all properties of a node in a single + dictionary. In the next step, the node map is + converted to a JSON-LD document in + flattened document form. + Finally, if a context has been passed, the flattened document + is compacted using the Compaction algorithm + before being returned.

+
+ +
+

Algorithm

+ +

The algorithm takes two input variables, an element to flatten and + an optional context used to compact the flattened document. If not + passed, context is set to null.

+ +

This algorithm generates new blank node identifiers + and relabels existing blank node identifiers. + The Generate Blank Node Identifier algorithm + keeps an identifier map and a counter to ensure consistent + relabeling and avoid collisions. Thus, before this algorithm is run, + the identifier map is reset and the counter is initialized + to 0.

+ +
    +
  1. Initialize node map to a dictionary consisting of + a single member whose key is @default and whose value is + an empty dictionary.
  2. +
  3. Perform the Node Map Generation algorithm, passing + element and node map.
  4. +
  5. Initialize default graph to the value of the @default + member of node map, which is a dictionary representing + the default graph.
  6. +
  7. For each key-value pair graph name-graph in node map + where graph name is not @default, perform the following steps: +
      +
    1. If default graph does not have a graph name member, create + one and initialize its value to a dictionary consisting of an + @id member whose value is set to graph name.
    2. +
    3. Reference the value associated with the graph name member in + default graph using the variable entry.
    4. +
    5. Add an @graph member to entry and set it to an + empty array.
    6. +
    7. For each id-node pair in graph ordered by id, + add node to the @graph member of entry, + unless the only member of node is @id.
    8. +
    +
  8. +
  9. Initialize an empty array flattened.
  10. +
  11. For each id-node pair in default graph ordered by id, + add node to flattened, + unless the only member of node is @id.
  12. +
  13. If context is null, return flattened.
  14. +
  15. Otherwise, return the result of compacting flattened according the + Compaction algorithm passing context + ensuring that the compaction result has only the @graph keyword (or its alias) + at the top-level other than @context, even if the context is empty or if there is only one element to + put in the @graph array. This ensures that the returned + document has a deterministic structure.
  16. +
+
+
+ +
+

Node Map Generation

+ +

This algorithm creates a dictionary 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 a member for every graph in the document whose + value is another object with a member for every node represented in the document. + The default graph is stored under the @default member, all other graphs are + stored under their graph name.

+ +
+

Overview

+ +

The algorithm recursively runs over an expanded JSON-LD document to + collect all properties of a node + in a single dictionary. The algorithm constructs a + dictionary node map whose keys represent the + graph names used in the document + (the default graph is stored under the key @default) + and whose associated values are dictionaries + which index the nodes in the + graph. If a + property's value is a node object, + it is replaced by a node object consisting of only an + @id member. If a node object has no @id + member 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.

+
+ +
+

Algorithm

+ +

The algorithm takes as input an expanded JSON-LD document element and a reference to + a dictionary node map. Furthermore it has the optional parameters + active graph (which defaults to @default), an active subject, + active property, and a reference to a dictionary list. If + not passed, active subject, active property, and list are + set to null.

+ +
    +
  1. If element is an array, process each item in element + as follows and then return: +
      +
    1. Run this algorithm recursively by passing item for element, + node map, active graph, active subject, + active property, and list.
    2. +
    +
  2. +
  3. Otherwise element is a dictionary. Reference the + dictionary which is the value of the active graph + member of node map using the variable graph. If the + active subject is null, set node to null + otherwise reference the active subject member of graph using the + variable node.
  4. +
  5. If element has an @type member, perform for each + item the following steps: +
      +
    1. If item is a blank node identifier, replace it with a newly + generated blank node identifier + passing item for identifier.
    2. +
    +
  6. +
  7. If element has an @value member, perform the following steps: +
      +
    1. If list is null: +
        +
      1. If node does not have an active property member, + create one and initialize its value to an array + containing element.
      2. +
      3. Otherwise, compare element against every item in the + array associated with the active property + member of node. If there is no item equivalent to element, + append element to the array. Two + dictionaries are considered + equal if they have equivalent key-value pairs.
      4. +
      +
    2. +
    3. Otherwise, append element to the @list member of list.
    4. +
    +
  8. +
  9. Otherwise, if element has an @list member, perform + the following steps: +
      +
    1. Initialize a new dictionary result consisting of a single member + @list whose value is initialized to an empty array.
    2. +
    3. Recursively call this algorithm passing the value of element's + @list member for element, active graph, + active subject, active property, and + result for list.
    4. +
    5. Append result to the value of the active property member + of node.
    6. +
    +
  10. +
  11. Otherwise element is a node object, perform + the following steps: +
      +
    1. If element has an @id member, set id + to its value and remove the member from element. If id + is a blank node identifier, replace it with a newly + generated blank node identifier + passing id for identifier.
    2. +
    3. Otherwise, set id to the result of the + Generate Blank Node Identifier algorithm + passing null for identifier.
    4. +
    5. If graph does not contain a member id, create one and initialize + its value to a dictionary consisting of a single member @id whose + value is id.
    6. +
    7. Reference the value of the id member of graph using the + variable node.
    8. +
    9. If active subject is a dictionary, a reverse property relationship + is being processed. Perform the following steps: +
        +
      1. If node does not have an active property member, + create one and initialize its value to an array + containing active subject.
      2. +
      3. Otherwise, compare active subject against every item in the + array associated with the active property + member of node. If there is no item equivalent to active subject, + append active subject to the array. Two + dictionaries are considered + equal if they have equivalent key-value pairs.
      4. +
      +
    10. +
    11. Otherwise, if active property is not null, perform the following steps: +
        +
      1. Create a new dictionary reference consisting of a single member + @id whose value is id.
      2. +
      3. If list is null: +
          +
        1. If node does not have an active property member, + create one and initialize its value to an array + containing reference.
        2. +
        3. Otherwise, compare reference against every item in the + array associated with the active property + member of node. If there is no item equivalent to reference, + append reference to the array. Two + dictionaries are considered + equal if they have equivalent key-value pairs.
        4. +
        +
      4. +
      5. Otherwise, append reference to the @list member of list.
      6. +
      +
    12. +
    13. If element has an @type key, append + each item of its associated array to the + array associated with the @type key of + node unless it is already in that array. Finally + remove the @type member from element.
    14. +
    15. If element has an @index member, set the @index + member of node to its value. If node has already an + @index member with a different value, a + conflicting indexes + error has been detected and processing is aborted. Otherwise, continue by + removing the @index member from element.
    16. +
    17. If element has an @reverse member: +
        +
      1. Create a dictionary referenced node with a single member @id whose + value is id.
      2. +
      3. Set reverse map to the value of the @reverse member of + element.
      4. +
      5. For each key-value pair property-values in reverse map: +
          +
        1. For each value of values: +
            +
          1. Recursively invoke this algorithm passing value for + element, node map, active graph, + referenced node for active subject, and + property for active property. Passing a + dictionary for active subject indicates to the + algorithm that a reverse property relationship is being processed.
          2. +
          +
        2. +
        +
      6. +
      7. Remove the @reverse member from element.
      8. +
      +
    18. +
    19. If element has an @graph member, recursively invoke this + algorithm passing the value of the @graph member for element, + node map, and id for active graph before removing + the @graph member from element.
    20. +
    21. Finally, for each key-value pair property-value in element ordered by + property perform the following steps: +
        +
      1. If property is a blank node identifier, replace it with a newly + generated blank node identifier + passing property for identifier.
      2. +
      3. If node does not have a property member, create one and initialize + its value to an empty array.
      4. +
      5. Recursively invoke this algorithm passing value for element, + node map, active graph, id for active subject, + and property for active property.
      6. +
      +
    22. +
    +
  12. +
+
+
+ +
+

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.

+ +
+

Overview

+ +

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 by concatenating the string _:b and the + counter. If the passed identifier is not null, + an entry is created in the identifier map associating the + identifier with the blank node identifier. Finally, + the counter is increased by one and the new + blank node identifier is returned.

+
+ +
+

Algorithm

+ +

The algorithm takes a single input variable identifier which may + be null. Between its executions, the algorithm needs to + keep an identifier map to relabel existing + blank node identifiers + consistently and a counter to generate new + blank node identifiers. The + counter is initialized to 0 by default.

+ +
    +
  1. If identifier is not null and has an entry in the + identifier map, return the mapped identifier.
  2. +
  3. Otherwise, generate a new blank node identifier by concatenating + the string _:b and counter.
  4. +
  5. Increment counter by 1.
  6. +
  7. If identifier is not null, create a new entry + for identifier in identifier map and set its value + to the new blank node identifier.
  8. +
  9. Return the new blank node identifier.
  10. +
+
+
+ +
+

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.

+ +
    +
  1. Create result as an empty dictionary
  2. +
  3. For each graph name and node map in graph map + and for each id and node in node map: +
      +
    1. Set merged node to the value for id in result, initializing it + with a new dictionary consisting of a single member @id whose value is id, if it does not exist.
    2. +
    3. For each property and values in node: +
        +
      1. If property is a keyword, add property and values to merged node.
      2. +
      3. Otherwise, merge each element from values into the values for property + in merged node, initializing it to an empty array if necessary.
      4. +
      +
    4. +
    +
  4. +
  5. Return result.
  6. +
+
+ +
+ + +
+

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 dictionary elements.

+ +

Throughout this section, the following vocabulary + prefixes are used in + compact IRIs:

+ + + + + + + + + + + + + + + + + + + + +
PrefixIRI
rdfhttp://www.w3.org/1999/02/22-rdf-syntax-ns#
rdfs http://www.w3.org/2000/01/rdf-schema#
xsdhttp://www.w3.org/2001/XMLSchema#
+ +
+

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 + RDF triples that would have contained blank nodes as properties are + discarded when interpreting JSON-LD as RDF.

+ +
+

Overview

+ +

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 RDF 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 member which corresponds to the + RDF subject, the other members + represent RDF predicates. Each + member value is either an IRI or + blank node identifier or can be transformed to an + RDF literal + to generate an RDF triple. Lists + are transformed into an + RDF collection + using the List to RDF Conversion algorithm.

+
+ +
+

Algorithm

+ +

The algorithm takes a JSON-LD document element and returns an + RDF dataset. Unless the produceGeneralizedRdf option + is set to true, RDF triple + containing a blank node predicate + are excluded from output.

+ +

This algorithm generates new blank node identifiers + and relabels existing blank node identifiers. + The Generate Blank Node Identifier algorithm + keeps an identifier map and a counter to ensure consistent + relabeling and avoid collisions. Thus, before this algorithm is run, + the identifier map is reset and the counter is initialized + to 0.

+ +
    +
  1. Expand element according to the + Expansion algorithm.
  2. +
  3. Generate a node map according to the + Node Map Generation algorithm.
  4. +
  5. Initialize an empty RDF dataset dataset.
  6. +
  7. For each graph name and graph in node map + ordered by graph name: +
      +
    1. If graph name is a relative IRI, continue + with the next graph name-graph pair.
    2. +
    3. Initialize triples as an empty array.
    4. +
    5. For each subject and node in graph ordered + by subject: +
        +
      1. If subject is a relative IRI, continue + with the next subject-node pair.
      2. +
      3. For each property and values in node + ordered by property: +
          +
        1. If property is @type, then for each + type in values, append a triple + composed of subject, rdf:type, + and type to triples.
        2. +
        3. Otherwise, if property is a keyword + continue with the next property-values pair.
        4. +
        5. Otherwise, if property is a blank node identifier and + the produceGeneralizedRdf option is not true, + continue with the next property-values pair.
        6. +
        7. Otherwise, if property is a relative IRI, + continue with the next property-values pair.
        8. +
        9. Otherwise, property is an absolute IRI or + blank node identifier. For each item + in values: +
            +
          1. If item is a list object, initialize + list triples as an empty array and + list head to the result of the List Conversion algorithm, passing + the value associated with the @list key from + item and list triples. Append first a + triple composed of subject, + property, and list head to triples and + finally append all triples from + list triples to triples.
          2. +
          3. Otherwise, item is a value object + or a node object. Append a triple + composed of subject, property, and + the result of using the + Object to RDF Conversion algorithm + passing item to triples, unless the result is + null, indicating a relative IRI that has + to be ignored.
          4. +
          +
        10. +
        +
      4. +
      +
    6. +
    7. If graph name is @default, add + triples to the default graph in dataset.
    8. +
    9. Otherwise, create a named graph in dataset + composed of graph name and add triples.
    10. +
    +
  8. +
  9. Return dataset.
  10. +
+
+
+ +
+

Object to RDF Conversion

+ +

This algorithm takes a node object or value object + and transforms it into an + RDF resource + to be used as the object of an RDF triple. If a + node object containing a relative IRI is passed to + the algorithm, null is returned which then causes the resulting + RDF triple to be ignored.

+ +
+

Overview

+ +

Value objects are transformed to + RDF literals as described in + + whereas node objects are transformed + to IRIs, + blank node identifiers, + or null.

+
+ +
+

Algorithm

+ +

The algorithm takes as its sole argument item which MUST be + either a value object or node object.

+ +
    +
  1. If item is a node object and the value of + its @id member is a relative IRI, return + null.
  2. +
  3. If item is a node object, return the + IRI or blank node identifier associated + with its @id member.
  4. +
  5. Otherwise, item is a value object. Initialize + value to the value associated with the @value + member in item. +
  6. Initialize datatype to the value associated with the + @type member of item or null if + item does not have such a member.
  7. +
  8. If value is true or + false, set value to the string + true or false which is the + canonical lexical form as described in + + If datatype is null, set it to + xsd:boolean.
  9. +
  10. Otherwise, if value is a number with a non-zero fractional + part (the result of a modulo‑1 operation) 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 + . + If datatype is null, set it to + xsd:double.
  11. +
  12. Otherwise, if value is a number with no non-zero + fractional part (the result of a modulo‑1 operation) or value + is a number and datatype + equals xsd:integer, convert value to a + string in canonical lexical form of + an xsd:integer as defined in [[!XMLSCHEMA11-2]] + and described in + . + If datatype is null, set it to + xsd:integer.
  13. +
  14. Otherwise, if datatype is null, set it to + xsd:string or rdf:langString, depending on if + item has an @language member.
  15. +
  16. Initialize literal as an RDF literal using + value and datatype. If item has an + @language member, add the value associated with the + @language key as the language tag of literal.
  17. +
  18. Return literal.
  19. +
+
+
+ +
+

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

+ +
+

Overview

+ +

For each element of the list a new blank node identifier + is allocated which is used to generate rdf:first and + rdf:rest ABBR. 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 a relative IRI, + the corresponding rdf:first triple is omitted.

+
+ +
+

Algorithm

+ +

The algorithm takes two inputs: an array list + and an empty array list triples used for returning + the generated triples.

+ +
    +
  1. If list is empty, return rdf:nil.
  2. +
  3. Otherwise, create an array bnodes composed of a + newly generated blank node identifier + for each entry in list.
  4. +
  5. Initialize an empty array list triples.
  6. +
  7. For each pair of subject from bnodes and item from list: +
      +
    1. Initialize object to the result of using the + Object to RDF Conversion algorithm + passing item to list triples.
    2. +
    3. Unless object is null, append a triple + composed of subject, rdf:first, and object.
    4. +
    5. Set 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.
    6. +
    +
  8. +
  9. Return the first blank node from bnodes or + rdf:nil if bnodes is empty.
  10. +
+
+
+ +
+

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.

+ +
+

Overview

+ +

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 use native types 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 + . + Unless the use rdf:type 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.

+
+ +
+

Algorithm

+ +

The algorithm takes one required and two optional inputs: an RDF dataset dataset + and the two flags use native types and use rdf:type + that both default to false.

+ +
    +
  1. Initialize default graph to an empty dictionary.
  2. +
  3. Initialize graph map to a dictionary consisting + of a single member @default whose value references + default graph.
  4. +
  5. Initialize node usage map to an empty dictionary.
  6. +
  7. For each graph in dataset: +
      +
    1. If graph is the default graph, + set name to @default, otherwise to the + graph name associated with graph.
    2. +
    3. If graph map has no name member, create one and set + its value to an empty dictionary.
    4. +
    5. If graph is not the default graph and + default graph does not have a name member, + create such a member and initialize its value to a new + dictionary with a single member @id + whose value is name.
    6. +
    7. Reference the value of the name member in graph map + using the variable node map.
    8. +
    9. For each RDF triple in graph + consisting of subject, predicate, and object: +
        +
      1. If node map does not have a subject member, + create one and initialize its value to a new dictionary + consisting of a single member @id whose value is + set to subject.
      2. +
      3. Reference the value of the subject member in node map + using the variable node.
      4. +
      5. If object is an IRI or blank node identifier, + and node map does not have an object member, + create one and initialize its value to a new dictionary + consisting of a single member @id whose value is + set to object.
      6. +
      7. If predicate equals rdf:type, the + use rdf:type flag is not true, and object + is an IRI or blank node identifier, + append object to the value of the @type + member of node; unless such an item already exists. + If no such member exists, create one + and initialize it to an array whose only item is + object. Finally, continue to the next + RDF triple.
      8. +
      9. Set value to the result of using the + RDF to Object Conversion algorithm, + passing object and use native types.
      10. +
      11. If node does not have an predicate member, create one + and initialize its value to an empty array.
      12. +
      13. If there is no item equivalent to value in the array + associated with the predicate member of node, append a + reference to value to the array. Two JSON objects + are considered equal if they have equivalent key-value pairs.
      14. +
      15. If object is a blank node identifier or IRI, + it might represent the list node: +
          +
        1. If the object member of node usage map does not exist, + initialize it to a new empty array.
        2. +
        3. Append the value of the @id member of node to + the object member of node usage map.
        4. +
        5. If the object member of node map has no + usages member, create one and initialize it to + an empty array.
        6. +
        7. Reference the usages member of the object + member of node map using the variable usages.
        8. +
        9. Append a new dictionary consisting of three + members, node, property, and value + to the usages array. The node member + is set to a reference to node, property to predicate, + and value to a reference to value.
        10. +
        +
      16. +
      +
    10. +
    +
  8. +
  9. For each name and graph object in graph map: +
      +
    1. If graph object has no rdf:nil member, continue + with the next name-graph object pair as the graph does + not contain any lists that need to be converted.
    2. +
    3. Initialize nil to the value of the rdf:nil member + of graph object.
    4. +
    5. For each item usage in the usages member of + nil, perform the following steps: +
        +
      1. Initialize node to the value of the value of the + node member of usage, property to + the value of the property member of usage, + and head to the value of the value member + of usage.
      2. +
      3. Initialize two empty arrays list + and list nodes.
      4. +
      5. While property equals rdf:rest, + the value of the @id member + of node is a blank node identifier, + the array value of the member of node usage map associated with the @id + member of node has only one member, + + the value associated to the usages member of node has + exactly 1 entry, + node has a rdf:first and rdf:rest property, + both of which have as value an array consisting of a single element, + and node has no other members apart from an optional @type + member 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: +
          +
        1. Append the only item of rdf:first member of + node to the list array.
        2. +
        3. Append the value of the @id member of + node to the list nodes array.
        4. +
        5. Initialize node usage to the only item of the + usages member of node.
        6. +
        7. Set node to the value of the node member + of node usage, property to the value of the + property member of node usage, and + head to the value of the value member + of node usage.
        8. +
        9. If the @id member of node is an + IRI instead of a blank node identifier, + exit the while loop.
        10. +
        +
      6. +
      7. If property equals rdf:first, i.e., the + detected list is nested inside another list +
          +
        1. and the value of the @id of node equals + rdf:nil, i.e., the detected list is empty, + continue with the next usage item. The + rdf:nil node cannot be converted to a + list object as it would result in a list of + lists, which isn't supported.
        2. +
        3. Otherwise, the list consists of at least one item. We preserve the + head node and transform the rest of the linked list to a + list object.
        4. +
        5. Set head id to the value of the @id + member of head.
        6. +
        7. Set head to the value of the head id member of + graph object so that all it's properties can be accessed.
        8. +
        9. Then, set head to the only item in the value of the + rdf:rest member of head.
        10. +
        11. Finally, remove the last item of the list array + and the last item of the list nodes array.
        12. +
        +
      8. +
      9. Remove the @id member from head.
      10. +
      11. Reverse the order of the list array.
      12. +
      13. Add an @list member to head and initialize + its value to the list array.
      14. +
      15. For each item node id in list nodes, remove the + node id member from graph object.
      16. +
      +
    6. +
    +
  10. +
  11. Initialize an empty array result.
  12. +
  13. For each subject and node in default graph + ordered by subject: +
      +
    1. If graph map has a subject member: +
        +
      1. Add an @graph member to node and initialize + its value to an empty array.
      2. +
      3. For each key-value pair s-n in the subject + member of graph map ordered by s, append n + to the @graph member of node after + removing its usages member, unless the only + remaining member of n is @id.
      4. +
      +
    2. +
    3. Append node to result after removing its + usages member, unless the only remaining member of + node is @id.
    4. +
    +
  14. +
  15. Return result.
  16. +
+
+
+ +
+

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.

+ +
+

Overview

+ +

RDF literals are transformed to + value objects whereas IRIs and + blank node identifiers are + transformed to node objects. + If the use native types 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 + .

+
+ +
+

Algorithm

+ +

This algorithm takes two required inputs: a value to be converted + to a dictionary and a flag use native types.

+ +
    +
  1. If value is an IRI or a + blank node identifier, return a new dictionary + consisting of a single member @id whose value is set to + value.
  2. +
  3. Otherwise value is an + RDF literal: +
      +
    1. Initialize a new empty dictionary result.
    2. +
    3. Initialize converted value to value.
    4. +
    5. Initialize type to null
    6. +
    7. If use native types is true +
        +
      1. If the + datatype IRI + of value equals xsd:string, set + converted value to the + lexical form + of value.
      2. +
      3. 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.
      4. +
      5. 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.
      6. +
      +
    8. +
    9. Otherwise, if value is a + language-tagged string + add a member @language to result and set its value to the + language tag of value.
    10. +
    11. Otherwise, set type to the + datatype IRI + of value, unless it equals xsd:string which is ignored.
    12. +
    13. Add a member @value to result whose value + is set to converted value.
    14. +
    15. If type is not null, add a member @type + to result whose value is set to type.
    16. +
    17. Return result.
    18. +
    +
  4. +
+
+
+ +
+

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 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 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:

+ +
+    
+    
+ +

The canonical lexical form of a double, i.e., a + number with a non-zero fractional part or a number + coerced to xsd:double, consists of a mantissa followed by the + character E, followed by an exponent. The mantissa is a + decimal number and the exponent is an integer. Leading zeros and a + preceding plus sign (+) are prohibited in the exponent. + If the exponent is zero, it is indicated by E0. For the + mantissa, the preceding optional plus sign is prohibited and the + decimal point is required. Leading and trailing zeros are prohibited + subject to the following: number representations must be normalized + such that there is a single digit which is non-zero to the left of + the decimal point and at least a single digit to the right of the + decimal point unless the value being represented is zero. The + canonical representation for zero is 0.0E0. + xsd:double's value space is defined by the IEEE + double-precision 64-bit floating point type [[!IEEE-754-2008]] whereas + the value space of JSON numbers is not + specified; when deserializing JSON-LD to RDF the mantissa is rounded to + 15 digits after the decimal point. In JavaScript, implementers + can use the following snippet of code to convert a double to + canonical lexical form:

+ +
+    
+    
+ +

The canonical lexical form of the boolean + values true and false are the strings + true and false.

+ +

When JSON-native numbers are deserialized + to RDF, lossless data round-tripping cannot be guaranteed, as rounding + errors might occur. When + serializing RDF as JSON-LD, + similar rounding errors might occur. Furthermore, the datatype or the lexical + representation might be lost. An xsd:double with a value + of 2.0 will, e.g., result in an xsd:integer + with a value of 2 in canonical lexical form + when converted from RDF to JSON-LD and back to RDF. It is important + to highlight that in practice it might be impossible to losslessly + convert an xsd:integer to a number because + its value space is not limited. While the JSON specification [[!RFC7159]] + 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 use native types 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 use native types 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 + http://example.com/ would be serialized as http:\/\/example.com\/. + This is problematic as other JSON parsers might not understand those escaping characters. + There is no need to backslash-escape forward slashes in JSON-LD. To aid + interoperability between JSON-LD processors, forward slashes MUST NOT be + backslash-escaped.

+
+
+ + +
+

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 asynchronous operations. + Promises are defined in [[ECMASCRIPT-6.0]]. + General use within specifications can be found in [[promises-guide]].

+ +
+

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 passing a JsonLdError with the corresponding error + 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.

+ +
+      [Constructor]
+      interface JsonLdProcessor {
+        static Promise<JsonLdDictionary> compact(
+          JsonLdInput input,
+          JsonLdContext context,
+          optional JsonLdOptions? options);
+        static Promise<sequence<JsonLdDictionary>> expand(
+          JsonLdInput input,
+          optional JsonLdOptions? options);
+        static Promise<JsonLdDictionary> flatten(
+          JsonLdInput input,
+          optional JsonLdContext? context,
+          optional JsonLdOptions? options);
+      };
+    
+ +
+
compact
+
+

Compacts the given input using the + context according to the steps in the + Compaction algorithm:

+ +
    +
  1. Create a new Promise promise and return it. The + following steps are then executed asynchronously.
  2. +
  3. Set expanded input to the result of using the + expand + method using input and options. +
  4. If context is a dictionary having an @context member, set + context to that member's value, otherwise to context.
  5. +
  6. Initialize an active context using context; + the base IRI is set 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.
  7. +
  8. Set compacted output to the result of using the + Compaction algorithm, using active context, + an empty dictionary as inverse context, + null as property, + expanded input as element, and if passed, the + compactArrays flag in options.
  9. +
  10. Fulfill the promise passing compacted output. + transforming compacted output from the + internal representation to a JSON serialization.
  11. +
+ +
+
input
+
The dictionary, array of dictionaries 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 dictionary, an + IRI, or an array consisting of + dictionaries and IRIs.
+
options
+
A set of options to configure the algorithms. This allows, e.g., + to set the input document's base IRI.
+
+
+ +
expand
+
+

Expands the given input according to + the steps in the Expansion algorithm:

+ +
    +
  1. Create a new Promise promise and return it. The + following steps are then executed asynchronously.
  2. +
  3. If the passed input is a string + representing the IRI of a remote document, dereference it. + If the retrieved document's content type is neither application/json, + nor application/ld+json, nor any other media type using a + +json suffix as defined in [[RFC6839]], reject the promise passing an + loading document failed + error.
  4. +
  5. Initialize a new empty active context. The base IRI + of the active context is set to the IRI of the currently being processed + document, if available; otherwise to null. If set, the + base option from options overrides the base IRI.
  6. +
  7. If an + expandContext option + has been passed, update the active context using the + Context Processing algorithm, passing the + expandContext + as local context. If + expandContext + is a dictionary having an @context member, pass that member's value instead.
  8. +
  9. Once input has been retrieved, the response has an HTTP Link Header [[!RFC5988]] + using the http://www.w3.org/ns/json-ld#context link relation + and a content type of application/json or any media type + with a +json suffix as defined in [[RFC6839]] except + application/ld+json, update the active context using the + Context Processing algorithm, passing the + context referenced in the HTTP Link Header as local context. The + HTTP Link Header is ignored for documents served as application/ld+json If + multiple HTTP Link Headers using the http://www.w3.org/ns/json-ld#context + link relation are found, the promise is rejected with a JsonLdError whose code is set to + multiple context link headers + and processing is terminated.
  10. +
  11. If necessary, transform input into the + internal representation. If input cannot be transformed to the + internal representation, reject promise passing a + loading document failed error.
  12. +
  13. Set expanded output to the result of using the + Expansion algorithm, passing the + active context and input as element, + and, if the frameExpansion option is set, pass the frame expansion flag as true..
  14. +
  15. Fulfill the promise passing expanded output. + transforming expanded output from the + internal representation to a JSON serialization.
  16. +
+ +
+
input
+
The dictionary or array of dictionaries 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 such. This allows, e.g., + to set the input document's base IRI.
+
+
+ +
flatten
+
+

Flattens the given input and + compacts it using the passed context + according to the steps in the Flattening algorithm:

+ +
    +
  1. Create a new Promise promise and return it. The + following steps are then executed asynchronously.
  2. +
  3. Set expanded input to the result of using the + expand + method using input and options. +
  4. If context is a dictionary having an @context member, set + context to that member's value, otherwise to context.
  5. +
  6. Initialize an active context using context; + the base IRI is set 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.
  7. +
  8. Initialize an empty identifier map and a counter (set to 0) + to be used by the + Generate Blank Node Identifier algorithm.
  9. +
  10. Set flattened output to the result of using the + Flattening algorithm, passing + expanded input as element, active context, and if passed, the + compactArrays flag in options + (which is internally passed to the + Compaction algorithm).
  11. +
  12. Fulfill the promise passing flattened output. + transforming flattened output from the + internal representation to a JSON serialization.
  13. +
+ +
+
input
+
The dictionary or array of dictionaries 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 dictionary, an + IRI, or an array consisting of dictionaries + and IRIs. If not + passed or null is passed, the result will not be compacted + but kept in expanded form.
+
options
+
A set of options to configure the used algorithms such. This allows, e.g., + to set the input document's base IRI.
+
+
+
+ +
+

The JsonLdDictionary is the definition of a dictionary + used to contain arbitrary key/value pairs which are the result of + parsing a JSON Object. + +

+ +

The JsonLdInput type is used to refer to an input value that + that may be a dictionary, an array of dictionaries or a string representing an + IRI which an be dereferenced to retrieve a valid JSON document.

+ +
+ +

The JsonLdContext type is used to refer to a value that + that may be a dictionary, a string representing an + IRI, or an array of dictionaries + and strings.

+
+ +
+

The JsonLdOptions Type

+ +

The JsonLdOptions type is used to pass various options to the + JsonLdProcessor methods.

+ +
+ +
+
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. +
+
documentLoader
+
The callback of the loader to be used to retrieve remote documents and contexts. + 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.
+
produceGeneralizedRdf
+
If set to true, the JSON-LD processor may emit blank nodes for + triple predicates, otherwise they will be omitted.
+
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.
+
compactToRelative
+
Determines if IRIs are compacted relative to the + base option or document location when compacting.
+
frameExpansion
+
Enables special frame processing rules for the Expansion Algorithm.
+
+
+ +
+

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.

+ +
+

LoadDocumentCallback

+ +

The LoadDocumentCallback defines a callback that custom document loaders + have to implement to be used to retrieve remote documents and contexts.

+ +
+ +
+
url
+
The URL of the remote document or context to load.
+
+ +

All errors result in the Promise being rejected with + a JsonLdError whose code is set to + loading document failed + or multiple context link headers + as described in the next section.

+
+ +
+

RemoteDocument

+ +

The RemoteDocument type is used by a LoadDocumentCallback + to return information about a remote document or context.

+ +
+ +
+
contextUrl
+
If available, the value of the HTTP Link Header [[!RFC5988]] using the + http://www.w3.org/ns/json-ld#context 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 http://www.w3.org/ns/json-ld#context link relation are found, + the Promise of the LoadDocumentCallback is rejected with + a JsonLdError whose code is set to + multiple context link headers.
+
documentUrl
+
The final URL of the loaded document. This is important + to handle HTTP redirects properly.
+
document
+
The retrieved document. This can either be the raw payload or the already + parsed document.
+
+
+
+ +
+

Error Handling

+ +

This section describes the datatype definitions used within the + JSON-LD API for error handling.

+ +
+

JsonLdError

+ +

The JsonLdError type is used to report processing errors.

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

JsonLdErrorCode

+

The JsonLdErrorCode represents the collection of valid JSON-LD error + codes.

+ +
+ +
+
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.
+
compaction to list of lists
+
The compacted document contains a list of lists as multiple + lists have been compacted to the same term.
+
conflicting indexes
+
Multiple conflicting indexes have been found for the same node.
+
cyclic IRI mapping
+
A cycle in IRI mappings has been detected.
+
invalid @id value
+
An @id member was encountered whose value was not a + string.
+
invalid @index value
+
An @index member 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 @reverse value
+
An invalid value for an @reverse member has been detected, + i.e., the value was not a dictionary.
+
invalid @version value
+
The @version key was used in a context with + an out of range value.
+
invalid base IRI
+
An invalid base IRI has been detected, i.e., it is + neither an absolute IRI nor null.
+
invalid container mapping
+
An @container member was encountered whose value was + not one of the following strings: + @list, @set, or @index.
+
invalid default language
+
The value of the default language is not a string + or null and thus invalid.
+
invalid IRI mapping
+
A local context contains a term that has + an invalid or missing IRI mapping.
+
invalid 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 has to be a string or an array of + strings.
+
invalid language mapping
+
An @language member in a term definition + was encountered whose value was neither a string nor + null and thus invalid.
+
invalid language-tagged string
+
A language-tagged string with an invalid language + value was detected.
+
invalid language-tagged value
+
A number, true, 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 set or list object
+
A set object or list object with + disallowed members has been detected.
+
invalid term definition
+
An invalid term definition has been detected.
+
invalid type mapping
+
An @type member in a term definition + was encountered whose value could not be expanded to an + absolute IRI.
+
invalid type value
+
An invalid value for an @type member has been detected, + i.e., the value was neither a string nor an array + of strings.
+
invalid typed value
+
A typed value with an invalid type was detected.
+
invalid value object
+
A value object with disallowed members has been + detected.
+
invalid value object value
+
An invalid value for the @value member 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 absolute IRI nor null.
+
keyword redefinition
+
A keyword redefinition has been detected.
+
list of lists
+
A list of lists was detected. List of lists are not supported in + this version of JSON-LD due to the algorithmic complexity.
+
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 [[!RFC5988]] using the + http://www.w3.org/ns/json-ld#context link relation + have been detected.
+
processing mode conflict
+
An attempt was made to change the processing mode which is + incompatible with the previous specified version.
+
recursive context inclusion
+
A cycle in remote context inclusions has been detected.
+
+
+
+
+ +
+
+ +
+

Security Considerations

+

Consider requirements from Self-Review Questionnaire: Security and Privacy.

+
+ +
+

Changes since 1.0 Recommendation of 16 January 2014

+ +
+ +
+

Open Issues

+

The following is a list of issues open at the time of publication.

+ +
+ + + +