JSON-LD API 1.0
JSON-LD API 1.0
An Application Programming Interface for the JSON-LD Syntax
Final Community Group Specification 26 June 2012
Latest editor's draft:
Editors:
Manu Sporny
Digital Bazaar
Gregg Kellogg
Kellogg Associates
Dave Longley
Digital Bazaar
Markus Lanthaler
Graz University of Technology
Authors:
Dave Longley
Digital Bazaar
Manu Sporny
Digital Bazaar
Gregg Kellogg
Kellogg Associates
Markus Lanthaler
Graz University of Technology
This document is also available in this non-normative format:
diff to previous version
2010-2012
the Contributors to the JSON-LD API 1.0 Specification, published by the
JSON for Linking Data Community Group
under the
W3C Community Final Specification Agreement (FSA)
A human-readable
summary
is available.
Abstract
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 in order to make them easier to work with in programming
environments like JavaScript, Python, and Ruby.
Status of This Document
This specification was published by the
JSON for Linking Data Community Group
It is not a W3C Standard nor is it on the W3C Standards Track.

Please note that under the
W3C Community Final Specification Agreement (FSA)
other conditions apply.

Learn more about
W3C Community and Business Groups
This document has been under development for over 18 months in the
JSON for Linking Data Community Group. The document has recently been
approved for transfer into the RDF Working Group for
review with the intent to publish the
document along the W3C
Recommendation track. This specification has undergone significant
development, review, and changes during the course of the last 18
months and is being published as a Final Community Group Specification so that
it may gain wider review and feedback.
There are currently
five interoperable implementations
of this specification. There is
fairly complete test suite
and a
live JSON-LD editor
that is capable of demonstrating the features described in
this document. While development on implementations, the test suite
and the live editor will continue, they are believed to be mature enough
to be integrated into a non-production system at this point in time with
the expectation that they could be used in a production system within the
next year.
Issue 1
It is important for readers to understand that the scope of this document is
currently under debate and new features may be added to the specification.
Existing features may be modified heavily or removed entirely from the
specification upon further review and feedback from the broader community.
This is a work in progress and publication as a First Public Working Draft
does not require that all Working Group members agree on the content of the
document.
Table of Contents
1.
Preface
1.1
Contributing
2.
Introduction
2.1
Expansion
2.2
Compaction
2.3
Conversion to and from RDF
2.4
Framing and Normalization
3.
The Application Programming Interface
3.1
General Terminology
3.2
JsonLdProcessor
3.2.1
Methods
3.3
Callbacks
3.3.1
JsonLdCallback
3.3.1.1
Methods
3.3.2
QuadCallback
3.3.2.1
Methods
3.4
Data Structures
3.4.1
URL
3.4.2
JsonLdOptions
3.4.3
Quad
3.4.3.1
Attributes
3.4.4
Node
3.4.5
IRI
3.4.5.1
Attributes
3.4.6
Blank Node
3.4.6.1
Attributes
3.4.7
Literal
3.4.7.1
Attributes
4.
Algorithms
4.1
Algorithm Terms
4.2
Context Processing
4.3
IRI
Expansion
4.4
IRI
Compaction
4.4.1
IRI
Compaction Algorithm
4.4.2
Term Rank Algorithm
4.5
Value Expansion
4.6
Value Compaction
4.7
Expansion
4.7.1
Expansion Algorithm
4.8
Compaction
4.8.1
Compaction Algorithm
4.9
RDF Conversion
4.9.1
Overview
4.9.2
Parsing Examples
4.9.3
Convert to RDF Algorithm
4.9.4
List Conversion
4.9.5
Convert from RDF Algorithm
5.
Data Round Tripping
A.
Initial Context
B.
Acknowledgements
C.
References
C.1
Normative references
C.2
Informative references
1.
Preface
This document is a detailed specification for an Application Programming
Interface for the JSON-LD Syntax. The document is primarily intended for
the following audiences:
Web authors and developers that want a very detailed view of how
a JSON-LD processor and the API operates.
Software developers that want to implement processors and APIs for
JSON-LD.
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
].
1.1
Contributing
There are a number of ways that one may participate in the development of
this specification:
If you want to make sure that your feedback is formally addressed by
the RDF Working Group, you should send it to public-rdf-comments:
[email protected]
Ad-hoc technical discussion primarily occurs on the public community mailing list:
[email protected]
Public JSON-LD Community Group teleconferences
are held on Tuesdays at 1500UTC every week.
RDF Working Group teleconferences are held on Wednesdays at 1500UTC
every week. Participation is limited to RDF Working Group members.
Specification bugs and issues should be reported in the
issue tracker
if you do not want to send an e-mail to the public-rdf-comments mailing
list.
Source code
for the specification can be found on Github.
The
#json-ld
IRC channel is available for real-time discussion on irc.freenode.net.
2.
Introduction
The JSON-LD Syntax specification [
JSON-LD
] outlines a language that may be
used to express Linked Data in JSON. Often, it is useful to be able to
transform JSON-LD documents so that they may be easily processed in
a programming environment like JavaScript, Python or Ruby.
There are three major types of transformation that are discussed in this
document; compaction, expansion, and RDF conversion.
2.1
Expansion
Software algorithms are easiest to write when the data that they are processing
have a regular form. Since information can be represented by JSON-LD in a
variety of different ways, transforming all of these methods into a uniform
structure allows the developer to simplify their processing code. For example,
note that the following input uses only
term
s and is fairly
compact:
Example 1
var input1 = {
"@context": "http://json-ld.org/contexts/person.jsonld"
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
The next input example uses one
IRI
to express a property, but
leaves the rest of the information untouched.
Example 2
var input2 = {
"@context": "http://json-ld.org/contexts/person.jsonld"
": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
While both inputs are valid JSON-LD, writing a program to handle every
permutation of possible inputs can be difficult, especially when the incoming
context could change as well. To ensure that the data can be given a more
uniform structure, JSON-LD introduces the notion of expansion.
Expansion
performs two important operations. The first is to
expand all values that are
IRI
s to their fully expanded form.
The second is to express all values in
expanded form
. To
transform both inputs above to the same representation, the developer could
do the following:
Example 3
function expansionCallback(output) {
console.log(output);

// the second parameter is 'null' because the developer does not wish to
// inject another context value
jsonld.expand(input1, null, expansionCallback);
jsonld.expand(input2, null, expansionCallback);
The output for both calls above will be:
Example 4
[{
"http://xmlns.com/foaf/0.1/name": [{
"@value": "Manu Sporny"
}],
"http://xmlns.com/foaf/0.1/homepage": [{
"@id": "http://manu.sporny.org/"
}]
}]
Note that in the example above; all
context
definitions have
been removed, all
term
and prefixes have been expanded to full
IRIs, and all
literal
s are expressed in
expanded form
While the output is more difficult for a human to read, it is easier for a
software program to process because of its very regular structure.
2.2
Compaction
While expansion expands a given input as much as possible, compaction performs
the opposite operation - expressing a given input as succinctly as possible.
While expansion is meant to produce something that is easy to process by
software programs, compaction is meant to produce something that is easy to
ready by software developers. Compaction uses a developer-supplied
context
to compresses all
IRI
s to
term
or
prefix
es, and compacts all
literal
s expressed
in
expanded form
as much as possible.
The following example expresses input that has already been fully expanded:
Example 5
var expandedInput = [{
"http://xmlns.com/foaf/0.1/name": [{
"@value": "Manu Sporny"
}],
"http://xmlns.com/foaf/0.1/homepage": [{
"@id": "http://manu.sporny.org/"
}]
}]
A developer that wants to transform the data above into a more human-readable
form, could do the following using the JSON-LD API:
Example 6
function compactionCallback(output) {
console.log(output);

jsonld.compact(expandedInput, "http://json-ld.org/contexts/person.jsonld", compactionCallback);
The following would be the result of the call above:
Example 7
"@context": "http://json-ld.org/contexts/person.jsonld"
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
Note that all of the
term
s have been compressed and
the
context
has been injected into the output. While compacted
output is most useful to humans, it can also be carefully used to generate
structures that are easy to use for developers to program against as well.
2.3
Conversion to and from RDF
JSON-LD can be used to losslessly express the RDF data model as described in
the RDF Concepts document [
RDF-CONCEPTS
]. This ensures that
data can be round-tripped from any RDF syntax, like N-Triples or TURTLE,
without any loss in the fidelity of the data. Assume the following RDF input
in N-Triples format:
Example 8
var data = "
\"Manu Sporny\" .\n
.";
A developer can use the JSON-LD API to transform the markup above into a
JSON-LD document:
Example 9
function conversionCallback(result)
console.log("JSON-LD Document: ", result);
};

jsonld.fromRDF(data, conversionCallback, {"format": "ntriples"});
The following expanded output would be the result of the call above:
Example 10
[{
"@id": "http://manu.sporny.org/about/#manu",
"http://xmlns.com/foaf/0.1/name": [{
"@value": "Manu Sporny"
}],
"http://xmlns.com/foaf/0.1/homepage": [{
"@id": "http://manu.sporny.org/"
}]
}]
Note that the output above, could easily be compacted to produce the following
using the technique outlined in the previous section:
Example 11
"@context": "http://json-ld.org/contexts/person.jsonld",
"@id": "http://manu.sporny.org/about/#manu",
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
Transforming the object above back to RDF is as simple as calling the
toRDF()
method:
Example 12
var jsonldDocument = ...; // assign the JSON-LD document here

function rdfCallback(quads)
console.log("RDF Data: ", quads);
};

jsonld.toRDF(jsonldDocument, rdfCallback);
2.4
Framing and Normalization
Issue 2
There are currently two other API methods that are in active development and
were not ready for publication at the time this document was published.
Framing allows a developer to force a different layout for the data and
effectively perform query-by-example on JSON-LD documents - this is most
useful when a JSON-LD-based REST API does not know the exact form of the data
it is getting in, but still wants to operate upon it if some bare essentials
are found in the data. JSON-LD normalization allows JSON-LD documents to be
deterministically serialized such that they can be digitally signed or be
used to find the differences between two
linked data graph
s.
It is expected that framing will be a part of the final API. It is expected
that normalization will be an optional feature that JSON-LD processors may
implement.
3.
The Application Programming Interface
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.
3.1
General Terminology
Issue 3
The intent of the Working Group and the Editors of this specification is to
eventually align terminology used in this document with the terminology used
in the RDF Concepts document to the extent to which it makes sense to do so.
In general, if there is an analogue to terminology used in this document in
the RDF Concepts document, the preference is to use the terminology in the
RDF Concepts document.
The following is an explanation of the general terminology used in this
document:
JSON object
An object structure is represented as a pair of curly brackets surrounding zero or
more name-value pairs. A name is a
string
. A single colon comes after
each name, separating the name from the value. A single comma separates a value
from a following name. The names within an object
should
be unique.
array
An array is represented as square brackets surrounding zero or more
values that are separated by commas.
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.
number
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.
true
and
false
Values that are used to express one of two possible boolean states.
null
Unless otherwise specified, a JSON-LD processor
must
act as if a
key-value pair in the body of a JSON-LD document was never declared when
the value equals
null
. If
@value
@list
, or
@set
is set to
null
in
expanded form, then the entire JSON object is ignored. If
@context
is set to
null
, the
active context
is reset and when used
within a
context
, it removes any definition associated
with the key, unless otherwise specified.
subject definition
JSON object
used to represent a
subject
and
one or more properties of that subject. A
JSON object
is a
subject definition if it does not contain they keys
@value
@list
or
@set
and it has one or more keys
other than
@id
subject reference
JSON object
used to reference a subject having only the
@id
key.
Linked Data
A set of documents, each containing a representation of a
linked data graph
linked data graph
or
dataset
An unordered labeled directed graph, where
node
s are
subject
s or
object
s, and edges are
properties.
node
A piece of information that is represented in a
linked data graph
named graph
linked data graph
that has one or more
IRI
that are used to refer to it.
graph name
An
IRI
that is a reference to a
named graph
default graph
When executing an algorithm, the graph where data should be placed
if a
named graph
is not specified.
subject
Any node in a
linked data graph
with at least one
outgoing edge.
IRI
An Internationalized Resource Identifier as described
in [
RFC3987
]).
object
A node in a
linked data graph
with at least one
incoming edge.
property
An edge of the
linked data graph
literal
An
object
with a label that is not an
IRI
quad
A piece of information that contains four items; a
subject
, a
property
, a
object
and a
graph name
context
JSON object
that contains rules for interpreting a
JSON-LD document.
keyword
A JSON key that is specific to JSON-LD, specified in the JSON-LD
Syntax specification [
JSON-LD
] in the section titled
Syntax Tokens and Keywords
3.2
JsonLdProcessor
The JSON-LD Processor interface is the high-level programming structure that
developers use to access the JSON-LD transformation methods.
NoInterfaceObject
interface
JsonLdProcessor
void
expand
object or object[] or URL
input
object or URL
context
JsonLdCallback
callback
optional
JsonLdOptions
options
);
void
compact
object or object[] or URL
input
object or URL
context
JsonLdCallback
callback
optional
JsonLdOptions
options
);
void
fromRDF
Quad
[]
input
JsonLdCallback
callback
optional
JsonLdOptions
options
);
void
toRDF
object or object[] or URL
input
QuadCallback
callback
optional
JsonLdOptions
options
);
};
3.2.1
Methods
compact
Compacts
the given
input
using the
context
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 appropriate exception
must
be
thrown.
Parameter
Type
Nullable
Optional
Description
input
object or object[] or URL
The JSON-LD object or array of JSON-LD objects to perform the compaction upon or an
IRI
referencing the JSON-LD document to compact.
context
object or URL
The context to use when compacting the
input
; either in the
form of an
JSON object
or as
IRI
callback
JsonLdCallback
A callback that is called when processing is complete on
the given
input
options
JsonLdOptions
A set of options that
may
affect the expansion algorithm such as, e.g., the
input document's base
IRI
. This also includes
optimize
which if set will cause processor-specific optimization.
Return type:
void
expand
Expands
the given
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 or object[] or URL
The JSON-LD object or array of JSON-LD objects to perform the expansion upon or an
IRI
referencing the JSON-LD document to expand.
context
object or URL
An optional external context to use additionally to the context embedded in
input
when expanding the
input
callback
JsonLdCallback
A callback that is called when processing is complete on
the given
input
options
JsonLdOptions
A set of options that
may
affect the expansion algorithm such as, e.g., the
input document's base
IRI
Return type:
void
fromRDF
Creates a JSON-LD document given an set of
Quads
Parameter
Type
Nullable
Optional
Description
input
Quad
[]
dataset
represented as an array of
Quads
callback
JsonLdCallback
A callback that is called when processing is complete on
the given
input
options
JsonLdOptions
A set of options that will affect the algorithm. This includes
notType
which if set to
true
causes the resulting document to use
rdf:type
as a property, instead of
@type
Return type:
void
toRDF
Processes the
input
according to the
Convert to RDF Algorithm
, calling
the provided
callback
for each
Quad
generated.
Parameter
Type
Nullable
Optional
Description
input
object or object[] or URL
The JSON-LD object or array of JSON-LD objects to convert to RDF or a
URL
referencing the JSON-LD document to convert to RDF.
callback
QuadCallback
A callback that is called when a
Quad
is created from processing
the given
input
options
JsonLdOptions
A set of options that
may
affect the conversion to RDF such as, e.g.,
the input document's base
IRI
Return type:
void
3.3
Callbacks
3.3.1
JsonLdCallback
The
JsonLdCallback
is used to return a processed JSON-LD representation
as the result of processing an API method.
NoInterfaceObject Callback
interface
JsonLdCallback
void
jsonLd
object or object
[]
jsonld
);
};
3.3.1.1
Methods
jsonLd
This callback is invoked when processing is complete.
Parameter
Type
Nullable
Optional
Description
jsonld
object or object
[]
The processed JSON-LD document.
Return type:
void
3.3.2
QuadCallback
The
QuadCallback
is called whenever the processor generates a
quad during the
quad()
call.
NoInterfaceObject Callback
interface
QuadCallback
void
quad
Quad
quad
);
};
3.3.2.1
Methods
quad
This callback is invoked whenever a quad is generated by the processor.
Parameter
Type
Nullable
Optional
Description
quad
Quad
The quad.
Return type:
void
3.4
Data Structures
This section describes datatype definitions used within the JSON-LD API.
3.4.1
URL
The
URL
datatype is a string representation of an
IRI
typedef
DOMString
URL
This datatype indicates that the
IRI
is interpreted as a Universal Resource
Locator
identifying a document, which when parsed as JSON yields either a
JSON object
or
array
3.4.2
JsonLdOptions
The
JsonLdOptions
type is used to convert a set of options to an interface method.
typedef
object
JsonLdOptions
URL
base
The Base
IRI
to use when expanding the document. This overrides the value of
input
if it is a
URL
or if it is a
object
or
object[]
boolean optimize
If set to
true
, the JSON-LD processor is allowed to
optimize the output of the
Compaction Algorithm
to produce even compacter representations. The algorithm for compaction
optimization is beyond the scope of this specification and thus
not defined. Consequently, different implementations
may
implement
different optimization algorithms.
boolean noType
If set to
true
, the JSON-LD processor will not use the
@type
property when generating the output, and will use the
expanded
rdf:type
IRI
as the property instead of
@type
The following data structures are used for representing data about
RDF quads. They are used for normalization,
fromRDF
and from
toRDF
interfaces.
3.4.3
Quad
The
Quad
interface represents an RDF Quad.
See [
RDF-CONCEPTS
] definition for
RDF triple
which most closely aligns to
Quad
NoInterfaceObject
interface
Quad
readonly attribute
Node
subject
readonly attribute
Node
predicate
readonly attribute
Node
object
readonly attribute
Node
graphName
};
3.4.3.1
Attributes
graphName
of type
Node
, readonly, nullable
If present, the name associated with the
Quad
identifying
it as a member of a
named graph
. If it is missing, the quad
is a member of the
default graph
Issue 4
This element is at risk, and may be removed.
object
of type
Node
, readonly
The
object
associated with the
Quad
predicate
of type
Node
, readonly
The predicate associated with the
Quad
Within JSON-LD, an
RDF predicate
is refered to as a
property
subject
of type
Node
, readonly
The
subject
associated with the
Quad
3.4.4
Node
Node
is the base class of
IRI
BlankNode
, and
Literal
. It is the IDL
representation of a
linked data graph
node
NoInterfaceObject
interface
Node
};
3.4.5
IRI
node
that is an
IRI
NoInterfaceObject
interface
IRI
Node
readonly attribute
DOMString
value
};
3.4.5.1
Attributes
value
of type
DOMString
, readonly
The
IRI
identifier of the
node
as a [
UNICODE
] string.
3.4.6
Blank Node
node
in the
linked data graph
that
does not contain a de-reference-able 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
_:
and an implementation dependent,
auto-generated suffix that is unique to all information associated with the
particular blank node.
NoInterfaceObject
interface
BlankNode
Node
readonly attribute
DOMString
identifier
};
3.4.6.1
Attributes
identifier
of type
DOMString
, readonly
The temporary identifier of the
blank node
The
identifier
must not
be relied upon in any way between two
separate processing runs of the same document or with a different document.
Note
Developers and authors must not assume that the
value of a
blank node
will remain the same between two
processing runs.
BlankNode
values are only valid for the
most recent processing run on the document.
BlankNode
values will often be generated differently by different processors.
Note
Implementers
must
ensure that
BlankNode
values are unique
within the current environment, two
BlankNodes
are considered equal if, and only
if, their values are strictly equal.
3.4.7
Literal
Literals represent values such as numbers, dates and strings in
RDF data. A
Literal
is comprised of three attributes:
a lexical form of the
value
an optional
language
tag
datatype
specified by an
IRI
Literals representing plain text in a natural language may have a
language
tag specified by a string token, as specified in
BCP47
], normalized to lowercase
(e.g.,
'en'
'fr'
'en-gb'
).
They also have a datatype attribute such as
xsd:string
If unspecified, the
datatype
defaults to
xsd:string
Literals representing values with a specific datatype, such as
the integer 72, may have a
datatype
attribute specified in the form
of a
IRI
(e.g.,
xsd:integer
).
See[
RDF-CONCEPTS
] definition for
literal
NoInterfaceObject
interface
Literal
Node
readonly attribute
DOMString
value
readonly attribute
DOMString
language
readonly attribute
IRI
datatype
};
3.4.7.1
Attributes
datatype
of type
IRI
, readonly, nullable
An optional datatype identified by a
IRI
language
of type
DOMString
, readonly, nullable
An optional language tag as defined in [
BCP47
], normalized to lowercase.
value
of type
DOMString
, readonly
The lexical form of the Literal's value.
4.
Algorithms
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.
4.1
Algorithm Terms
initial context
a context that is specified to the algorithm before processing begins. The contents of the
initial context is defined in
Appendix A
active subject
the currently active subject that the processor should use when
processing.
active property
the currently active property 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 object
the currently active object that the processor should use when
processing.
active context
a context that is used to resolve
term
s while the processing
algorithm is running. The
active context
is the context
contained within the
processor state
compact
IRI
a compact
IRI
is has the form of
prefix
and
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
local context
a context that is specified within a
JSON object
specified via the
@context
keyword
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
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.
term
term
is a short word defined in a context that
may
be expanded to an
IRI
prefix
prefix
is a
term
that expands to a vocabulary base
IRI
. It
is typically used along with a
suffix
to form a
compact
IRI
to create an
IRI
within a vocabulary.
language-tagged literal
language-tagged literal
is a
literal
without a datatype, including
a language.
See
languaged-tagged literal
in [
RDF-CONCEPTS
].
typed literal
typed literal
is a
literal
with an associated
IRI
which indicates the literal's datatype.
See
languaged-tagged literal
in [
RDF-CONCEPTS
].
4.2
Context Processing
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 properties and values of a
JSON object
(or elements
of an array) using a
term mapping
. It is also used to maintain
coercion mapping
s from terms to datatypes,
language mapping
s from terms to language codes,
and
list mapping
s and
set mapping
s for terms. Processors
must
use the
lexical form of the property when creating a mapping, as lookup is performed on lexical forms, not
expanded
IRI
representations.
local context
is identified within a
JSON object
having a
@context
property with a
string
array
or a
JSON object
value.
When processing a
local context
, special processing rules apply:
Create a new, empty
local context
Let
context
be the value of
@context
If
context
equals
null
, reset the
active context
to the
initial context
If
context
is an
array
, process each element as
context
in order
by starting at
Step 2.1
If
context
is a
string
, it
must
have a lexical form of
absolute
IRI
Dereference
context
If the resulting document is a JSON document, extract the top-level
@context
element using the JSON Pointer "/@context" as described in [
JSON-POINTER
]. Set
context
to the extracted content and process it by starting at
Step 2.1
If
context
is a
JSON object
, perform the following steps:
If
context
has a
@language
property, it
must
have a value of a
simple
string
or
null
. Add the language to the
local context
Otherwise, for each property in
context
perform the following steps:
If the property's value is a simple
string
, 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 property into the
local context
term mapping
, unless the property is a JSON-LD
keyword
, in which
case throw an exception.
Otherwise, if the property's value is
null
remove mapping, coercion,
container and language information associated with property from the
local context
Otherwise, the
property
's
value
must
be a
JSON object
If the
property
is a JSON-LD
keyword
and the value has
@id
@language
or
@type
properties, throw an exception.
Issue 5
Undecided if
@type
or
@graph
can take a
@container
with
@set
If the
property
has the form of
term
, its
value
must
have an
@id
property with a string value which
must
have the form of a
term
compact
IRI
, or
absolute
IRI
. Determine the
IRI
mapping
by performing
IRI
Expansion
on the associated value.
If the result of the
IRI
mapping is an
absolute
IRI
, merge the
property
into the
local context
term mapping
If the
property
has the form of of a
compact
IRI
or
absolute
IRI
the
value
may
have a
@id
property with a string value which
must
have the
form of a
term
compact
IRI
, or absolute
IRI
Determine the
IRI
mapping by performing
IRI
Expansion
on the associated
value. If the result of the
IRI
mapping is an
absolute
IRI
, merge the
property
into the
local context
term mapping
If the
value
has a
@type
property, its value
must
have the form of a
term
compact
IRI
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
using the lexical value of the
property
If the
value
has a
@container
property, its value
must
be
@list
or
@set
. Merge the
list mapping
or
set mapping
into the
local context
using the lexical value of the
property
If the
value
has a
@language
property but no
@type
property, the value of the
@language
property
must
be a
string
or
null
Merge the
language mapping
into the
local context
using the lexical value of the
property
Merge the
local context
into the
active context
Repeat
Step 2.4.2
until no entries are added to the
local
context
Note
It can be difficult to distinguish between a
compact
IRI
and an
absolute
IRI
as a
compact
IRI
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 2.3.2
until no changes are made, mappings to IRIs created
using an undefined term prefix will eventually resolve to
absolute
IRI
s.
Issue 6
Issue 43
concerns performing
IRI
expansion in the key position of a context definition.
4.3
IRI
Expansion
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
IRI
s may be represented as an
absolute
IRI
, a
term
or a
compact
IRI
An
absolute
IRI
is defined in [
RFC3987
] containing a
scheme
along with
path
and optional
query
and fragment segments. A
relative
IRI
is an
IRI
that is relative some other
absolute
IRI
; in the case of JSON-LD this is the base location
of the document.
The algorithm for generating an
IRI
is:
If the
active context
contains a
term
mapping for the value using
a case-sensitive comparison, use the mapped value as an
IRI
Otherwise, split the value into a
prefix
and
suffix
from the first occurrence of ':'.
If the prefix is a '_' (underscore), the value represents a named
blank node
If the
active context
contains a
term
mapping for
prefix
using
a case-sensitive comparison, and
suffix
does not does not begin with '//'
(i.e., it does not match a
hier-part
including
authority
(as defined in [
RFC3986
]), generate an
IRI
by prepending the mapped prefix to the (possibly empty) suffix using textual concatenation. Note that an empty
suffix and no suffix (meaning the value contains no ':' string at all) are treated equivalently.
Otherwise, use the value directly as an
IRI
Note
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.
4.4
IRI
Compaction
Some keys and values are expressed using
IRI
s. This section defines an
algorithm for transforming an
IRI
iri
) to a
term
or
compact
IRI
using the
term
s specified in the
active context
using an optional
value
4.4.1
IRI
Compaction Algorithm
The algorithm for generating a
compact
IRI
is:
Create an empty list of terms
that will be populated with
term
s that are ranked according to how closely they match
value
. Initialize
highest rank
to
and set a flag
list container
to
false
For each
term
in the
active context
If the
term
's
IRI
is not a complete match against
iri
, continue to the next
term
If
value
is a
JSON object
containing only the property
@list
If
term
has a
@container
set to
@set
, continue
to the next
term
If
list container
is
true
and
term
does not have a
container
set to
@list
, continue to the next
term
Otherwise, if
term
has a
container
set to
@list
continue to the next
term
Set
rank
to the
term rank
of
value
by passing
passing
term
value
, and
active context
to
the
Term Rank Algorithm
If
rank
is greater than
If
term
has a
container
set to
@set
, then add
to
rank
If
value
is a
JSON object
containing only the property
@list
and
list container
is
false
and
term
has a
container
set to
@list
, then set
list container
to
true
, clear
, set
highest rank
to
rank
, and add
term
to
Otherwise, if
rank
is greater than or equal to
highest rank
If
rank
is greater than
highest rank
, clear
and set
highest rank
to
rank
Add
term
to
If
is empty, add a
compact
IRI
representation of
iri
for each
term
in the
active context
which
maps to an
IRI
which is a prefix for
iri
where
the resulting
compact
IRI
is not a
term
in the
active context
. The resulting
compact
IRI
is the
term
associated with the partially
matched
IRI
in the
active context
concatenated with a
colon (:) character and the unmatched part of
iri
If
is empty, return
iri
Otherwise, return the shortest and lexicographically least value in
4.4.2
Term Rank Algorithm
When selecting among multiple possible terms for a given property, it may be that multiple
are defined with the same
IRI
, but differ in
@type
@container
or
@language
. The purpose of this algorithm is to take a
term
and a value and give it a
term rank
. The selection can then be based, partly, on
the term having the highest
term rank
Given a
term
term
value
, and
active context
determine the
term rank
using the following steps:
If
value
is
null
term rank
is
Otherwise, if
value
is a
JSON object
containing only the property
@list
If the
@list
property is an empty array, if
term
has
@container
set to
@list
term rank
is
, otherwise
Otherwise, return the sum of the
term rank
s for every entry in the list.
Otherwise,
value
must
be a
subject definition
subject reference
or a
JSON object
having a
@value
If
value
has a
@value
property:
If
value
has a
@type
property matching a
@type
coercion for
term
term rank
is
, otherwise if
term
has no
@type
coercion and no
@language
term rank
is
, otherwise
Otherwise, if
@value
is not a
string
, if
term
has
no
@type
or
@language
it is
, otherwise
Otherwise, if
value
has no
@language
property, if
term
has
@language
null
, or
term
has no
@type
or
@language
and the
active context
has no
@language
term rank
is
, otherwise
Otherwise, if
value
has a
@language
property matching a
@language
definition for
term
(or
term
has no
@type
or
@language
definition and
@language
in the
active context
matches the
value
@language
),
term rank
is
, otherwise if
term
has no
@type
coercion and no
@language
term rank
is
, otherwise
Otherwise, if
term
has
@type
coerced to
@id
term rank
is
, otherwise
if
term
has no
@type
coercion and no
@language
term rank
is
, otherwise
Return
term rank
4.5
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.
The algorithm for expanding a
value
takes an
active property
and
active context
. It is implemented as follows:
If
value
is
null
, the
value
is already expanded.
If
active property
is
@graph
or the target of an
@id
coercion,
expand the value into an object with a key-value pair where the key is
@id
and the value is
the expanded
IRI
according to the
IRI
Expansion
rules.
Otherwise, if
active property
is not a
keyword
, then expand
value
into an
object:
Set the first key-value pair to
@value
and the unexpanded
value
If the
active property
is the target of typed literal coercion, set the second key-value pair
to
@type
and the associated coercion datatype expanded according to the
IRI
Expansion
rules.
Otherwise, if the
active property
is the target of language tagging, set the second key-value
pair to
@language
and value of the language tagging from the
active context
Otherwise,
value
is already expanded.
4.6
Value Compaction
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:
If
value
only has one property and the
active context
has no default language,
then the compacted value is the value of
@value
Otherwise, if
active property
is
@graph
, the compacted value is the
value associated with the
@id
key, processed according to
the
IRI
Compaction
steps.
Otherwise, if the
active context
contains a coercion target for the
key that matches the expression of the value, compact the value using the
following steps:
If the coercion target is an
@id
, the compacted
value is the value associated with the
@id
key,
processed according to the
IRI
Compaction
steps.
If the coercion target is a
typed literal
, the compacted
value is the value associated with the
@value
key.
Otherwise, if
value
contains an
@id
key, the compacted value is
value
with
the value of
@id
processed according to the
IRI
Compaction
steps.
Otherwise, if the
active context
contains a
@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.
Otherwise, if the value contains a
@type
key, the compacted value
is
value
with the
@type
value processed according to the
IRI
Compaction
steps.
Otherwise, the value is not modified.
4.7
Expansion
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 other JSON-LD API methods.
For example, assume the following JSON-LD input document:
Example 13
"@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:
Example 14
"http://xmlns.com/foaf/0.1/name": "Manu Sporny",
"http://xmlns.com/foaf/0.1/homepage": {
"@id": "http://manu.sporny.org/"
4.7.1
Expansion Algorithm
The algorithm takes three input variables: an
active context
, an
active property
, and an
element
to be expanded. To
begin, the
active context
is set to the result of performing,
Context Processing
on the passed
context
, or to the
initial context
if
context
is
null
active property
is set to
null
, and
element
is set to the
JSON-LD
input
If
element
is an
array
, process each entry in
element
recursively
using this algorithm, passing copies of the
active context
and
active property
If has a
@container
set to
@list
and any entry in
element
is an
array
, or is a
JSON object
containing a
@list
property,
throw an exception, as lists of lists are not allowed.
If the expanded entry is null, drop it. If it's an array, merge its entries with
element
's entries.
Otherwise, if
element
is an object
If
element
has a
@context
property, update the
active context
according to
the steps outlined in
Context Processing
and remove the
@context
property.
Then, proceed and process each
property
and
value
in
element
as follows:
Remove
property
from
element
, expand
property
according to the steps outlined in
IRI
Expansion
Set the
active property
to the original un-expanded
property
if
property
is not a
keyword
If
property
does not expand to a keyword or an
absolute
IRI
(i.e., it doesn't contain a colon),
continue with the next property from
element
If
value
is
null
and
property
is not
@value
, continue with the next
property from
element
If the
property
is
@id
the
value
must
be a
string
Expand the
value
according to
IRI
Expansion
Otherwise, if the
property
is
@type
If
value
is a
string
, expand according to
IRI
Expansion
Otherwise, if
value
is a
subject reference
, the expanded value
is the result of performing
IRI
Expansion
on the value of
@id
Otherwise, if
value
is a
JSON Object
, it must be empty (used for
Framing
).
Otherwise, if
value
is an
array
, all elements must be either a
string
or
subject reference
. Expand
value
for each
of its entries using the previous three steps.
Otherwise, if the
property
is
@value
or
@language
the
value
must not
be a
JSON object
or an
array
Otherwise, if the
property
is
@list
or
@set
expand
value
recursively using this algorithm, passing copies of the
active context
and
active property
. If the expanded
value
is not an
array
, convert it to an
array
If
property
is
@list
and any entry in
value
is a
JSON object
containing an
@list
property, throw an exception, as
lists of lists are not supported.
Otherwise, expand
value
recursively using this algorithm, passing copies of the
active context
and
active property
If
property
is not a keyword
and
active property
has a
@container
@list
and the expanded
value
is not
null
convert
value
to an
object
with an
@list
property whose value is
set to
value
(unless
value
is already in that form).
Convert
value
to
array
form unless
value
is
null
or
property
is
@id
@type
@value
, or
@language
If
value
is not
null
, either merge
value
into an existing
property
property of
element
or create a new
property
property with
value
as value.
If the processed
element
has an
@value
property
element
must not
have more than one other property, which can either be
@language
or
@type
with a
string
value.
if the value of
@value
equals
null
replace
element
with the value of
@value
Otherwise, if
element
has an
@type
property and its value is not in the form of an
array
, convert it to an
array
If
element
has an
@set
or
@list
property, it
must
be the only property.
Set
element
to the value of
@set
; leave
@list
untouched.
If
element
has just a
@language
property, set
element
to
null
Otherwise, expand
element
according to the
Value Expansion
rules,
passing copies of the
active context
and
active property
If, after the algorithm outlined above is run, the resulting
element
is an
JSON object
with just a
@graph
property,
element
is set to the value of
@graph
's value. Finally, if
element
is a
JSON object
it is wrapped into an
array
4.8
Compaction
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:
Example 15
"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:
Example 16
"@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:
Example 17
"@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
to
name
, it could have also mapped it to any arbitrary string
provided by the developer.
4.8.1
Compaction Algorithm
The algorithm takes three input variables: an
active context
, an
active property
and an
element
to be compacted. To begin, the
active context
is
set to the result of performing
Context Processing
on the passed
context
active property
is set to
null
, and
element
is set to the result of performing the
Expansion Algorithm
on the
JSON-LD input
. This removes any existing
context to allow the given
active context
to be cleanly applied.
If
element
is an
array
, process each entry in
element
recursively
using this algorithm, passing a copy of the
active context
and the
active property
If
element
has a single item, the compacted value is that item; otherwise the compacted value
is
element
Otherwise, if
element
is an object:
If
element
has an
@value
property or element is a
subject reference
return the result of performing
Value Compaction
on
element
using
active property
Otherwise, if the
active property
has a
@container
mapping to
@list
and
element
has a corresponding
@list
property, recursively compact that
property's value passing a copy of the
active context
and the
active property
ensuring
that the result is an array and removing
null
values. Return either the
result as an array, as an object with a key of
@list
(or appropriate alias from
active context
).
Otherwise, construct
output
as a new
JSON object
used for returning the result
of compacting
element
. For each
property
and
value
in
element:
If
property
is
@id
or
@type
Set
active property
to the result of performing
IRI
Compaction
on
property
If
value
is a
string
, the compacted
value
is the result of performing
IRI
Compaction
on
value
Otherwise,
value
must
be an
array
. Perform
IRI
Compaction
on every entry of
value
. If
value
contains just one entry,
value
is set to that entry.
Add
active property
and the expanded
value
to
output
Otherwise,
value
must
be an
array
If
value
is empty:
Set
active property
to the result of performing
IRI
Compaction
on
property
Create an entry in
output
for
active property
and
value
For each
item
in
value
Set
active property
to the result of performing
IRI
Compaction
for
property
and
item
using the
active context
Compact
item
by recursively performing this algorithm passing a copy of
the
active context
and the
active property
If an entry already exists in
output
for
active property
, convert it
to an
array
if necessary, and append the compacted
value
Otherwise, if the compacted
value
is not an
array
and
active property
has a
@container
mapping to
@set
create an entry in
output
for
active property
and
value
as an
array
Otherwise, create an entry in
output
for
active property
and
value
Otherwise, return
element
as the compacted
element
Issue 7
Perhaps this should also call
Value Compaction
on
native types and strings, which could consolidate potential transformation in one place.
If, after the algorithm outlined above is run, the resulting
element
is an
array
, put
element
into the
@graph
property of a new
JSON object
and then set
element
to that
JSON object
Finally, add a
@context
property to
element
and set it to the initially passed
context
4.9
RDF Conversion
A JSON-LD document
may
be converted between other RDF-compatible document
formats using the algorithms specified in this section.
The JSON-LD Processing Model describes processing rules for extracting RDF
from a JSON-LD document, and for transforming an array of
Quad
retrieved by processing
another serialization format into JSON-LD. Note that many uses of JSON-LD may not require
generation of RDF.
The processing algorithms described in this section are 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 quads during the output process and are not required to
implement the algorithm exactly as described.
4.9.1
Overview
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
node
in a
linked data graph
Nodes may be of three basic types.
The first is the
IRI
, which is used to refer to
node
s in other
linked data graph
s.
The second is the
blank node
, which are nodes for which an external name does not
exist, or is not known. The third is a
Literal
, which express
values such as strings, dates and other information having a lexical
form, possibly including an explicit language or datatype.
Data described with JSON-LD may be considered to be a graph made
up of
subject
and
object
nodes
related via a
property
node
. Specific implementations may also choose to operate
on the document as a normal JSON description of objects having
attributes. Both approaches are valid ways to interact with JSON-LD
documents.
4.9.2
Parsing Examples
This section is non-normative.
The following examples show simple transformations of JSON-LD documents to Turtle [
TURTLE-TR
].
The first example uses a simple document containing a simple FOAF profile:
Example 18
"@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
"@id": "http://greggkellogg.net/foaf#me",
"@type": "foaf:Person",
"foaf:name": "Gregg Kellogg",
"foaf:knows": {
"@type": "foaf:Person",
"foaf:name": "Manu Sporny"
This translates fairly directly to a similar Turtle document:
Example 19
@prefix foaf: .

a foaf:Person;
foaf:name "Gregg Kellogg";
foaf:knows [ a foaf:Person; foaf:name "Manu Sporny"].
The actual parsing steps first require that the JSON-LD document be expanded,
to eliminate the
@context
Example 20
[{
"@id": "http://greggkellogg.net/foaf#me",
"@type": ["http://xmlns.com/foaf/0.1/Person"],
"http://xmlns.com/foaf/0.1/name": [{"@value": "Gregg Kellogg"}],
"http://xmlns.com/foaf/0.1/knows": [{
"@type": ["http://xmlns.com/foaf/0.1/Person"],
"http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}]
}]
}]
The process of translating this to RDF then operates over each
subject definition
to find a subject,
each
property
to find an RDF
predicate
and each value of that property to find an
object
In this case, each property has just a single object:
foaf:name
identifies a
literal
, and
foaf:knows
identifies a second
subject definition
similar to Turtle's
blankNodePropertyList
After expansion, JSON-LD
numbers
booleans
, typed- and language-tagged-
literals
, and
IRIs
become explicit, and can be directly transformed into their RDF representations.
Example 21
[{
"@id": "http://greggkellogg.net/foaf#me",
"@type": ["http://xmlns.com/foaf/0.1/Person"],
"http://xmlns.com/foaf/0.1/name": [{"@value": "Gregg Kellogg"}],
"http://xmlns.com/foaf/0.1/currentProject": [{"@id": "http://json-ld.org/"}],
"http://xmlns.com/foaf/0.1/birthday": [{
"@value": "1957-02-27",
"@type": "http://www.w3.org/2001/XMLSchema#date"
}],
"http://xmlns.com/foaf/0.1/knows": [{
"@type": ["http://xmlns.com/foaf/0.1/Person"],
"http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}]
}]
}]
Translates to:
Example 22
@prefix foaf: .
@prefix xsd: .

a foaf:Person;
foaf:name "Gregg Kellogg";
foaf:currentProject ;
foaf:birthday "1957-02-27"^^xsd:date;
foaf:knows [ a foaf:Person; foaf:name "Manu Sporny"].
4.9.3
Convert to RDF Algorithm
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 set of RDF
Quads
that the following
algorithm generates:
The algorithm takes five input variables: a
element
to be converted, an
active subject
active property
and
graph name
To begin, the
active subject
active property
and
graph name
are set to
null
, and
element
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.
If
element
is a
JSON object
, perform the following steps:
Set
active object
to
null
If
element
has a
@value
property:
If the value of
@value
is a
number
, set the
active object
to a
typed literal
using a string representation
of the value as defined in the section
Data Round Tripping
Set datatype to the value of the
@type
property if it exists, otherwise
either
xsd:integer
or
xsd:double
, depending
on if the value contains a fractional and/or an exponential component.
Otherwise, if the value of
@value
is
true
or
false
set the
active object
to a
typed literal
created from the
string representation of the value. Set datatype to the value of the
@type
property if it exists, otherwise
xsd:boolean
Otherwise, if
element
contains a
@type
property, set the
active object
to a
typed literal
Otherwise, if
element
contains a
@language
property, set the
active object
to a
language-tagged literal
Otherwise, set the
active object
to a
typed literal
using
xsd:string
as the datatype.
If
element
has a
@list
property the value
must
be an
array
Process its value as a list as described in
List Conversion
using
the return value as the
active object
If
active object
is not
null
If neither
active subject
nor
active property
are
null
generate a
Quad
representing
active subject
active property
active object
, and
graph name
Return
active object
If
element
has a
@id
property,
the value
must
be a
string
, set the
active subject
to the previously
expanded value (either a
blank node
or an
IRI
).
Otherwise, if
element
does not have a
@id
property, set the
active
subject
to newly generated
blank node
Process each
property
and
value
in
element
, ordered by
property
, as follows:
If
property
is
@type
, set the
active property
to
rdf:type
Otherwise, if
property
is
@graph
process
value
algorithm recursively, using
active subject
as
graph name
and null values for
active subject
and
active property
and then
proceed to next property.
Otherwise, if
property
is a
keyword
, skip this step.
Otherwise, set
active property
to the
IRI
value of
property
Process
value
recursively using this algorithm, passing copies of
active subject
active property
and
graph name
Set
active object
to
active subject
Otherwise, if
element
is an
array
, process each value in the
array
as follows, process
element
recursively using this algorithm, using copies of
active subject
active property
, and
graph name
Otherwise, if
element
is a
string
, then the
active property
must be
rdf:type
so set the
active object
to an
IRI
If any of these steps created an
active object
and neither
active subject
nor
active property
are
null
, generate a
Quad
using
active subject
active property
active object
and
graph name
Return
active object
4.9.4
List Conversion
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 returns a value to be used as an
active object
in the calling location.
Note
This algorithm does not support lists containing lists.
If
array
is empty return
rdf:nil
Otherwise, generate a
Quad
using using the
active subject
active property
and a newly generated
blank node
identified as
first
blank node
For each element in
array
other than the last element:
Create a processor state using
first blank node
as the
active subject
, and
rdf:first
as the
active property
Process the value starting at
Step 1
Proceed using the previous
processor state
Unless this is the last element in
array
, generate a new
blank node
identified as
rest blank node
, otherwise use
rdf:nil
Generate a new
Quad
using
first blank node
rdf:rest
and
rest blank node
Set
first blank node
to
rest blank node
Return
first blank node
4.9.5
Convert from RDF Algorithm
In some cases, data exists natively in Triples or Quads form; for example, if the data was originally
represented in an RDF graph or triple/quad store. This algorithm is designed to simply translate
an array of
Quads
into a JSON-LD document.
When expanding
typed literal
values having a datatype of
xsd:string
the
@type
must not
be set to
xsd:string
and the resulting value
must
have only a
@value
property.
The conversion algorithm takes a single parameter
input
in the form of an
array of
Quad
representations.
Construct
defaultGraph
as a
JSON object
containing
subjects
and
listMap
, each an empty
JSON object
Construct
graphs
as a
JSON object
containing
defaultGraph
identified by
an empty
string
For each quad in
input
Set
graph
to the entry in
graphs
identified
by
name
, initializing it to a new entry using the mechanism
described in
Step 1
If
property
is
rdf:first
use the entry in
graph.listMap
indexed by
subject
initializing it to a new
JSON object
if nesessary. Represent
object
in expanded form, as described in
Value Expansion
. Add the
resulting
object representation
to the entry indexed by
first
, and skip to the next quad.
If
property
is
rdf:rest
If
object
is a
blank node
, use the entry in
graph.listMap
indexed by
subject
, initializing it
to a new
JSON object
if necessary. Add the
nominalValue
of
object
to the entry indexed by
rest
Skip to the next quad.
If
name
is not
null
, and
defaultGraph.subjects
does not contain an entry for
name
create a new entry for
name
from a new
JSON object
with key/value pair of
@id
and
a string representation of
name
Set
value
as the entry from
graph.subjects
for
subject
, initializing it to a new
JSON object
with key/value pair of
@id
and
a string representation of
subject
if necessary.
If
property
is
rdf:type
and the
notType
option is present and not
true
Append the string representation of
object
to the array value for the
key
@type
, creating an entry in
value
if necessary.
Otherwise, if
object
is
rdf:nil
Let
key
be the string representation of
property
Append an empty
@list
representation to the array value for
key
, creating an entry in
value
if necessary.
Otherwise,
Let
key
be the string representation of
property
and let
object representation
be
object
represented in expanded form as described in
Value Expansion
If
object
is a
blank node
use the entry in
graph.listMap
indexed by
object
initializing it to a new
JSON object
if nesessary.
Add an entry for
head
with
object representation
Append
object representation
to the array value for
key
, creating an entry in
value
if necessary.
For each
name
and
graph
in
graphs
For each
subject
and
entry
in
graph
where
entry
has both
head
and
first
keys:
Set
value
to the value of
head
in
entry
Remove the entry for
@id
in
value
Add an entry to
value
for
@list
initialized to a new array
containing the value of
first
from
entry
While
entry
has a key for
rest
Set
entry
to the value of
graph.listMap
for
entry.rest
Add the value for
entry.first
to the list array.
Create
array
as an empty
array
For each
subject
and
entry
in
defaultGraph.subjects
ordered by
subject
Add
entry
to
array
If
graphs
has an entry for
subject
, add a property
@graph
in
entry
containing the ordered entries
from
graphs[subject].subjects
Return
array
as the result.
5.
Data Round Tripping
When coercing numbers to
xsd:integer
or
xsd:double
as it, e.g., happens during
RDF Conversion
, implementers
must
ensure that the result is a canonical lexical form in the form of a
string
. A
canonical lexical form
is a set of literals
from among the valid set of literals for a datatype such that there is a one-to-one mapping
between the canonical lexical form and a value in the value space as defined in
XMLSCHEMA11-2
]]. In other words, every value
must
be converted to a deterministic string
representation.
The canonical lexical form of an
integer
, i.e., a number without fractions
or a number coerced to
xsd:integer
, is a finite-length sequence of decimal
digits (
0-9
) with an optional leading minus sign; leading zeroes are prohibited.
To convert the number in JavaScript, implementers can use the following snippet of code:
Example 23
(value).toFixed(0).toString()
The canonical lexical form of a
double
, i.e., a number with fractions
or a number coerced to
xsd:double
, consists of a mantissa followed by the
character "E", followed by an exponent. The mantissa
must
be a decimal number. The exponent
must
be an integer. Leading zeroes and a preceding plus sign (
) are prohibited
in the exponent. If the exponent is zero, it must be indicated by
E0
For the mantissa, the preceding optional plus sign is prohibited and the decimal point is
required. Leading and trailing zeroes 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
To convert the number in JavaScript, implementers can use the following snippet of code:
Example 24
(value).toExponential().replace(/e\+?/,'E')
xsd:double
's value space is defined by the IEEE double-precision 64-bit
floating point type [
IEEE-754-1985
].
Note
When data such as decimals need 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. Authors should instead use the expanded object form to
set the canonical lexical form directly.
Note
When JSON-native datatypes, like
number
s, are type coerced, lossless
data round-tripping can not be guaranted. Consider the following code example:
Example 25
var myObj1 = {
"@context": {
"number": {
"@id": "http://example.com/vocab#number",
"@type": "xsd:nonNegativeInteger"
},
"number" :
42
};

// Convert the JSON-LD document to RDF; this converts 42 to a string
var jsonldText = jsonld.toRDF(myObj1, myRdfTripleCollector);

// Convert the RDF triples back to a JavaScript object
var myObj2 = jsonld.fromRDF(myRdfTripleCollector.getTriples());
At this point,
myObj1
and
myObj2
will have different
values for the "number" property.
myObj1
will have the number
42
, while
myObj2
have an object consisting of
@value
set to the string
"42"
and
@type
set to the expanded value of
xsd:nonNegativeInteger
Note
Some JSON serializers, such as PHP's native implementation in some versions,
backslash-escape the forward slash character. For example, the value
would be serialized as
http:\/\/example.com\/
This is problematic as other JSON parsers might not understand those escaping characters.
There is no need to backslash-escape forward slashes in JSON-LD. To aid interoperability
between JSON-LD processors, a JSON-LD serializer
must not
backslash-escape forward slashes.
A.
Initial Context
Issue 8
It is
still being
discussed
whether JSON-LD has the notion of an initial context or not. If JSON-LD has an
initial context, it
must
be specified external to the JSON-LD Syntax specification at a
well-known location.
B.
Acknowledgements
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, Josh Mandel, Eric Prud'hommeaux,
David Wood, Guus Schreiber, Pat Hayes, Sandro Hawke, and Richard
Cyganiak for their input on the specification.
C.
References
C.1
Normative references
[BCP47]
A. Phillips; M. Davis.
Tags for Identifying Languages
September 2009. IETF Best Current Practice. URL:
[IEEE-754-1985]
IEEE.
IEEE Standard for Binary Floating-Point Arithmetic.
See
[JSON-LD]
The JSON-LD Syntax
Manu Sporny, Gregg Kellogg, Markus Lanthaler Editors. World Wide Web Consortium (work in progress). 22 May 2012. Editor's Draft. This edition of the JSON-LD Syntax specification is http://json-ld.org/spec/ED/json-ld-syntax/20120522/. The
latest edition of the JSON-LD Syntax
is available at http://json-ld.org/spec/latest/json-ld-syntax/
[JSON-POINTER]
JSON Pointer
P. Bryan, Ed. IETF Draft. URL:
[RDF-CONCEPTS]
RDF 1.1 Concepts and Abstract Syntax
Richard Cyganiak, David Wood, Editors. World Wide Web Consortium (work in progress). 30 May 2012. Editor's Draft. This edition of the JSON-LD Syntax specification is http://www.w3.org/TR/2011/WD-rdf11-concepts-20110830/. The
latest edition of the JSON-LD Syntax
is available at http://www.w3.org/TR/rdf11-concepts/
[RDF-SCHEMA]
Dan Brickley; Ramanathan V. Guha.
RDF Vocabulary Description Language 1.0: RDF Schema.
10 February 2004. W3C Recommendation. URL:
[RFC3986]
T. Berners-Lee; R. Fielding; L. Masinter.
Uniform Resource Identifier (URI): Generic Syntax.
January 2005. Internet RFC 3986. URL:
[RFC3987]
M. Dürst; M. Suignard.
Internationalized Resource Identifiers (IRIs).
January 2005. Internet RFC 3987. URL:
[RFC4627]
D. Crockford.
The application/json Media Type for JavaScript Object Notation (JSON)
July 2006. Internet RFC 4627. URL:
[WEBIDL]
Web IDL
Cameron McCormack, Editor. World Wide Web Consortium. 19 April 2012. Candidate Recommendataion. This edition of Web IDL is http://www.w3.org/TR/2012/CR-WebIDL-20120419/. The
latest edition of Web IDL
is available at http://dev.w3.org/2006/webapi/WebIDL/
[XMLSCHEMA11-2]
Henry S. Thompson; et al.
W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes.
5 April 2012. W3C Recommendation URL:
C.2
Informative references
[ECMA-262]
ECMAScript Language Specification.
December 1999. URL:
[TURTLE-TR]
Eric Prud'hommeaux, Gavin Carothers.
Turtle: Terse RDF Triple Language.
09 August 2011. W3C Working Draft. URL:
[UNICODE]
The Unicode Consortium.
The Unicode Standard.
2003. Defined by: The Unicode Standard, Version 4.0 (Boston, MA, Addison-Wesley, ISBN 0-321-18578-1), as updated from time to time by the publication of new versions URL: