This document is also available in this non-normative format: diff to previous version.
This document is licensed under a Creative Commons Attribution 3.0 License.
JSON [RFC4627] has proven to be a highly useful object serialization and messaging format. JSON-LD [JSON-LD] harmonizes the representation of Linked Data in JSON by outlining a common JSON representation format for expressing directed graphs; mixing both Linked Data and non-Linked Data in a single document. This document outlines an Application Programming Interface and a set of algorithms for programmatically transforming JSON-LD documents.
This document is merely a public working draft of a potential specification. It has no official standing of any kind and does not represent the support or consensus of any standards organisation.
This document is an experimental work in progress.
JSON, as specified in [RFC4627], is a simple language for representing data on the Web. Linked Data is a technique for creating a graph of interlinked data across different documents or Web sites. Data entities are described using IRIs, which are typically dereferencable and thus may be used to find more information about an entity, creating a "Web of Knowledge". JSON-LD is intended to be a simple publishing method for expressing not only Linked Data in JSON, but also for adding semantics to existing JSON.
JSON-LD is designed as a light-weight syntax that can be used to express Linked Data. It is primarily intended to be a way to use Linked Data in Javascript and other Web-based programming environments. It is also useful when building interoperable Web services and when storing Linked Data in JSON-based document storage engines. It is practical and designed to be as simple as possible, utilizing the large number of JSON parsers and libraries available today. It is designed to be able to express key-value pairs, RDF data, RDFa [RDFA-CORE] data, Microformats [MICROFORMATS] data, and Microdata [MICRODATA]. That is, it supports every major Web-based structured data model in use today.
The syntax does not necessarily require applications to change their JSON, but allows to easily add meaning by adding context in a way that is either in-band or out-of-band. The syntax is designed to not disturb already deployed systems running on JSON, but provide a smooth upgrade path from JSON to JSON with added semantics. Finally, the format is intended to be easy to parse, efficient to generate, convertible to RDF in one pass, and require a very small memory footprint in order to operate.
This document is a detailed specification for a serialization of Linked Data in JSON. 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 [RFC4627]. You must also understand the JSON-LD Syntax [JSON-LD], 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 [ECMA-262] and WebIDL [WEBIDL]. To understand how JSON-LD maps to RDF, it is helpful to be familiar with the basic RDF concepts [RDF-CONCEPTS].
Examples may contain references to existing vocabularies and use prefixes to refer to Web Vocabularies. The following is a list of all vocabularies and their prefix abbreviations, as used in this document:
dc
, e.g., dc:title
)foaf
, e.g., foaf:knows
)rdf
, e.g., rdf:type
)xsd
, e.g., xsd:integer
)JSON [RFC4627] defines several terms which are used throughout this document:
The following definition for Linked Data is the one that will be used for this specification.
Note that the definition for Linked Data above is silent on the topic of unlabeled nodes. Unlabeled nodes are not considered Linked Data. However, this specification allows for the expression of unlabled nodes, as most graph-based data sets on the Web contain a number of associated nodes that are not named and thus are not directly de-referenceable.
There are a number of ways that one may participate in the development of this specification:
This API provides a clean mechanism that enables developers to convert JSON-LD data into a a variety of output formats that are easier to work with in various programming languages. If a JSON-LD API is provided in a programming environment, the entirety of the following API must be implemented.
[NoInterfaceObject]
interface JsonLdProcessor {
object expand (object input, optional object? context) raises (InvalidContext);
object compact (object input, optional object? context) raises (InvalidContext, ProcessingError);
object frame (object input, object frame, object options) raises (InvalidFrame);
DOMString normalize (object input, optional object? context) raises (InvalidContext);
void triples (object input, JsonLdTripleCallback
tripleCallback, optional object? context) raises (InvalidContext);
};
compact
input
according to the steps in the
Compaction Algorithm. The
input
must be copied, compacted and returned if there are
no errors. If the compaction fails, an appropirate exception must be
thrown.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
input | object | ✘ | ✘ | The JSON-LD object to perform compaction on. |
context | object | ✔ | ✔ | The base context to use when compacting the input . |
Exception | Description | ||||
---|---|---|---|---|---|
InvalidContext |
| ||||
ProcessingError |
|
object
expand
input
according to the steps in the
Expansion Algorithm. The
input
must be copied, expanded and returned if there are
no errors. If the expansion fails, an appropriate exception must be thrown.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
input | object | ✘ | ✘ | The JSON-LD object to copy and perform the expansion upon. |
context | object | ✔ | ✔ | An external context to use additionally to the context embedded in input when expanding the input . |
Exception | Description | ||||
---|---|---|---|---|---|
InvalidContext |
|
object
frame
input
using the frame
according to the steps in the
Framing Algorithm. The
input
is used to build the framed output and is returned if
there are no errors. If there are no matches for the frame,
null
must be returned. Exceptions must be thrown if there are
errors.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
input | object | ✘ | ✘ | The JSON-LD object to perform framing on. |
frame | object | ✘ | ✘ | The frame to use when re-arranging the data. |
options | object | ✘ | ✘ | A set of options that will affect the framing algorithm. |
Exception | Description | ||||
---|---|---|---|---|---|
InvalidFrame |
|
object
normalize
input
according to the steps in the
Normalization Algorithm. The
input
must be copied, normalized and returned if there are
no errors. If the compaction fails, null
must be returned.
The output is the serialized representation returned from the
Normalization Algorithm.
It's still an open question if the result is a DOMString
representing the serialized graph in JSON-LD, or an array representation
which is in normalized form.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
input | object | ✘ | ✘ | The JSON-LD object to perform normalization upon. |
context | object | ✔ | ✔ | An external context to use additionally to the context embedded in
input when expanding the input . |
Exception | Description | ||||
---|---|---|---|---|---|
InvalidContext |
|
DOMString
triples
input
according to the
RDF Conversion Algorithm, calling
the provided tripleCallback
for each triple generated.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
input | object | ✘ | ✘ | The JSON-LD object to process when outputting triples. |
tripleCallback |
| ✘ | ✘ | A callback that is called whenever a processing error occurs on
the given input .
This callback should be aligned with the
RDF API. |
context | object | ✔ | ✔ | An external context to use additionally to the context embedded in
input when expanding the input . |
Exception | Description | ||||
---|---|---|---|---|---|
InvalidContext |
|
void
The JsonLdTripleCallback is called whenever the processor generates a
triple during the triple()
call.
[NoInterfaceObject Callback]
interface JsonLdTripleCallback {
void triple (DOMString subject, DOMString property, DOMString objectType, DOMString object, DOMString? datatype, DOMString? language);
};
triple
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
subject | DOMString | ✘ | ✘ | The subject IRI that is associated with the triple. |
property | DOMString | ✘ | ✘ | The property IRI that is associated with the triple. |
objectType | DOMString | ✘ | ✘ | The type of object that is associated with the triple. Valid values
are IRI and literal . |
object | DOMString | ✘ | ✘ | The object value associated with the subject and the property. |
datatype | DOMString | ✔ | ✘ | The datatype associated with the object. |
language | DOMString | ✔ | ✘ | The language associated with the object in BCP47 format. |
void
All algorithms described in this section are intended to operate on language-native data structures. That is, the serialization to a text-based JSON document isn't required as input or output to any of these algorithms and language-native data structures must be used where applicable.
JSON-LD specifies a number of syntax tokens and keywords that are using in all algorithms described in this section:
@context
@id
@language
@type
@value
:
All JSON-LD tokens and keywords are case-sensitive.
@context
keyword.
Processing of JSON-LD data structure is managed recursively. During processing, each rule is applied using information provided by the active context. Processing begins by pushing a new processor state onto the processor state stack and initializing the active context with the initial context. If a local context is encountered, information from the local context is merged into the active context.
The active context is used for expanding keys and values of a JSON object (or elements of a list (see List Processing)) using a term mapping. It is also used to maintain coercion mappings from IRIs associated with terms to datatypes, and list mappings for IRIs associated with terms.
A local context is identified within a JSON object having a key of
@context
with string, array or a JSON object value.
When processing a local context, special processing rules apply:
@context
@context
element using the JSON Pointer "/@context" as described in [JSON-POINTER]. Set value
to the extracted content, or an empty JSON Object if no value exists.@language
key, it must have a value of a
simple string or null
. Add the language to the local context.@id
key with a string value, the value must have the
form of term, prefix:suffix, absolute IRI. Determine the IRI mapping value
by performing IRI Expansion on the associated value. If the result of
the IRI mapping is an absolute IRI, merge the key-value pair into the local context
term mapping.@type
key, the value must have the form of term,
prefix:suffix, absolute IRI or the keyword @id
. Determine the IRI by
performing IRI Expansion on the associated value. If the result of the
IRI mapping is an absolute IRI or @id
, merge into the local context
coercion mapping.@list
key, the value must be
true
or false
. Merge into the local context list
mapping.It can be difficult to distinguish between a prefix:suffix
and an absolute IRI,
as a prefix may seem to be a valid IRI scheme. When performing repeated IRI expansion,
a term used as a prefix may not have a valid mapping due to dependencies in resolving term definitions. By
continuing Step 3.2 until no changes are made, mappings to IRIs created
using an undefined term prefix will eventually resolve to absolute IRIs.
Issue 43 concerns performing IRI expansion in the key position of a context definition.
Keys and some values are evaluated to produce an IRI. This section defines an algorithm for transforming a value representing an IRI into an actual IRI.
IRIs may be represented as an absolute IRI, a term or a prefix:suffix construct.
The algorithm for generating an IRI is:
Previous versions of this specification used @base
and @vocab
to define IRI prefixes
used to resolve relative IRIs. It was determined that this added too much complexity, but the issue
can be re-examined in the future based on community input.
Some keys and values are expressed using IRIs. This section defines an algorithm for transforming an IRI to a compact IRI using the terms specified in the local context.
The algorithm for generating a compacted IRI is:
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.
The algorithm for expanding a value takes an active property and active context. It is implemented as follows:
@value
and
the string representation of value. The second key-value pair will be @type>
,
and the expanded version of xsd:boolean
, xsd:integer
, or xsd:double
,
depending on value.@id
coercion,
expand the value by adding a new key-value pair where the
key is @id
and the value is the expanded IRI according to the IRI
Expansion rules.@value
and the unexpanded value. The second key-value pair will be @type
and the associated coercion
datatype expanded according to the IRI Expansion rules.@language
,
expand value by adding two new key-value pairs. The first key-value pair will be @value
and the unexpanded value. The second key-value pair will be @language
and value of
@language
from the active context.Some values, such as IRIs and typed literals, may be expressed in an expanded form in JSON-LD. These values are required to be compacted at times when processing JSON-LD documents.
The algorithm for compacting an expanded value value takes an active property and active context. It is implemented as follows:
@value
value.@id
, the compacted
value is the value associated with the @id
key,
processed according to the
IRI Compaction steps.@value
key.@id
key, the compacted value is value with
the value of @id
processed according to the
IRI Compaction steps.@language
, which
matches the @language
of the value, or the value has only a @value
key, the compacted
value is the value associated with the @value
key.@type
key, the compacted value
is value with the @type
value processed according to the
IRI Compaction steps.Expansion is the process of taking a JSON-LD document and applying a context such that all IRI, datatypes, and literal values are expanded so that the context is no longer necessary. JSON-LD document expansion is typically used as a part of Framing or Normalization.
For example, assume the following JSON-LD input document:
{ "@context": { "name": "http://xmlns.com/foaf/0.1/name", "homepage": { "@id": "http://xmlns.com/foaf/0.1/homepage", "@type", "@id" } }, "name": "Manu Sporny", "homepage": "http://manu.sporny.org/" }
Running the JSON-LD Expansion algorithm against the JSON-LD input document provided above would result in the following output:
{ "http://xmlns.com/foaf/0.1/name": "Manu Sporny", "http://xmlns.com/foaf/0.1/homepage": { "@id": "http://manu.sporny.org/" } }
The algorithm takes three input variables: an active context, an active property, and a value to be expanded. To begin, the active context is set to the initial context, active property is set to nil, and value is set to the JSON-LD input.
@id
or @type
and the value is a string,
expand the value according to IRI Expansion.@value
, the value must be a string and
is not subject to further expansion.@list
expansion, replace the value with a new key-value key where the key is @list
and value
set to the current value.Compaction is the process of taking a JSON-LD document and applying a context such that the most compact form of the document is generated. JSON is typically expressed in a very compact, key-value format. That is, full IRIs are rarely used as keys. At times, a JSON-LD document may be received that is not in its most compact form. JSON-LD, via the API, provides a way to compact a JSON-LD document.
For example, assume the following JSON-LD input document:
{ "http://xmlns.com/foaf/0.1/name": "Manu Sporny", "http://xmlns.com/foaf/0.1/homepage": { "@id": "http://manu.sporny.org/" } }
Additionally, assume the following developer-supplied JSON-LD context:
{ "name": "http://xmlns.com/foaf/0.1/name", "homepage": { "@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id" } }
Running the JSON-LD Compaction algorithm given the context supplied above against the JSON-LD input document provided above would result in the following output:
{ "@context": { "name": "http://xmlns.com/foaf/0.1/name", "homepage": { "@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id" } }, "name": "Manu Sporny", "homepage": "http://manu.sporny.org/" }
The compaction algorithm also enables the developer to map any expanded
format into an application-specific compacted format. While the context
provided above mapped http://xmlns.com/foaf/0.1/name
to
name, it could have also mapped it to any arbitrary string
provided by the developer.
The algorithm takes two input variables: an active property, and a value to be expanded. To begin, the active property is set to nil, and value is set to the result of performing the Expansion Algorithm on the JSON-LD input. This removes any existing context to allow the given context to be cleanly applied. The active context to the given context.
@id
or @type
@id
key or the value contains a
@value
key, the compacted value is the result of performing
Value Compaction on the value.@list
key, and the
active property is subject to list coercion, the compacted value is the result of
performing this algorithm on that value.JSON-LD Framing allows developers to query by example and force a specific tree layout to a JSON-LD document.
A JSON-LD document is a representation of a directed graph. A single directed graph can have many different serializations, each expressing exactly the same information. Developers typically work with trees, represented as JSON objects. While mapping a graph to a tree can be done, the layout of the end result must be specified in advance. A Frame can be used by a developer on a JSON-LD document to specify a deterministic layout for a graph.
Framing is the process of taking a JSON-LD document, which expresses a graph of information, and applying a specific graph layout (called a Frame).
The JSON-LD document below expresses a library, a book and a chapter:
{ "@context": { "Book": "http://example.org/vocab#Book", "Chapter": "http://example.org/vocab#Chapter", "contains": { "@id": "http://example.org/vocab#contains", "@type": "@id" }, "creator": "http://purl.org/dc/terms/creator", "description": "http://purl.org/dc/terms/description", "Library": "http://example.org/vocab#Library", "title": "http://purl.org/dc/terms/title" }, "@id": [{ "@id": "http://example.com/library", "@type": "Library", "contains": "http://example.org/library/the-republic" }, { "@id": "http://example.org/library/the-republic", "@type": "Book", "creator": "Plato", "title": "The Republic", "contains": "http://example.org/library/the-republic#introduction" }, { "@id": "http://example.org/library/the-republic#introduction", "@type": "Chapter", "description": "An introductory chapter on The Republic.", "title": "The Introduction" }] }
Developers typically like to operate on items in a hierarchical, tree-based fashion. Ideally, a developer would want the data above sorted into top-level libraries, then the books that are contained in each library, and then the chapters contained in each book. To achieve that layout, the developer can define the following frame:
{ "@context": { "Book": "http://example.org/vocab#Book", "Chapter": "http://example.org/vocab#Chapter", "contains": "http://example.org/vocab#contains", "creator": "http://purl.org/dc/terms/creator" "description": "http://purl.org/dc/terms/description" "Library": "http://example.org/vocab#Library", "title": "http://purl.org/dc/terms/title" }, "@type": "Library", "contains": { "@type": "Book", "contains": { "@type": "Chapter" } } }
When the framing algorithm is run against the previously defined JSON-LD document, paired with the frame above, the following JSON-LD document is the end result:
{ "@context": { "Book": "http://example.org/vocab#Book", "Chapter": "http://example.org/vocab#Chapter", "contains": "http://example.org/vocab#contains", "creator": "http://purl.org/dc/terms/creator" "description": "http://purl.org/dc/terms/description" "Library": "http://example.org/vocab#Library", "title": "http://purl.org/dc/terms/title" }, "@id": "http://example.org/library", "@type": "Library", "contains": { "@id": "http://example.org/library/the-republic", "@type": "Book", "creator": "Plato", "title": "The Republic", "contains": { "@id": "http://example.org/library/the-republic#introduction", "@type": "Chapter", "description": "An introductory chapter on The Republic.", "title": "The Introduction" }, }, }
This algorithm is a work in progress, do not implement it. There was also a recent update to the algorithm in order to auto-embed frame-unspecified data (if the explicit inclusion flag is not set) in order to preserve graph information. This change is particularly important for comparing subgraphs (or verifying digital signatures on subgraphs). This change is not yet reflected in the algorithm below.
The framing algorithm takes JSON-LD input that has been normalized according to the Normalization Algorithm (normalized input), an input frame that has been expanded according to the Expansion Algorithm (expanded frame), and a number of options and produces JSON-LD output. The following series of steps is the recursive portion of the framing algorithm:
null
.Invalid Frame Format
exception. Add each matching item from the normalized input
to the matches array and decrement the
match limit by 1 if:
rdf:type
that exists in the item's list of rdf:type
s. Note:
the rdf:type
can be an array, but only one value needs
to be in common between the item and the
expanded frame for a match.rdf:type
property, but every property in the
expanded frame exists in the item.matches array not defined anywhere.
@embed
keyword, set the object embed flag to its value.
If the match frame contains an @explicit
keyword, set the explicit inclusion flag to its value.
Note: if the keyword exists, but the value is neither
true
or false
, set the associated flag to
true
.@id
property, replace the item with the value
of the @id
property.@id
property, and its IRI is in the
map of embedded subjects, throw a
Duplicate Embed
exception.@id
property and its IRI is not in the
map of embedded subjects:
@id
.rdf:type
:
@id
value that exists in the
normalized input, replace the object in the
recursion input list with a new object containing
the @id
key where the value is the value of
the @id
, and all of the other key-value pairs for
that subject. Set the recursion match frame to the
value associated with the match frame's key. Replace
the value associated with the key by recursively calling this
algorithm using recursion input list,
recursion match frame as input.null
otherwise.null
,
process the omit missing properties flag:
@omitDefault
keyword, set the
omit missing properties flag to its value.
Note: if the keyword exists, but the value is neither
true
or false
, set the associated
flag to true
.@default
keyword is set in the
property frame set the item's value to the value
of @default
.null
set it to
the item, otherwise, append the item to the
JSON-LD output.The final, non-recursive step of the framing algorithm requires the JSON-LD output to be compacted according to the Compaction Algorithm by using the context provided in the input frame. The resulting value is the final output of the compaction algorithm and is what should be returned to the application.
What are the implications for framing lists?
This algorithm is a work in progress, do not implement it.
Normalization is the process of taking JSON-LD input and performing a deterministic transformation on that input that results in a normalized and serialized JSON-LD representation.
Normalization is achieved by transforming JSON-LD input to RDF, as described in RDF Conversion, invoking the normalization procedure as described in [RDF-NORMALIZATION], returning the serialized results.
There an open issue (ISSUE-53) on the purpose and results of performing normalization. Previous versions of the specification generated JSON-LD as the result of the normalization algorithm, however normalization is a process required across different linked data serializations. To be useful, a graph requires an identical normalized representation that is independent of the data format originally used for markup, or the way in which language features or publisher preferences create differences in the markup of identical graphs.
It may be that the need for either or both of flattening algorithm or to retrieve such a cryptographic signature.
Normalization is useful when comparing two graphs against one another, when generating a detailed list of differences between two graphs, and when generating a cryptographic digital signature for information contained in a graph or when generating a hash of the information contained in a graph.
The example below is an un-normalized JSON-LD document:
{ "@context": { "name": "http://xmlns.com/foaf/0.1/name", "homepage": { "@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id" }, "xsd": "http://www.w3.org/2001/XMLSchema#" }, "name": "Manu Sporny", "homepage": "http://manu.sporny.org/" }
The example below is the normalized form of the JSON-LD document above:
Whitespace is used below to aid readability. The normalization algorithm for JSON-LD removes all unnecessary whitespace in the fully normalized form.
Not clear that whitespace must be normalized, as the JSON-LD representation can't be used directly to create a signature, but would be based on the serialized result of [RDF-NORMALIZATION].
[{ "@id": "_:c14n0", "http://xmlns.com/foaf/0.1/homepage": { "@id": "http://manu.sporny.org/" }, "http://xmlns.com/foaf/0.1/name": "Manu Sporny" }]
Notice how all of the terms have been expanded and sorted in alphabetical order. Also, notice how the subject has been labeled with a named blank node. Normalization ensures that any arbitrary graph containing exactly the same information would be normalized to exactly the same form shown above.
The normalization algorithm transforms the JSON-LD input into RDF, normalizes it according to [RDF-NORMALIZATION] and then transforms back to JSON-LD. The result is an object representation that deterministically represents a RDF graph.
http://www.w3.org/1999/02/22-rdf-syntax-ns#first
,
let object representation be object represented in expanded
form as described in Value Expansion.
@list
and an
array containing object representation.http://www.w3.org/1999/02/22-rdf-syntax-ns#rest
, ignore this triple.@id
having a value of subject:
@id
and
a string representation of subject and use as value.predicate
is http://www.w3.org/1999/02/22-rdf-syntax-ns#type
:
@type
and an array,
append the string representation of object to that array.@type
, replace that value
with a new array containing the existing value and a string representation of
object.@type
and value being a
string representation of object.When normalizing xsd:double values, implementers must
ensure that the normalized value is a string. In order to generate the
string from a double value, output equivalent to the
printf("%1.6e", value)
function in C must be used where
"%1.6e" is the string formatter and value
is the value to be converted.
To convert the a double value in JavaScript, implementers can use the following snippet of code:
// the variable 'value' below is the JavaScript native double value that is to be converted (value).toExponential(6).replace(/(e(?:\+|-))([0-9])$/, '$10$2')
When data needs to be normalized, JSON-LD authors should not use values that are going to undergo automatic conversion. This is due to the lossy nature of xsd:double values.
Some JSON serializers, such as PHP's native implementation,
backslash-escapes the forward slash character. For example, the value
http://example.com/
would be serialized as
http:\/\/example.com\/
in some
versions of PHP. This is problematic when generating a byte
stream for processes such as normalization. There is no need to
backslash-escape forward-slashes in JSON-LD. To aid interoperability between
JSON-LD processors, a JSON-LD serializer must not backslash-escape
forward slashes.
Round-tripping data can be problematic if we mix and match coercion rules with JSON-native datatypes, like integers. Consider the following code example:
var myObj = { "@context" : { "number" : { "@id": "http://example.com/vocab#number", "@type": "xsd:nonNegativeInteger" } }, "number" : 42 }; // Map the language-native object to JSON-LD var jsonldText = jsonld.normalize(myObj); // Convert the normalized object back to a JavaScript object var myObj2 = jsonld.parse(jsonldText);
At this point, myObj2 and myObj will have different values for the "number" value. myObj will be the number 42, while myObj2 will be the string "42". This type of data round-tripping error can bite developers. We are currently wondering if having a "coercion validation" phase in the parsing/normalization phases would be a good idea. It would prevent data round-tripping issues like the one mentioned above.
A JSON-LD document may be converted to any other RDF-compatible document format using the algorithm specified in this section.
The JSON-LD Processing Model describes processing rules for extracting RDF from a JSON-LD document. Note that many uses of JSON-LD may not require generation of RDF.
The processing algorithm described in this section is provided in order to demonstrate how one might implement a JSON-LD to RDF processor. Conformant implementations are only required to produce the same type and number of triples during the output process and are not required to implement the algorithm exactly as described.
This section is non-normative.
JSON-LD is intended to have an easy to parse grammar that closely models existing practice in using JSON for describing object representations. This allows the use of existing libraries for parsing JSON.
As with other grammars used for describing Linked Data, a key concept is that of a resource. Resources may be of three basic types: IRIs, for describing externally named entities, BNodes, resources for which an external name does not exist, or is not known, and Literals, which describe terminal entities such as strings, dates and other representations having a lexical representation possibly including an explicit language or datatype.
An Internationalized Resource Identifier (IRI), as described in [RFC3987], is a mechanism for representing unique identifiers on the web. In Linked Data, an IRI is commonly used for expressing a subject, a property or an object.
Data described with JSON-LD may be considered to be the representation of a graph made up of subject and object resources related via a property resource. However, specific implementations may choose to operate on the document as a normal JSON description of objects having attributes.
The algorithm below is designed for in-memory implementations with random access to JSON object elements.
A conforming JSON-LD processor implementing RDF conversion must implement a processing algorithm that results in the same default graph that the following algorithm generates:
@context
key, process the local context as
described in Context.
@value
key, set the active object
to a literal value as follows:
@type
key
after performing IRI Expansion on the specified@type
.
@language
key, use it's value to set the language of the plain literal.
@list
key and the value is an array
process the value as a list as described in List Conversion.
@id
key:
@id
key, set the active
object to newly generated blank node. Generate a triple
representing the active subject, the active property and the
active object. Set the active subject to the active
object.
@type
, set the active property
to rdf:type
.
@list
coercion,
and the value is an array,
process the value as a list as described in in List Conversion.
@id
coercion,
set the active object by
performing IRI Expansion on the string.
language
key with a non-null
value,
use it's value to set the language of the plain literal.
xsd:integer
or
xsd:double
, depending on if the value contains a
fractional and/or an exponential component. Generate a triple using the active
subject, active property and the generated typed literal.
xsd:boolean
.
List Conversion is the process of taking an array of values and adding them to a newly
created RDF Collection (see
[RDF-SCHEMA]) by linking each element of the list using rdf:first
and rdf:next
,
terminating the list with rdf:nil
using the following sequence:
The algorithm is invoked with an array array, the active property, and the active context and returns a value to be used as an active object.
rdf:nil
.
rdf:first
as the active property.
rdf:nil
.rdf:rest
and rest blank node.The editors would like to thank Mark Birbeck, who provided a great deal of the initial push behind the JSON-LD work via his work on RDFj, Dave Lehn and Mike Johnson who reviewed, provided feedback, and performed several implementations of the specification, and Ian Davis, who created RDF/JSON. Thanks also to Nathan Rixham, Bradley P. Allen, Kingsley Idehen, Glenn McDonald, Alexandre Passant, Danny Ayers, Ted Thibodeau Jr., Olivier Grisel, Niklas Lindström, Markus Lanthaler, and Richard Cyganiak for their input on the specification.
The initial context is defined with the following default entries:
{ "@context": { "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": { "@type": "@id"} } }
Processors must act as if the initial context is defined in the outer-most level when processing JSON-LD documents.
Should we define other default prefixes?