Copyright © 2010-2018 W3C ® ( MIT , ERCIM , Keio , Beihang ). W3C liability , trademark and permissive document license rules apply.
JSON is a useful data serialization and messaging format. This specification defines JSON-LD, a JSON-based format to serialize Linked Data. The syntax is designed to easily integrate into deployed systems that already use JSON, and provides a smooth upgrade path from JSON to JSON-LD. It is primarily intended to be a way to use Linked Data in Web-based programming environments, to build interoperable Web services, and to store Linked Data in JSON-based storage engines.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.
This document has been developed by the JSON-LD Working Group .
This document was published by the JSON-LD Working Group as an Editor's Draft.
GitHub Issues are preferred for discussion of this specification. Alternatively, you can send comments to our mailing list. Please send them to public-json-ld-wg@w3.org ( archives ).
Publication as an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the W3C Patent Policy . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy .
This
document
is
governed
by
the
1
February
2018
W3C
Process
Document
.
This
document
is
one
of
three
JSON-LD
1.1
Recommendations
produced
by
the
JSON-LD
Working
Group
:
Set
of
Documents
This section is non-normative.
Linked Data [ LINKED-DATA ] is a way to create a network of standards-based machine interpretable data across different documents and Web sites. It allows an application to start at one piece of Linked Data, and follow embedded links to other pieces of Linked Data that are hosted on different sites across the Web.
JSON-LD is a lightweight syntax to serialize Linked Data in JSON [ RFC7159 ]. Its design allows existing JSON to be interpreted as Linked Data with minimal changes. JSON-LD is primarily intended to be a way to use Linked Data in Web-based programming environments, to build interoperable Web services, and to store Linked Data in JSON-based storage engines. Since JSON-LD is 100% compatible with JSON, the large number of JSON parsers and libraries available today can be reused. In addition to all the features JSON provides, JSON-LD introduces:
JSON-LD
is
designed
to
be
usable
directly
as
JSON,
with
no
knowledge
of
RDF
[
RDF11-CONCEPTS
].
It
is
also
designed
to
be
usable
as
RDF,
if
desired,
for
use
with
other
Linked
Data
technologies
like
SPARQL.
Developers
who
require
any
of
the
facilities
listed
above
or
need
to
serialize
an
RDF
Graph
or
RDF
Dataset
in
a
JSON-based
syntax
will
find
JSON-LD
of
interest.
People
intending
to
use
JSON-LD
with
RDF
tools
will
find
it
can
be
used
as
another
RDF
syntax,
like
Turtle
[
TURTLE
].
Complete
details
of
how
JSON-LD
relates
to
RDF
are
in
section
7.
10.
Relationship
to
RDF
.
The syntax is designed to not disturb already deployed systems running on JSON, but provide a smooth upgrade path from JSON to JSON-LD. Since the shape of such data varies wildly, JSON-LD features mechanisms to reshape documents into a deterministic structure which simplifies their processing.
This section is non-normative.
This document is a detailed specification for a serialization of Linked Data in JSON. The document is primarily intended for the following audiences:
A companion document, the JSON-LD 1.1 Processing Algorithms and API specification [ JSON-LD11-API ], specifies how to work with JSON-LD at a higher level by providing a standard library interface for common JSON-LD operations.
To understand the basics in this specification you must first be familiar with JSON , which is detailed in [ RFC7159 ].
This document almost exclusively uses the term IRI ( Internationalized Resource Indicator ) when discussing hyperlinks. Many Web developers are more familiar with the URL ( Uniform Resource Locator ) terminology. The document also uses, albeit rarely, the URI ( Uniform Resource Indicator ) terminology. While these terms are often used interchangeably among technical communities, they do have important distinctions from one another and the specification goes to great lengths to try and use the proper terminology at all times.
There are a number of ways that one may participate in the development of this specification:
This document uses the following terms as defined in JSON [ RFC7159 ]. Refer to the JSON Grammar section in [ RFC7159 ] for formal definitions.
@context
where
the
value,
or
the
@id
of
the
value,
is
null
explicitly
decouples
a
term's
association
with
an
IRI
.
A
key-value
pair
in
the
body
of
a
JSON-LD
document
whose
value
is
null
has
the
same
meaning
as
if
the
key-value
pair
was
not
defined.
If
@value
,
@list
,
or
@set
is
set
to
null
in
expanded
form,
then
the
entire
JSON
object
is
ignored.
Furthermore, the following terminology is used throughout this document:
_:
.
_:
.
@language
key
whose
value
MUST
be
a
string
representing
a
[
BCP47
]
language
code
or
null
.
@graph
member,
and
may
also
have
@id
,
and
@index
members.
A
simple
graph
object
is
a
graph
object
which
does
not
have
an
@id
member.
Note
that
node
objects
may
have
a
@graph
member,
but
are
not
considered
graph
objects
if
they
include
any
other
properties.
A
top-level
object
consisting
of
@graph
is
also
not
a
graph
object
.
@container
set
to
@id
,
whose
keys
are
interpreted
as
IRIs
representing
the
@id
of
the
associated
node
object
;
value
MUST
be
a
node
object
.
If
the
value
contains
a
property
expanding
to
@id
,
it's
value
MUST
be
equivalent
to
the
referencing
key.
@container
is
set
to
@graph
.
@container
set
to
@index
,
whose
values
MUST
be
any
of
the
following
types:
string
,
number
,
true
,
false
,
null
,
node
object
,
value
object
,
list
object
,
set
object
,
or
an
array
of
zero
or
more
of
the
above
possibilities.
@container
set
to
@language
,
whose
keys
MUST
be
strings
representing
[
BCP47
]
language
codes
and
the
values
MUST
be
any
of
the
following
types:
null
,
string
,
or
an
array
of
zero
or
more
of
the
above
possibilities.
@list
member.
@context
keyword
.
@value
,
@list
,
or
@set
keywords,
or
@graph
and
@context
.
@version
member
in
a
context
,
or
via
explicit
API
option,
other
processing
modes
can
be
accessed.
This
specification
defines
extensions
for
the
json-ld-1.1
processing
mode
.
@type
,
and
values
of
terms
defined
to
be
vocabulary
relative
are
resolved
relative
to
the
vocabulary
mapping
,
not
the
base
IRI
.
@set
member.
@container
set
to
@type
,
whose
keys
are
interpreted
as
IRIs
representing
the
@type
of
the
associated
node
object
;
value
MUST
be
a
node
object
,
or
array
of
node
objects.
If
the
value
contains
a
property
expanding
to
@type
,
it's
values
are
merged
with
the
map
value
when
expanding.
@value
member.
@vocab
key
whose
value
MUST
be
an
absolute
IRI
null
.
The following typographic conventions are used in this specification:
markup
markup
definition
reference
markup
external
definition
reference
Notes are in light green boxes with a green left border and with a "Note" header in green. Notes are normative or informative depending on the whether they are in a normative or informative section, respectively.
Examples are in light khaki boxes, with khaki left border, and with a
numbered "Example" header in khaki. Examples are always informative.
The
content
of
the
example
is
in
monospace
font
and
may
be
syntax
colored.
This section is non-normative.
JSON-LD satisfies the following design goals:
@context
and
@id
)
to
use
the
basic
functionality
in
JSON-LD.
This section is non-normative.
Generally
speaking,
the
data
model
described
by
a
JSON-LD
document
is
a
labeled,
directed
graph
.
The
graph
contains
nodes
,
which
are
connected
by
edges
.
A
node
is
typically
data
such
as
a
string
,
number
,
typed
values
(like
dates
and
times)
or
an
IRI
.
There
is
also
a
special
class
of
node
called
Within
a
blank
node
,
which
is
typically
used
to
express
data
that
does
directed
graph,
nodes
with
may
be
unnamed
,
i.e.,
not
have
a
global
identifier
like
identified
by
an
IRI
or
representing
data
such
as
strings
or
numbers
.
Blank
Such
nodes
are
called
blank
nodes
,
and
may
be
identified
using
a
blank
node
identifier
.
These
identifiers
may
be
required
to
represent
a
fully
connected
graph
using
a
tree
structure,
such
as
JSON,
but
otherwise
have
no
intrinsic
meaning.
This
simple
data
model
is
incredibly
flexible
and
powerful,
capable
of
modeling
almost
any
kind
of
data.
For
a
deeper
explanation
of
the
data
model,
see
section
5.
8.
Data
Model
.
Developers
who
are
familiar
with
Linked
Data
technologies
will
recognize
the
data
model
as
the
RDF
Data
Model.
To
dive
deeper
into
how
JSON-LD
and
RDF
are
related,
see
section
7.
10.
Relationship
to
RDF
.
At the surface level, a JSON-LD document is simply JSON , detailed in [ RFC7159 ]. For the purpose of describing the core data structures, this is limited to arrays , dictionaries (the parsed version of a JSON Object ), strings , numbers , booleans , and null , called the JSON-LD internal representation . This allows surface syntaxes other than JSON to be manipulated using the same algorithms, when the syntax maps to equivalent core data structures .
Although not discussed in this specification, parallel work using YAML [ YAML ] and binary representations such as CBOR [ RFC7049 ] could be used to map into the internal representation , allowing the JSON-LD 1.1 API [ JSON-LD11-API ] to operate as if the source was a JSON document.
JSON-LD specifies a number of syntax tokens and keywords that are a core part of the language:
:
@base
@container
@context
@context
keyword
is
described
in
detail
in
section
3.1
The
Context
.
@graph
@id
@index
@language
@list
@nest
@none
@prefix
@reverse
@set
@type
@value
@version
json-ld-1.1
.
@vocab
@type
with
a
common
prefix
IRI
.
This
keyword
is
described
in
section
All keys, keywords , and values in JSON-LD are case-sensitive.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY , MUST , MUST NOT , RECOMMENDED , SHOULD , and SHOULD NOT are to be interpreted as described in [ RFC2119 ].
Conformance criteria are relevant to authors and authoring tool implementers. As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
A
JSON-LD
document
complies
with
this
specification
if
it
follows
the
normative
statements
in
appendix
6.
9.
JSON-LD
Grammar
.
JSON
documents
can
be
interpreted
as
JSON-LD
by
following
the
normative
statements
in
section
4.9
6.
Interpreting
JSON
as
JSON-LD
.
For
convenience,
normative
statements
for
documents
are
often
phrased
as
statements
on
the
properties
of
the
document.
This specification makes use of the following namespaces:
dc
:
http://purl.org/dc/terms/
cred
:
https://w3id.org/credentials#
foaf
:
http://xmlns.com/foaf/0.1/
prov
http://www.w3.org/ns/prov#
rdf
:
http://www.w3.org/1999/02/22-rdf-syntax-ns#
schema
:
http://schema.org/
xsd
:
http://www.w3.org/2001/XMLSchema#
These
are
used
within
this
document
as
part
of
a
compact
IRI
as
a
shorthand
for
the
resulting
absolute
IRI
,
such
as
dc:title
used
to
represent
http://purl.org/dc/terms/title
.
This section is non-normative.
JSON [ RFC7159 ] is a lightweight, language-independent data interchange format. It is easy to parse and easy to generate. However, it is difficult to integrate JSON from different sources as the data may contain keys that conflict with other data sources. Furthermore, JSON has no built-in support for hyperlinks, which are a fundamental building block on the Web. Let's start by looking at an example that we will be using for the rest of this section:
{
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/",
"image": "http://manu.sporny.org/images/manu.png"
}
It's
obvious
to
humans
that
the
data
is
about
a
person
whose
name
is
"Manu
Sporny"
and
that
the
homepage
property
contains
the
URL
of
that
person's
homepage.
A
machine
doesn't
have
such
an
intuitive
understanding
and
sometimes,
even
for
humans,
it
is
difficult
to
resolve
ambiguities
in
such
representations.
This
problem
can
be
solved
by
using
unambiguous
identifiers
to
denote
the
different
concepts
instead
of
tokens
such
as
"name",
"homepage",
etc.
Linked
Data,
and
the
Web
in
general,
uses
IRIs
(
Internationalized
Resource
Identifiers
as
described
in
[
RFC3987
])
for
unambiguous
identification.
The
idea
is
to
use
IRIs
to
assign
unambiguous
identifiers
to
data
that
may
be
of
use
to
other
developers.
It
is
useful
for
terms
,
like
name
and
homepage
,
to
expand
to
IRIs
so
that
developers
don't
accidentally
step
on
each
other's
terms.
Furthermore,
developers
and
machines
are
able
to
use
this
IRI
(by
using
a
web
browser,
for
instance)
to
go
to
the
term
and
get
a
definition
of
what
the
term
means.
This
process
is
known
as
IRI
dereferencing.
Leveraging the popular schema.org vocabulary , the example above could be unambiguously expressed as follows:
{ "http://schema.org/name": "Manu Sporny", "http://schema.org/url": { "@id": "http://manu.sporny.org/" }, ← The '@id' keyword means 'This value is an identifier that is an IRI' "http://schema.org/image": { "@id": "http://manu.sporny.org/images/manu.png" } }
In
the
example
above,
every
property
is
unambiguously
identified
by
an
IRI
and
all
values
representing
IRIs
are
explicitly
marked
as
such
by
the
@id
keyword
.
While
this
is
a
valid
JSON-LD
document
that
is
very
specific
about
its
data,
the
document
is
also
overly
verbose
and
difficult
to
work
with
for
human
developers.
To
address
this
issue,
JSON-LD
introduces
the
notion
of
a
context
as
described
in
the
next
section.
This section is non-normative.
When two people communicate with one another, the conversation takes place in a shared environment, typically called "the context of the conversation". This shared context allows the individuals to use shortcut terms, like the first name of a mutual friend, to communicate more quickly but without losing accuracy. A context in JSON-LD works in the same way. It allows two applications to use shortcut terms to communicate with one another more efficiently, but without losing accuracy.
Simply speaking, a context is used to map terms to IRIs . Terms are case sensitive and any valid string that is not a reserved JSON-LD keyword can be used as a term .
For the sample document in the previous section, a context would look something like this:
{ "@context": { "name": "http://schema.org/name", ← This means that 'name' is shorthand for 'http://schema.org/name' "image": { "@id": "http://schema.org/image", ← This means that 'image' is shorthand for 'http://schema.org/image' "@type": "@id" ← This means that a string value associated with 'image' should be interpreted as an identifier that is an IRI }, "homepage": { "@id": "http://schema.org/url", ← This means that 'homepage' is shorthand for 'http://schema.org/url' "@type": "@id" ← This means that a string value associated with 'homepage' should be interpreted as an identifier that is an IRI } } }
As the context above shows, the value of a term definition can either be a simple string, mapping the term to an IRI , or a JSON object .
When
a
JSON
object
is
associated
with
a
term,
it
is
called
an
expanded
term
definition
.
The
example
above
specifies
that
the
values
of
image
and
homepage
,
if
they
are
strings,
are
to
be
interpreted
as
IRIs
.
Expanded
term
definitions
also
allow
terms
to
be
used
for
index
maps
and
to
specify
whether
array
values
are
to
be
interpreted
as
sets
or
lists
.
Expanded
term
definitions
may
be
defined
using
absolute
or
compact
IRIs
as
keys,
which
is
mainly
used
to
associate
type
or
language
information
with
an
absolute
or
compact
IRI
.
Contexts
can
either
be
directly
embedded
into
the
document
or
be
referenced.
Assuming
the
context
document
in
the
previous
example
can
be
retrieved
at
https://json-ld.org/contexts/person.jsonld
,
it
can
be
referenced
by
adding
a
single
line
and
allows
a
JSON-LD
document
to
be
expressed
much
more
concisely
as
shown
in
the
example
below:
{
"@context": "https://json-ld.org/contexts/person.jsonld",
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/",
"image": "http://manu.sporny.org/images/manu.png"
}
The
referenced
context
not
only
specifies
how
the
terms
map
to
IRIs
in
the
Schema.org
vocabulary
but
also
specifies
that
string
values
associated
with
the
homepage
and
image
property
can
be
interpreted
as
an
IRI
(
"@type":
"@id"
,
see
section
3.2
IRIs
for
more
details).
This
information
allows
developers
to
re-use
each
other's
data
without
having
to
agree
to
how
their
data
will
interoperate
on
a
site-by-site
basis.
External
JSON-LD
context
documents
may
contain
extra
information
located
outside
of
the
@context
key,
such
as
documentation
about
the
terms
declared
in
the
document.
Information
contained
outside
of
the
@context
value
is
ignored
when
the
document
is
used
as
an
external
JSON-LD
context
document.
JSON
documents
can
be
interpreted
as
JSON-LD
without
having
to
be
modified
by
referencing
a
context
via
an
HTTP
Link
Header
as
described
in
section
4.9
6.
Interpreting
JSON
as
JSON-LD
.
It
is
also
possible
to
apply
a
custom
context
using
the
JSON-LD
1.1
API
[
JSON-LD11-API
].
In JSON-LD documents , contexts may also be specified inline. This has the advantage that documents can be processed even in the absence of a connection to the Web. Ultimately, this is a modeling decision and different use cases may require different handling.
{
"@context": {
"name": "http://schema.org/name",
"image": {
"@id": "http://schema.org/image",
"@type": "@id"
},
"homepage": {
"@id": "http://schema.org/url",
"@type": "@id"
}
},
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/",
"image": "http://manu.sporny.org/images/manu.png"
}
This section only covers the most basic features of the JSON-LD Context. The Context can also be used to help interpret other more complex JSON data structures, such as indexed values , ordered values , and nested properties . More advanced features related to the JSON-LD Context are covered in section section 4. Advanced Concepts .
This section is non-normative.
IRIs ( Internationalized Resource Identifiers [ RFC3987 ]) are fundamental to Linked Data as that is how most nodes and properties are identified. In JSON-LD, IRIs may be represented as an absolute IRI or a relative IRI . An absolute IRI is defined in [ RFC3987 ] as containing a scheme along with path and optional query and fragment segments. A relative IRI is an IRI that is relative to some other absolute IRI . In JSON-LD, with exceptions are as described below, all relative IRIs are resolved relative to the base IRI .
Properties
,
values
of
@type
,
and
values
of
properties
with
a
term
definition
that
defines
them
as
being
relative
to
the
vocabulary
mapping
,
may
have
the
form
of
a
relative
IRI
,
but
are
resolved
using
the
vocabulary
mapping
,
and
not
the
base
IRI
.
A
string
is
interpreted
as
an
IRI
when
it
is
the
value
of
an
@id
member:
{ ... "homepage": { "@id": "http://example.com/" } ... }
Values
that
are
interpreted
as
IRIs
,
can
also
be
expressed
as
relative
IRIs
.
For
example,
assuming
that
the
following
document
is
located
at
http://example.com/about/
,
the
relative
IRI
../
would
expand
to
http://example.com/
(for
more
information
on
where
relative
IRIs
can
be
used,
please
refer
to
section
6.
9.
JSON-LD
Grammar
).
{ ... "homepage": { "@id": "../" } ... }
Absolute IRIs can be expressed directly in the key position like so:
{ ... "http://schema.org/name": "Manu Sporny", ... }
In
the
example
above,
the
key
http://schema.org/name
is
interpreted
as
an
absolute
IRI
.
Term-to- IRI expansion occurs if the key matches a term defined within the active context :
{ "@context": { "name": "http://schema.org/name" }, "name": "Manu Sporny", "status": "trollin'" }
JSON
keys
that
do
not
expand
to
an
IRI
,
such
as
status
in
the
example
above,
are
not
Linked
Data
and
thus
ignored
when
processed.
If
type
coercion
rules
are
specified
in
the
@context
for
a
particular
term
or
property
IRI
,
an
IRI
is
generated:
{ "@context": { ... "homepage": { "@id": "http://schema.org/url", "@type": "@id" } ... }, ... "homepage": "http://manu.sporny.org/" ... }
In
the
example
above,
since
the
value
http://manu.sporny.org/
is
expressed
as
a
JSON
string
,
the
type
coercion
rules
will
transform
the
value
into
an
IRI
when
processing
the
data.
See
section
4.6
4.2.2
Type
Coercion
for
more
details
about
this
feature.
In summary, IRIs can be expressed in a variety of different ways in JSON-LD:
@id
or
@type
.
@type
key
that
is
set
to
a
value
of
@id
or
@vocab
.
This section only covers the most basic features associated with IRIs in JSON-LD. More advanced features related to IRIs are covered in section 4. Advanced Concepts .
This section is non-normative.
To be able to externally reference nodes in a graph , it is important that nodes have an identifier. IRIs are a fundamental concept of Linked Data, for nodes to be truly linked, dereferencing the identifier should result in a representation of that node . This may allow an application to retrieve further information about a node .
In
JSON-LD,
a
node
is
identified
using
the
@id
keyword
:
{ "@context": { ... "name": "http://schema.org/name" }, "@id": "http://me.markus-lanthaler.com/", "name": "Markus Lanthaler", ... }
The
example
above
contains
a
node
object
identified
by
the
IRI
http://me.markus-lanthaler.com/
.
This section only covers the most basic features associated with node identifiers in JSON-LD. More advanced features related to node identifiers are covered in section 4. Advanced Concepts .
This section is non-normative.
In
Linked
Data,
it
is
common
to
specify
the
type
of
a
graph
node;
in
many
cases,
this
can
be
inferred
based
on
the
properties
used
within
a
given
node
object
,
or
the
property
for
which
a
node
is
a
value.
For
example,
in
the
schema.org
vocabulary,
the
givenName
property
is
associated
with
a
Person
.
Therefore,
one
may
reason
that
if
a
node
object
contains
the
property
firstName
,
that
the
type
is
a
Person
;
making
this
explicit
with
@type
helps
to
clarify
the
association.
The
type
of
a
particular
node
can
be
specified
using
the
@type
keyword
.
In
Linked
Data,
types
are
uniquely
identified
with
an
IRI
.
{"@id": "http://example.org/places#BrewEats", ","@context": { ... "givenName": "http://schema.org/givenName", "familyName": "http://schema.org/familyName" }, "@id": "http://me.markus-lanthaler.com/", "@type": "http://schema.org/Person", "givenName": "Markus", "familyName": "Lanthaler", ... }
A node can be assigned more than one type by using an array :
{ ..."@id": "http://example.org/places#BrewEats", ","@id": "http://me.markus-lanthaler.com/", "@type": [ "http://schema.org/Person", "http://xmlns.com/foaf/0.1/Person" ], ... }
The
value
of
an
@type
key
may
also
be
a
term
defined
in
the
active
context
:
{ "@context": { ..."Person": "http://schema.org/Person" }, "@id": "http://example.org/places#BrewEats",,"@type": "Person", ... }
This
section
only
covers
the
most
basic
features
associated
with
types
in
JSON-LD.
It
is
worth
noting
that
the
@type
keyword
is
not
only
used
to
specify
the
type
of
a
node
but
also
to
express
typed
values
(as
described
in
section
4.5
4.2.1
Typed
Values
)
and
to
type
coerce
values
(as
described
in
section
4.6
4.2.2
Type
Coercion
).
Specifically,
@type
cannot
be
used
in
a
context
to
define
a
node
's
type.
For
a
detailed
description
of
the
differences,
please
refer
to
section
4.5
4.2.1
Typed
Values
.
JSON-LD
has
a
number
of
features
that
provide
functionality
above
and
beyond
the
core
functionality
described
above.
The
following
JSON
can
be
used
to
express
data
using
such
structures,
and
the
features
described
in
this
section
describes
can
be
used
to
interpret
a
variety
of
different
JSON
structures
as
Linked
Data.
A
JSON-LD
processor
will
make
use
of
provided
and
embedded
contexts
to
interpret
property
values
in
a
number
of
different
idiomatic
ways.
One pattern in JSON is for the value of a property to be a string. Often times, this string actually represents some other typed value, for example an IRI , a date, or a string in some specific language. See section 4.2 Describing Values for details on how to describe such value typing.
In JSON, a property with an array value implies an implicit order; arrays in JSON-LD do not provide an ordering of the contained elements by default, unless defined using embedded structures or through a context definition. See section 4.3 Value Ordering for a further discussion.
Another JSON idiom often found in APIs is to use an intermediate object to represent the properties of an object; in JSON-LD these are refered to as nested properties and are described in section 4.4 Nested Properties .
Linked Data is all about describing the relationships between different resources. Sometimes these relationships are between resources defined in different documents described on the web, sometimes the resources are described within the same document.
{ "@context": { "@vocab": "http://schema.org/", "knows": {"@type": "@id"} }, "@id": "http://manu.sporny.org/about#manu", "@type": "Person", "name": "Manu Sporny", "knows": "http://greggkellogg.net/foaf#me" }
In
this
case,
a
document
residing
at
http://manu.sporny.org/about
may
contain
the
example
above,
and
reference
another
document
at
http://greggkellogg.net/foaf
which
could
include
a
similar
representation.
A common idiom found in JSON usage is objects being specified as the value of other objects, called object embedding in JSON-LD; for example, a friend specified as an object value of a Person :
{ "@context": { "@vocab": "http://schema.org/" }, "@id": "http://manu.sporny.org/about#manu", "@type": "Person", "name": "Manu Sporny", "knows": { "@id": "http://greggkellogg.net/foaf#me", "@type": "Person", "name": "Gregg Kellogg" } }
See section 4.5 Embedding details these relationships.
Another common idiom in JSON is to use an intermediate object to represent property values via indexing. JSON-LD allows data to be indexed in a number of different ways, as detailed in section 4.6 Indexed Values .
JSON-LD serializes directed graphs . That means that every property points from a node to another node or value . However, in some cases, it is desirable to serialize in the reverse direction, as detailed in section 4.7 Reverse Properties .
The following sections describe such advanced functionality in more detail.
This section is non-normative.
Section 3.1 The Context introduced the basics of what makes JSON-LD work. This section expands on the basic principles of the context and demonstrates how more advanced use cases can be achieved using JSON-LD.
In general, contexts may be used any time a JSON object is defined. The only time that one cannot express a context is as a direct child of another context definition (other than as part of an expanded term definition ). For example, a JSON-LD document may use more than one context at different points in a document:
[ { "@context": "http://example.org/contexts/person.jsonld", "name": "Manu Sporny", "homepage": "http://manu.sporny.org/", "depiction": "http://twitter.com/account/profile_image/manusporny" }, { "@context": "http://example.org/contexts/place.jsonld", "name": "The Empire State Building", "description": "The Empire State Building is a 102-story landmark in New York City.", "geo": { "latitude": "40.75", "longitude": "73.98" } } ]
Duplicate context terms are overridden using a most-recently-defined-wins mechanism.
{ "@context": { "name": "http://example.com/person#name", "details": "http://example.com/person#details" }, "name": "Markus Lanthaler", ... "details": { "@context": { "name": "http://example.com/organization#name" }, "name": "Graz University of Technology" } }
In
the
example
above,
the
name
term
is
overridden
in
the
more
deeply
nested
details
structure.
Note
that
this
is
rarely
a
good
authoring
practice
and
is
typically
used
when
working
with
legacy
applications
that
depend
on
a
specific
structure
of
the
JSON
object
.
If
a
term
is
redefined
within
a
context,
all
previous
rules
associated
with
the
previous
definition
are
removed.
If
a
term
is
redefined
to
null
,
the
term
is
effectively
removed
from
the
list
of
terms
defined
in
the
active
context
.
Multiple
contexts
may
be
combined
using
an
array
,
which
is
processed
in
order.
The
set
of
contexts
defined
within
a
specific
JSON
object
are
referred
to
as
local
contexts
.
The
active
context
refers
to
the
accumulation
of
local
contexts
that
are
in
scope
at
a
specific
point
within
the
document.
Setting
a
local
context
to
null
effectively
resets
the
active
context
to
an
empty
context,
without
term
definitions
,
default
language
,
or
other
things
defined
within
previous
contexts.
The
following
example
specifies
an
external
context
and
then
layers
an
embedded
context
on
top
of
the
external
context:
{ "@context": [ "https://json-ld.org/contexts/person.jsonld", { "pic": "http://xmlns.com/foaf/0.1/depiction" } ], "name": "Manu Sporny", "homepage": "http://manu.sporny.org/", "pic": "http://twitter.com/account/profile_image/manusporny" }
When possible, the context definition should be put at the top of a JSON-LD document. This makes the document easier to read and might make streaming parsers more efficient. Documents that do not have the context at the top are still conformant JSON-LD.
To
avoid
forward-compatibility
issues,
terms
starting
with
an
@
character
are
to
be
avoided
as
they
might
be
used
as
keyword
in
future
versions
of
JSON-LD.
Terms
starting
with
an
@
character
that
are
not
JSON-LD
1.1
keywords
are
treated
as
any
other
term,
i.e.,
they
are
ignored
unless
mapped
to
an
IRI
.
Furthermore,
the
use
of
empty
terms
(
""
)
is
not
allowed
as
not
all
programming
languages
are
able
to
handle
empty
JSON
keys.
This section is non-normative.
New
features
defined
in
JSON-LD
1.1
are
available
when
the
processing
mode
is
set
to
json-ld-1.1
.
This
may
be
set
using
the
@version
member
in
a
context
set
to
the
value
1.1
as
a
number
,
or
through
an
API
option.
{ "@context": { "@version": 1.1, ... }, ... }
The
first
context
encountered
when
processing
a
document
which
contains
@version
determines
the
processing
mode
,
unless
it
is
defined
explicitly
through
an
API
option.
Setting the processing mode explicitly for JSON-LD 1.1 is necessary so that a JSON-LD 1.0 processor does not attempt to process a JSON-LD 1.1 document and silently produce different results.
This section is non-normative.
At
times,
all
properties
and
types
may
come
from
the
same
vocabulary.
JSON-LD's
@vocab
keyword
allows
an
author
to
set
a
common
prefix
which
is
used
as
the
vocabulary
mapping
and
is
used
for
all
properties
and
types
that
do
not
match
a
term
and
are
neither
a
compact
IRI
nor
an
absolute
IRI
(i.e.,
they
do
not
contain
a
colon).
{ "@context": { "@vocab": "http://schema.org/" }, "@id": "http://example.org/places#BrewEats", "@type": "Restaurant", "name": "Brew Eats" ... }
If
@vocab
is
used
but
certain
keys
in
an
object
should
not
be
expanded
using
the
vocabulary
IRI
,
a
term
can
be
explicitly
set
to
null
in
the
context
.
For
instance,
in
the
example
below
the
databaseId
member
would
not
expand
to
an
IRI
causing
the
property
to
be
dropped
when
expanding.
{ "@context": { "@vocab": "http://schema.org/", "databaseId": null }, "@id": "http://example.org/places#BrewEats", "@type": "Restaurant", "name": "Brew Eats", "databaseId": "23987520" }
In
some
cases,
vocabulary
terms
are
defined
directly
within
the
document
itself,
rather
than
in
an
external
vocabulary.
Since
json-ld-1.1
,
the
vocabulary
mapping
in
the
active
context
can
be
set
to
the
empty
string
""
,
which
causes
terms
which
are
expanded
relative
to
the
vocabulary,
such
as
the
keys
of
node
objects
,
to
use
the
base
IRI
to
create
absolute
IRIs
.
{ "@context": { "@version": 1.1, "@base": "http://example/document", "@vocab": "" }, "@id": "http://example.org/places#BrewEats", "@type": "#Restaurant", "#name": "Brew Eats" ... }
If
this
document
were
located
at
http://example/document
,
it
would
expand
as
follows:
[{ "@id": "http://example.org/places#BrewEats", "@type": ["http://example/document#Restaurant"], "http://example/document#name": [{"@value": "Brew Eats"}] }]
This section is non-normative.
JSON-LD
allows
IRIs
to
be
specified
in
a
relative
form
which
is
resolved
against
the
document
base
according
section
5.1
Establishing
a
Base
URI
of
[
RFC3986
].
The
base
IRI
may
be
explicitly
set
with
a
context
using
the
@base
keyword.
For
example,
if
a
JSON-LD
document
was
retrieved
from
http://example.com/document.jsonld
,
relative
IRIs
would
resolve
against
that
IRI
:
{
"@context": {
"label": "http://www.w3.org/2000/01/rdf-schema#label"
},
"@id": "",
"label": "Just a simple document"
}
This
document
uses
an
empty
@id
,
which
resolves
to
the
document
base.
However,
if
the
document
is
moved
to
a
different
location,
the
IRI
would
change.
To
prevent
this
without
having
to
use
an
absolute
IRI
,
a
context
may
define
an
@base
mapping,
to
overwrite
the
base
IRI
for
the
document.
{
"@context": {
"@base": "http://example.com/document.jsonld",
"label": "http://www.w3.org/2000/01/rdf-schema#label"
},
"@id": "",
"label": "Just a simple document"
}
Setting
@base
to
null
will
prevent
relative
IRIs
from
being
expanded
to
absolute
IRIs
.
Please
note
that
the
@base
will
be
ignored
if
used
in
external
contexts.
This section is non-normative.
A
compact
IRI
is
a
way
of
expressing
an
IRI
using
a
prefix
and
suffix
separated
by
a
colon
(
:
).
The
prefix
is
a
term
taken
from
the
active
context
and
is
a
short
string
identifying
a
particular
IRI
in
a
JSON-LD
document.
For
example,
the
prefix
foaf
may
be
used
as
a
short
hand
for
the
Friend-of-a-Friend
vocabulary,
which
is
identified
using
the
IRI
http://xmlns.com/foaf/0.1/
.
A
developer
may
append
any
of
the
FOAF
vocabulary
terms
to
the
end
of
the
prefix
to
specify
a
short-hand
version
of
the
absolute
IRI
for
the
vocabulary
term.
For
example,
foaf:name
would
be
expanded
to
the
IRI
http://xmlns.com/foaf/0.1/name
.
{ "@context": { "foaf": "http://xmlns.com/foaf/0.1/" ... }, "@type": "foaf:Person", "foaf:name": "Dave Longley", ... }
In
the
example
above,
foaf:name
expands
to
the
IRI
http://xmlns.com/foaf/0.1/name
and
foaf:Person
expands
to
http://xmlns.com/foaf/0.1/Person
.
Prefixes
are
expanded
when
the
form
of
the
value
is
a
compact
IRI
represented
as
a
prefix:suffix
combination,
the
prefix
matches
a
term
defined
within
the
active
context
,
and
the
suffix
does
not
begin
with
two
slashes (
//
).
The
compact
IRI
is
expanded
by
concatenating
the
IRI
mapped
to
the
prefix
to
the
(possibly
empty)
suffix
.
If
the
prefix
is
not
defined
in
the
active
context
,
or
the
suffix
begins
with
two
slashes
(such
as
in
http://example.com
),
the
value
is
interpreted
as
absolute
IRI
instead.
If
the
prefix
is
an
underscore
(
_
),
the
value
is
interpreted
as
blank
node
identifier
instead.
It's also possible to use compact IRIs within the context as shown in the following example:
{ "@context": { "@version": 1.1, "xsd": "http://www.w3.org/2001/XMLSchema#", "foaf": "http://xmlns.com/foaf/0.1/", "foaf:homepage": { "@type": "@id" }, "picture": { "@id": "foaf:depiction", "@type": "@id" } }, "@id": "http://me.markus-lanthaler.com/", "@type": "foaf:Person", "foaf:name": "Markus Lanthaler", "foaf:homepage": "http://www.markus-lanthaler.com/", "picture": "http://twitter.com/account/profile_image/markuslanthaler" }
In
JSON-LD
1.0,
terms
may
be
chosen
as
compact
IRI
prefixes
when
compacting
only
if
a
simple
term
definition
is
used
where
the
value
ends
with
a
URI
gen-delim
character
(e.g,
/
,
#
and
others,
see
[
RFC3986
]).
The
previous
specification
allows
any
term
to
be
chosen
as
a
compact
IRI
prefix,
which
led
to
a
poor
experience.
In
JSON-LD
1.1,
terms
may
be
chosen
as
compact
IRI
prefixes
when
compacting
only
if
a
simple
term
definition
is
used
where
the
value
ends
with
a
URI
gen-delim
character,
or
if
their
expanded
term
definition
contains
a
@prefix
member
with
the
value
true
.
This represents a small change to the 1.0 algorithm to prevent IRIs that are not really intended to be used as prefixes from being used for creating compact IRIs .
When
processing
mode
is
set
to
json-ld-1.1
,
terms
will
be
used
as
compact
IRI
prefixes
when
compacting
only
if
their
expanded
term
definition
contains
a
@prefix
member
with
the
value
true
,
or
if
it
has
a
a
simple
term
definition
where
the
value
ends
with
a
URI
gen-delim
character
(e.g,
/
,
#
and
others,
see
[
RFC3986
]).
{ "@context": { "compact-iris": {"@id": "http://example.com/compact-iris-", "@prefix": true}, "property": "http://example.com/property" }, "property": { "@id": "compact-iris:are-considered", "property": "@prefix does not require a gen-delim" } }
In
this
case,
the
compact-iris
term
would
not
normally
be
usable
as
a
prefix,
both
because
it
is
defined
with
an
expanded
term
definition
,
and
because
it's
@id
does
not
end
in
a
gen-delim
character.
Adding
"@prefix":
true
allows
it
to
be
used
as
the
prefix
portion
of
the
compact
IRI
compact-iris:are-considered
.
This section is non-normative.
Each
of
the
JSON-LD
keywords
,
except
for
@context
,
may
be
aliased
to
application-specific
keywords.
This
feature
allows
legacy
JSON
content
to
be
utilized
by
JSON-LD
by
re-using
JSON
keys
that
already
exist
in
legacy
documents.
This
feature
also
allows
developers
to
design
domain-specific
implementations
using
only
the
JSON-LD
context
.
{ "@context": { "url": "@id", "a": "@type", "name": "http://xmlns.com/foaf/0.1/name" }, "url": "http://example.com/about#gregg", "a": "http://xmlns.com/foaf/0.1/Person", "name": "Gregg Kellogg" }
In
the
example
above,
the
@id
and
@type
keywords
have
been
given
the
aliases
url
and
a
,
respectively.
Since keywords cannot be redefined, they can also not be aliased to other keywords.
Aliased keywords may not be used within a context , itself.
This section is non-normative.
In
general,
normal
IRI
expansion
rules
apply
anywhere
an
IRI
is
expected
(see
section
3.2
IRIs
).
Within
a
context
definition,
this
can
mean
that
terms
defined
within
the
context
may
also
be
used
within
that
context
as
long
as
there
are
no
circular
dependencies.
For
example,
it
is
common
to
use
the
xsd
namespace
when
defining
typed
values
:
{ "@context": { "xsd": "http://www.w3.org/2001/XMLSchema#", "name": "http://xmlns.com/foaf/0.1/name", "age": { "@id": "http://xmlns.com/foaf/0.1/age", "@type": "xsd:integer" }, "homepage": { "@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id" } }, ... }
In
this
example,
the
xsd
term
is
defined
and
used
as
a
prefix
for
the
@type
coercion
of
the
age
property.
Terms may also be used when defining the IRI of another term :
{ "@context": { "foaf": "http://xmlns.com/foaf/0.1/", "xsd": "http://www.w3.org/2001/XMLSchema#", "name": "foaf:name", "age": { "@id": "foaf:age", "@type": "xsd:integer" }, "homepage": { "@id": "foaf:homepage", "@type": "@id" } }, ... }
Compact IRIs and IRIs may be used on the left-hand side of a term definition.
{ "@context": { "foaf": "http://xmlns.com/foaf/0.1/", "xsd": "http://www.w3.org/2001/XMLSchema#", "name": "foaf:name", "foaf:age": { "@type": "xsd:integer" }, "foaf:homepage": { "@type": "@id" } }, ... }
In
this
example,
the
compact
IRI
form
is
used
in
two
different
ways.
In
the
first
approach,
foaf:age
declares
both
the
IRI
for
the
term
(using
short-form)
as
well
as
the
@type
associated
with
the
term
.
In
the
second
approach,
only
the
@type
associated
with
the
term
is
specified.
The
full
IRI
for
foaf:homepage
is
determined
by
looking
up
the
foaf
prefix
in
the
context
.
Absolute IRIs may also be used in the key position in a context :
{ "@context": { "foaf": "http://xmlns.com/foaf/0.1/", "xsd": "http://www.w3.org/2001/XMLSchema#", "name": "foaf:name", "foaf:age": { "@id": "foaf:age", "@type": "xsd:integer" }, "http://xmlns.com/foaf/0.1/homepage": { "@type": "@id" } }, ... }
In
order
for
the
absolute
IRI
to
match
above,
the
absolute
IRI
needs
to
be
used
in
the
JSON-LD
document
.
Also
note
that
foaf:homepage
will
not
use
the
{
"@type":
"@id"
}
declaration
because
foaf:homepage
is
not
the
same
as
http://xmlns.com/foaf/0.1/homepage
.
That
is,
terms
are
looked
up
in
a
context
using
direct
string
comparison
before
the
prefix
lookup
mechanism
is
applied.
While
it
is
possible
to
define
a
compact
IRI
,
or
an
absolute
IRI
to
expand
to
some
other
unrelated
IRI
(for
example,
foaf:name
expanding
to
http://example.org/unrelated#species
),
such
usage
is
strongly
discouraged.
The only exception for using terms in the context is that circular definitions are not allowed. That is, a definition of term1 cannot depend on the definition of term2 if term2 also depends on term1 . For example, the following context definition is illegal:
{ "@context": { "term1": "term2:foo", "term2": "term1:bar" }, ... }
This section is non-normative.
An
expanded
term
definition
can
include
a
@context
property,
which
defines
a
context
(an
embedded
context
)
for
values
of
properties
defined
using
that
term
.
This
allows
values
to
use
term
definitions
,
base
IRI
,
vocabulary
mapping
or
default
language
which
is
different
from
the
node
object
they
are
contained
in,
as
if
the
context
was
specified
within
the
value
itself.
{ "@context": { "@version": 1.1, "name": "http://schema.org/name", "interest": { "@id": "http://xmlns.com/foaf/0.1/interest", "@context": {"@vocab": "http://xmlns.com/foaf/0.1/"} } }, "name": "Manu Sporny", "interest": { "@id": "https://www.w3.org/TR/json-ld/", "name": "JSON-LD", "topic": "Linking Data" } }
In this case, the social profile is defined using the schema.org vocabulary, but interest is imported from FOAF, and is used to define a node describing one of Manu's interests where those properties now come from the FOAF vocabulary.
Expanding this document, uses a combination of terms defined in the outer context, and those defined specifically for that term in an embedded context .
[{
"http://schema.org/name": [{"@value": "Manu Sporny"}],
"http://xmlns.com/foaf/0.1/interest": [{
"@id": "https://www.w3.org/TR/json-ld/",
"http://schema.org/name": [{"@value": "JSON-LD"}],
"http://xmlns.com/foaf/0.1/topic": [{"@value": "Linking Data"}]
}]
}]
Scoping
can
also
be
performed
using
a
term
used
as
a
value
of
@type
:
{ "@context": { "@version": 1.1, "name": "http://schema.org/name", "interest": "http://xmlns.com/foaf/0.1/interest", "Document": { "@id": "http://xmlns.com/foaf/0.1/Document", "@context": {"@vocab": "http://xmlns.com/foaf/0.1/"} } }, "@type": "Person", "name": "Manu Sporny", "interest": { "@id": "https://www.w3.org/TR/json-ld/", "@type": "Document", "name": "JSON-LD", "topic": "Linking Data" } }
Scoping
on
@type
is
useful
when
common
properties
are
used
to
relate
things
of
different
types,
where
the
vocabularies
in
use
within
different
entities
calls
for
different
context
scoping.
For
example,
hasPart
/
partOf
may
be
common
terms
used
in
a
document,
but
mean
different
things
depending
on
the
context.
When
expanding,
each
value
of
@type
is
considered
(ordering
them
lexographically)
where
that
value
is
also
a
term
in
the
active
context
having
its
own
embedded
context
.
If
so,
that
embedded
context
is
applied
to
the
active
context
.
When
compacting,
if
a
term
is
chosen
to
represent
an
IRI
used
as
a
value
of
@type
where
that
term
definition
also
has
an
embedded
context
,
it
is
then
applied
to
the
active
context
to
affect
further
compaction.
The
values
of
@type
are
unordered,
so
if
multiple
types
are
listed,
the
order
that
scoped
contexts
are
applied
is
based
on
lexicographical
ordering.
If a term defines a scoped context, and then that term is later re-defined, the association of the context defined in the earlier expanded term definition is lost within the scope of that re-definition. This is consistent with term definitions of a term overriding previous term definitions from earlier less deeply nested definitions, as discussed in section 4.1 Advanced Context Usage .
Scoped
Contexts
are
a
new
feature
in
JSON-LD
1.1,
requiring
processing
mode
set
to
json-ld-1.1
.
This section is non-normative.
Values are leaf nodes in a graph associated with scalar values such as strings , dates, times, and other such atomic values.
This section is non-normative.
A value with an associated type, also known as a typed value , is indicated by associating a value with an IRI which indicates the value's type. Typed values may be expressed in JSON-LD in three ways:
@type
keyword
when
defining
a
term
within
an
@context
section.
The
first
example
uses
the
@type
keyword
to
associate
a
type
with
a
particular
term
in
the
@context
:
{ "@context": { "modified": { "@id": "http://purl.org/dc/terms/modified", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" } }, ... "@id": "http://example.com/docs/1", "modified": "2010-05-29T14:17:39+02:00", ... }
The
modified
key's
value
above
is
automatically
type
coerced
to
a
dateTime
value
because
of
the
information
specified
in
the
@context
.
A
JSON-LD
processor
will
interpret
the
example
above
as
follows:
Subject | Property | Value | Value Type |
---|---|---|---|
http://example.com/docs/1 | http://purl.org/dc/terms/modified | 2010-05-29T14:17:39+02:00 | xsd:dateTime |
The second example uses the expanded form of setting the type information in the body of a JSON-LD document:
{ "@context": { "modified": { "@id": "http://purl.org/dc/terms/modified" } }, ... "modified": { "@value": "2010-05-29T14:17:39+02:00", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" } ... }
Both
examples
above
would
generate
the
value
2010-05-29T14:17:39+02:00
with
the
type
http://www.w3.org/2001/XMLSchema#dateTime
.
Note
that
it
is
also
possible
to
use
a
term
or
a
compact
IRI
to
express
the
value
of
a
type.
The
@type
keyword
is
also
used
to
associate
a
type
with
a
node
.
The
concept
of
a
node
type
and
a
value
type
are
different.
A node type specifies the type of thing that is being described, like a person, place, event, or web page. A value type specifies the data type of a particular value, such as an integer, a floating point number, or a date.
{ ... "@id": "http://example.org/posts#TripToWestVirginia", "@type": "http://schema.org/BlogPosting", ← This is a node type "modified": { "@value": "2010-05-29T14:17:39+02:00", "@type": "http://www.w3.org/2001/XMLSchema#dateTime" ← This is a value type } ... }
The
first
use
of
@type
associates
a
node
type
(
http://schema.org/BlogPosting
)
with
the
node
,
which
is
expressed
using
the
@id
keyword
.
The
second
use
of
@type
associates
a
value
type
(
http://www.w3.org/2001/XMLSchema#dateTime
)
with
the
value
expressed
using
the
@value
keyword
.
As
a
general
rule,
when
@value
and
@type
are
used
in
the
same
JSON
object
,
the
@type
keyword
is
expressing
a
value
type
.
Otherwise,
the
@type
keyword
is
expressing
a
node
type
.
The
example
above
expresses
the
following
data:
Subject | Property | Value | Value Type |
---|---|---|---|
http://example.org/posts#TripToWestVirginia | rdf:type | schema:BlogPosting | - |
http://example.org/posts#TripToWestVirginia | dc:modified | 2010-05-29T14:17:39+02:00 | xsd:dateTime |
This section is non-normative.
JSON-LD supports the coercion of values to particular data types. Type coercion allows someone deploying JSON-LD to coerce the incoming or outgoing values to the proper data type based on a mapping of data type IRIs to terms . Using type coercion, value representation is preserved without requiring the data type to be specified with each piece of data.
Type
coercion
is
specified
within
an
expanded
term
definition
using
the
@type
key.
The
value
of
this
key
expands
to
an
IRI
.
Alternatively,
the
keyword
@id
or
@vocab
may
be
used
as
value
to
indicate
that
within
the
body
of
a
JSON-LD
document,
a
string
value
of
a
term
coerced
to
@id
or
@vocab
is
to
be
interpreted
as
an
IRI
.
The
difference
between
@id
and
@vocab
is
how
values
are
expanded
to
absolute
IRIs
.
@vocab
first
tries
to
expand
the
value
by
interpreting
it
as
term
.
If
no
matching
term
is
found
in
the
active
context
,
it
tries
to
expand
it
as
compact
IRI
or
absolute
IRI
if
there's
a
colon
in
the
value;
otherwise,
it
will
expand
the
value
using
the
active
context's
vocabulary
mapping
,
if
present.
Values
coerced
to
@id
in
contrast
are
expanded
as
compact
IRI
or
absolute
IRI
if
a
colon
is
present;
otherwise,
they
are
interpreted
as
relative
IRI
.
Terms
or
compact
IRIs
used
as
the
value
of
a
@type
key
may
be
defined
within
the
same
context.
This
means
that
one
may
specify
a
term
like
xsd
and
then
use
xsd:integer
within
the
same
context
definition.
The example below demonstrates how a JSON-LD author can coerce values to typed values and IRIs .
{ "@context": { "xsd": "http://www.w3.org/2001/XMLSchema#", "name": "http://xmlns.com/foaf/0.1/name", "age": { "@id": "http://xmlns.com/foaf/0.1/age", "@type": "xsd:integer" }, "homepage": { "@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id" } }, "@id": "http://example.com/people#john", "name": "John Smith", "age": "41", "homepage": [ "http://personal.example.org/", "http://work.example.com/jsmith/" ] }
The
example
shown
above
would
generate
the
following
data.
data:
Subject | Property | Value | Value Type |
---|---|---|---|
http://example.com/people#john | foaf:name | John Smith | |
http://example.com/people#john | foaf:age | 41 | xsd:integer |
http://example.com/people#john | foaf:homepage | http://personal.example.org/ | IRI |
http://work.example.com/jsmith/ | IRI |
Terms may also be defined using absolute IRIs or compact IRIs . This allows coercion rules to be applied to keys which are not represented as a simple term . For example:
{ "@context": { "foaf": "http://xmlns.com/foaf/0.1/", "foaf:age": { "@id": "http://xmlns.com/foaf/0.1/age", "@type": "xsd:integer" }, "http://xmlns.com/foaf/0.1/homepage": { "@type": "@id" } }, "foaf:name": "John Smith", "foaf:age": "41", "http://xmlns.com/foaf/0.1/homepage": [ "http://personal.example.org/", "http://work.example.com/jsmith/" ] }
In
this
case
the
@id
definition
in
the
term
definition
is
optional.
If
it
does
exist,
the
compact
IRI
or
IRI
representing
the
term
will
always
be
expanded
to
IRI
defined
by
the
@id
key—regardless
of
whether
a
prefix
is
defined
or
not.
Type
coercion
is
always
performed
using
the
unexpanded
value
of
the
key.
In
the
example
above,
that
means
that
type
coercion
is
done
looking
for
foaf:age
in
the
active
context
and
not
for
the
corresponding,
expanded
IRI
http://xmlns.com/foaf/0.1/age
.
Keys
in
the
context
are
treated
as
terms
for
the
purpose
of
expansion
and
value
coercion.
At
times,
this
may
result
in
multiple
representations
for
the
same
expanded
IRI
.
For
example,
one
could
specify
that
dog
and
cat
both
expanded
to
http://example.com/vocab#animal
.
Doing
this
could
be
useful
for
establishing
different
type
coercion
or
language
specification
rules.
It
also
allows
a
compact
IRI
(or
even
an
absolute
IRI
)
to
be
defined
as
something
else
entirely.
For
example,
one
could
specify
that
the
term
http://example.org/zoo
should
expand
to
http://example.org/river
,
but
this
usage
is
discouraged
because
it
would
lead
to
a
great
deal
of
confusion
among
developers
attempting
to
understand
the
JSON-LD
document.
This section is non-normative.
At
times,
it
is
important
to
annotate
a
string
with
its
language.
In
JSON-LD
this
is
possible
in
a
variety
of
ways.
First,
it
is
possible
to
define
a
default
language
for
a
JSON-LD
document
by
setting
the
@language
key
in
the
context
:
{ "@context": { ... "@language": "ja" }, "name": "花澄", "occupation": "科学者" }
The
example
above
would
associate
the
ja
language
code
with
the
two
strings
花澄
and
科学者
.
Languages
codes
are
defined
in
[
BCP47
].
The
default
language
applies
to
all
string
values
that
are
not
type
coerced
.
To
clear
the
default
language
for
a
subtree,
@language
can
be
set
to
null
in
a
local
context
as
follows:
{ "@context": { ... "@language": "ja" }, "name": "花澄", "details": { "@context": { "@language": null }, "occupation": "Ninja" } }
Second, it is possible to associate a language with a specific term using an expanded term definition :
{ "@context": { ... "ex": "http://example.com/vocab/", "@language": "ja", "name": { "@id": "ex:name", "@language": null }, "occupation": { "@id": "ex:occupation" }, "occupation_en": { "@id": "ex:occupation", "@language": "en" }, "occupation_cs": { "@id": "ex:occupation", "@language": "cs" } }, "name": "Yagyū Muneyoshi", "occupation": "忍者", "occupation_en": "Ninja", "occupation_cs": "Nindža", ... }
The
example
above
would
associate
忍者
with
the
specified
default
language
code
ja
,
Ninja
with
the
language
code
en
,
and
Nindža
with
the
language
code
cs
.
The
value
of
name
,
Yagyū
Muneyoshi
wouldn't
be
associated
with
any
language
code
since
@language
was
reset
to
null
in
the
expanded
term
definition
.
Language associations are only applied to plain strings . Typed values or values that are subject to type coercion are not language tagged.
Just as in the example above, systems often need to express the value of a property in multiple languages. Typically, such systems also try to ensure that developers have a programmatically easy way to navigate the data structures for the language-specific data. In this case, language maps may be utilized.
{ "@context": { ... "occupation": { "@id": "ex:occupation", "@container": "@language" } }, "name": "Yagyū Muneyoshi", "occupation": { "ja": "忍者", "en": "Ninja", "cs": "Nindža" } ... }
The
example
above
expresses
exactly
the
same
information
as
the
previous
example
but
consolidates
all
values
in
a
single
property.
To
access
the
value
in
a
specific
language
in
a
programming
language
supporting
dot-notation
accessors
for
object
properties,
a
developer
may
use
the
property.language
pattern.
For
example,
to
access
the
occupation
in
English,
a
developer
would
use
the
following
code
snippet:
obj.occupation.en
.
Third, it is possible to override the default language by using a value object :
{ "@context": { ... "@language": "ja" }, "name": "花澄", "occupation": { "@value": "Scientist", "@language": "en" } }
This
makes
it
possible
to
specify
a
plain
string
by
omitting
the
@language
tag
or
setting
it
to
null
when
expressing
it
using
a
value
object
:
{ "@context": { ... "@language": "ja" }, "name": { "@value": "Frank" }, "occupation": { "@value": "Ninja", "@language": "en" }, "speciality": "手裏剣" }
In
general,
normal
IRI
expansion
rules
apply
anywhere
an
IRI
is
expected
(see
See
section
3.2
9.6
IRIs
).
Within
a
context
definition,
this
can
mean
that
terms
defined
within
the
context
may
also
be
used
within
that
context
as
long
as
there
are
no
circular
dependencies.
For
example,
it
is
common
to
use
the
xsd
namespace
when
defining
typed
values
:
Example
44
:
IRI
expansion
within
a
context
Language
Maps
{
"@context": {
,
"name": "http://xmlns.com/foaf/0.1/name",
"age": {
"@id": "http://xmlns.com/foaf/0.1/age",
"@type":
},
"homepage": {
"@id": "http://xmlns.com/foaf/0.1/homepage",
"@type": "@id"
}
},
...
}
In
this
example,
the
xsd
term
is
defined
and
used
as
a
prefix
for
the
@type
coercion
of
the
age
property.
Terms
may
also
be
used
when
defining
the
IRI
of
another
term
:
Example
45
:
Using
a
term
to
define
the
IRI
of
another
term
within
a
context
{
"@context": {
,
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": ,
"age": {
"@id": ,
"@type": "xsd:integer"
},
"homepage": {
"@id": ,
"@type": "@id"
}
},
...
}
Compact
IRIs
and
IRIs
may
be
used
on
the
left-hand
side
description
of
a
term
definition.
Example
46
:
Using
a
compact
IRI
as
a
term
{
"@context": {
,
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": "foaf:name",
"": {
"@type": "xsd:integer"
},
"{
"@type": "@id"
}
},
...
}
In
this
example,
the
compact
IRI
form
is
used
in
two
different
ways.
In
the
first
approach,
foaf:age
declares
both
the
IRI
for
the
term
(using
short-form)
as
well
as
the
@type
associated
with
the
term
.
In
the
second
approach,
only
the
@type
associated
with
the
term
is
specified.
The
full
IRI
for
foaf:homepage
is
determined
by
looking
up
the
foaf
prefix
in
the
context
.
Absolute
IRIs
may
also
be
used
in
the
key
position
in
a
context
:
Example
47
:
Associating
context
definitions
with
absolute
IRIs
{
"@context": {
"foaf": "http://xmlns.com/foaf/0.1/",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"name": "foaf:name",
"foaf:age": {
"@id": "foaf:age",
"@type": "xsd:integer"
},
"": {
"@type": "@id"
}
},
...
}
In
order
for
the
absolute
IRI
to
match
above,
the
absolute
IRI
needs
to
be
used
in
the
JSON-LD
document
.
Also
note
that
foaf:homepage
will
not
use
the
{
"@type":
"@id"
}
declaration
because
foaf:homepage
is
not
the
same
as
http://xmlns.com/foaf/0.1/homepage
.
That
is,
terms
are
looked
up
in
a
context
using
direct
string
comparison
before
the
prefix
lookup
mechanism
is
applied.
Note
While
it
is
possible
to
define
a
compact
IRI
,
or
an
absolute
IRI
to
expand
to
some
other
unrelated
IRI
language
maps
(for
example,
foaf:name
expanding
to
http://example.org/unrelated#species
),
such
usage
is
strongly
discouraged.
The
only
exception
for
using
terms
in
the
context
is
that
circular
definitions
are
not
allowed.
That
is,
a
definition
of
term1
cannot
depend
on
set
the
definition
language
of
term2
if
term2
also
depends
on
term1
.
For
example,
the
following
context
definition
is
illegal:
mapped
values.
This section is non-normative.
A JSON-LD author can express multiple values in a compact way by using arrays . Since graphs do not describe ordering for links between nodes, arrays in JSON-LD do not provide an ordering of the contained elements by default. This is exactly the opposite from regular JSON arrays, which are ordered by default. For example, consider the following simple document:
{ ... "@id": "http://example.org/people#joebob", "foaf:nick": [ "joe", "bob", "JB" ], ... }
The example shown above would result in the following data being generated, each relating the node to an individual value, with no inherent order:
Subject | Property | Value |
---|---|---|
http://example.org/people#joebob | foaf:nick | joe |
http://example.org/people#joebob | foaf:nick | bob |
http://example.org/people#joebob | foaf:nick | JB |
Multiple values may also be expressed using the expanded form:
{
"@id": "http://example.org/articles/8",
"dc:title": [
{
"@value": "Das Kapital",
"@language": "de"
},
{
"@value": "Capital",
"@language": "en"
}
]
}
The example shown above would generate the following data, again with no inherent order:
Subject | Property | Value | Language |
---|---|---|---|
http://example.org/articles/8 | dc:title | Das Kapital | de |
http://example.org/articles/8 | dc:title | Capital | en |
Although multiple values of a property are typically of the same type, JSON-LD places no restriction on this, and a property may have values of different types:
{ "@id": "http://example.org/people#michael", "dc:name": [ "Michael", {"@value": "Mike"}, {"@value": "Miguel", "@language": "es"}, { "@id": "https://www.wikidata.org/wiki/Q4927524" }, 42 ] }
The example shown above would generate the following data, also with no inherent order:
Subject | Property | Value | Language | Value Type |
---|---|---|---|---|
http://example.org/people#michael | dc:name | Michael | ||
http://example.org/people#michael | dc:name | Mike | ||
http://example.org/people#michael | dc:name | Miguel | es | |
http://example.org/people#michael | dc:name | https://www.wikidata.org/wiki/Q4927524 | ||
http://example.org/people#michael | dc:name | 42 | xsd:integer |
This section is non-normative.
As
the
notion
of
ordered
collections
is
rather
important
in
data
modeling,
it
is
useful
to
have
specific
language
support.
In
JSON-LD,
a
list
may
be
represented
using
the
@list
keyword
as
follows:
{ ... "@id": "http://example.org/people#joebob", "foaf:nick": { "@list": [ "joe", "bob", "jaybee" ] }, ... }
This
describes
the
use
of
this
array
as
being
ordered,
and
order
is
maintained
when
processing
a
document.
If
every
use
of
a
given
multi-valued
property
is
a
list,
this
may
be
abbreviated
by
setting
@container
to
@list
in
the
context
:
{ "@context": { ... "nick": { "@id": "http://xmlns.com/foaf/0.1/nick", "@container": "@list" } }, ... "@id": "http://example.org/people#joebob", "nick": [ "joe", "bob", "jaybee" ], ... }
The
implementation
of
lists
in
RDF
depends
on
linking
anonymous
nodes
together
using
the
properties
rdf:first
and
rdf:rest
,
with
the
end
of
the
list
defined
as
the
resource
rdf:nil
.
This
can
be
represented
as
triples,
as
the
following
example
shows:
Subject | Property | Value |
---|---|---|
http://example.org/people#joebob | foaf:nick | _:b0 |
_:b0 | rdf:first | joe |
_:b0 | rdf:rest | _:b1 |
_:b1 | rdf:first | bob |
_:b1 | rdf:rest | _:b2 |
_:b2 | rdf:first | jaybee |
_:b2 | rdf:rest | rdf:nil |
JSON-LD provides a syntactic shortcut for these lists. In Turtle, the graph would be expressed as follows:
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<http://example.org/people#joebob>
foaf:nick
(
"joe"
"bob"
"jaybe"
)
.
In JSON-LD 1.1, lists of lists, where the value of a list object , may itself be a list object , are fully supported. For example, in GeoJSON (see [ RFC7946 ]), coordinates are an ordered list of positions , which are represented as an array of two or more numbers:
{ "type": "Feature", "bbox": [-10.0, -10.0, 10.0, 10.0], "geometry": { "type": "Polygon", "coordinates": [ [ [-10.0, -10.0], [10.0, -10.0], [10.0, 10.0], [-10.0, -10.0] ] ] } //... }
For these examples, it's important that values expressed within bbox and coordinates maintain their order, which requires the use of embedded list structures. In JSON-LD 1.1, we can express this using recursive lists, by simply adding the appropriate context definion:
{ "@context": { "@vocab": "https://purl.org/geojson/vocab#", "type": "@type", "bbox": {"@container": "@list"}, "coordinates": {"@container": "@list"} }, "type": "Feature", "bbox": [-10.0, -10.0, 10.0, 10.0], "geometry": { "type": "Polygon", "coordinates": [ [ [-10.0, -10.0], [10.0, -10.0], [10.0, 10.0], [-10.0, -10.0] ] ] } //... }
This is equivalent to the expanded form, which uses list objects :
[{ "@type": ["https://purl.org/geojson/vocab#Feature"], "https://purl.org/geojson/vocab#bbox": [{ "@list": [ {"@value": -10.0}, {"@value": -10.0}, {"@value": 10.0}, {"@value": 10.0} ] }], "https://purl.org/geojson/vocab#geometry": [{ "@type": ["https://purl.org/geojson/vocab#Polygon"], "https://purl.org/geojson/vocab#coordinates": [{ "@list": [{ "@list": [ {"@list": [{"@value": -10.0}, {"@value": -10.0}]}, {"@list": [{"@value": 10.0}, {"@value": -10.0}]}, {"@list": [{"@value": 10.0}, {"@value": 10.0}]}, {"@list": [{"@value": -10.0}, {"@value": -10.0}]} ] }] }] }] }]
Note that coordinates includes three levels of lists. When expressed in Turtle, this would be the following:
Values
of
terms
associated
with
an
@list
container
are
always
represented
in
the
form
of
an
array
,
even
if
there
is
just
a
single
value
or
no
value
at
all.
This section is non-normative.
While
@list
is
used
to
describe
ordered
lists
,
the
@set
keyword
is
used
to
describe
unordered
sets
.
The
use
of
@set
in
the
body
of
a
JSON-LD
document
is
optimized
away
when
processing
the
document,
as
it
is
just
syntactic
sugar.
However,
@set
is
helpful
when
used
within
the
context
of
a
document.
Values
of
terms
associated
with
an
@set
or
@list
container
are
always
represented
in
the
form
of
an
array
,
even
if
there
is
just
a
single
value
that
would
otherwise
be
optimized
to
a
non-array
form
in
compact
form
(see
section
4.26
5.2
Compacted
Document
Form
).
This
makes
post-processing
of
JSON-LD
documents
easier
as
the
data
is
always
in
array
form,
even
if
the
array
only
contains
a
single
value.
{ ... "@id": "http://example.org/people#joebob", "foaf:nick": { "@set": [ "joe", "bob", "jaybee" ] }, ... }
This
describes
the
use
of
this
array
as
being
unordered,
and
order
is
maintained
when
processing
a
document.
By
default,
arrays
of
values
are
unordered,
but
this
may
be
made
explicit
by
setting
@container
to
@set
in
the
context
:
{ "@context": { ... "nick": { "@id": "http://xmlns.com/foaf/0.1/nick", "@container": "@set" } }, ... "@id": "http://example.org/people#joebob", "nick": [ "joe", "bob", "jaybee" ], ... }
Since
JSON-LD
1.1,
the
@set
keyword
may
be
combined
with
other
container
specifications
within
an
expanded
term
definition
to
similarly
cause
compacted
values
of
indexes
to
be
consistently
represented
using
arrays.
See
section
4.6
Indexed
Values
for
a
further
discussion.
This section is non-normative.
Many
JSON
APIs
separate
properties
from
their
entities
using
an
intermediate
object;
in
JSON-LD
serializes
directed
graphs
these
are
called
nested
properties
.
That
means
that
every
property
points
from
For
example,
a
node
set
of
possible
labels
may
be
grouped
under
a
common
property:
{ "@context": { "@version": 1.1, "skos": "http://www.w3.org/2004/02/skos/core#", "labels": "@nest", "main_label": {"@id": "skos:prefLabel"}, "other_label": {"@id": "skos:altLabel"}, "homepage": {"@id": "http://schema.org/description", "@type": "@id"} }, "@id": "http://example.org/myresource", "homepage": "http://example.org", "labels": { "main_label": "This is the main label for my resource", "other_label": "This is the other label" } }
By
defining
labels
using
the
keyword
to
another
node
@nest
,
a
JSON-LD
processor
or
value
.
However,
in
some
cases,
it
is
desirable
to
serialize
in
will
ignore
the
reverse
direction.
Consider
for
example
nesting
created
by
using
the
case
where
a
person
labels
property
and
its
children
should
be
described
in
a
document.
If
process
the
contents
as
if
it
were
declared
directly
within
containing
object.
In
this
case,
the
used
vocabulary
does
not
provide
a
children
labels
property
is
semantically
meaningless.
Defining
it
as
equivalent
to
@nest
causes
it
to
be
ignored
when
expanding,
making
it
equivalent
to
the
following:
{
"@context": {
"skos": "http://www.w3.org/2004/02/skos/core#",
"main_label": {"@id": "skos:prefLabel"},
"other_label": {"@id": "skos:altLabel"},
"homepage": {"@id": "http://schema.org/description", "@type": "@id"}
},
"@id": "http://example.org/myresource",
"homepage": "http://example.org",
"main_label": "This is the main label for my resource",
"other_label": "This is the other label"
}
Similarly,
node
objects
may
contain
a
@nest
property
to
reference
a
term
aliased
to
@nest
which
causes
such
values
to
be
nested
under
that
aliased
term.
{ "@context": { "@version": 1.1, "skos": "http://www.w3.org/2004/02/skos/core#", "labels": "@nest", "main_label": {"@id": "skos:prefLabel", "@nest": "labels"}, "other_label": {"@id": "skos:altLabel", "@nest": "labels"}, "homepage": {"@id": "http://schema.org/description", "@type": "@id"} }, "@id": "http://example.org/myresource", "homepage": "http://example.org", "labels": { "main_label": "This is the main label for my resource", "other_label": "This is the other label" } }
Nested
properties
but
just
are
a
new
feature
in
JSON-LD
1.1,
requiring
processing
mode
set
to
json-ld-1.1
.
parent
This
section
is
non-normative.
Embedding
is
a
JSON-LD
feature
that
allows
an
author
to
use
node
objects
as
property
,
every
node
representing
values.
This
is
a
child
would
have
to
be
expressed
with
commonly
used
mechanism
for
creating
a
property
parent-child
relationship
between
two
nodes
.
Without
embedding,
node
objects
pointing
to
the
parent
as
in
can
be
linked
by
referencing
the
following
example.
identifier
of
another
node
object
.
For
example:
{ "@context": { "@vocab": "http://schema.org/", "knows": {"@type": "@id"} }, "@graph": [{ "name": "Manu Sporny", "@type": "Person", "knows": "http://greggkellogg.net/foaf#me" }, {"@id": "#lisa", "http://example.com/vocab#name": "Lisa", } ]"@id": "http://greggkellogg.net/foaf#me", "@type": "Person", "name": "Gregg Kellogg" }] }
Expressing
such
data
is
much
simpler
by
using
JSON-LD's
The
previous
example
describes
two
node
objects
,
for
Manu
and
Gregg,
with
the
@reverse
knows
keyword
:
property
defined
to
treat
string
values
as
identifiers.
Embedding
allows
the
node
object
for
Gregg
to
be
embedded
as
a
value
of
the
knows
property:
{"@id": "#homer", "http://example.com/vocab#name": "Homer", : { : [ { "@id": "#bart", "http://example.com/vocab#name": "Bart" }, { "@id": "#lisa", "http://example.com/vocab#name": "Lisa" } ] }"@context": { "@vocab": "http://schema.org/" }, "name": "Manu Sporny", "knows": { "@id": "http://greggkellogg.net/foaf#me", "@type": "Person", "name": "Gregg Kellogg" } }
The
@reverse
keyword
can
also
A
node
object
,
like
the
one
used
above,
may
be
used
in
expanded
term
definitions
any
value
position
in
the
body
of
a
JSON-LD
document.
Note
that
type
coercion
to
create
reverse
properties
of
the
knows
property
is
not
required,
as
shown
the
value
is
not
a
string.
While
it
is
considered
a
best
practice
to
identify
nodes
in
a
graph,
at
times
this
is
impractical.
In
the
following
example:
data
model,
nodes
without
an
explicit
identifier
are
called
blank
nodes
,
which
can
be
represented
in
a
serialization
such
as
JSON-LD
using
a
blank
node
identifier
.
In
the
previous
example,
the
top-level
node
for
Manu
does
not
have
an
identifier,
and
does
not
need
one
to
describe
it
within
the
data
model.
However,
if
we
were
to
want
to
describe
a
knows
relationship
from
Gregg
to
Manu,
we
would
need
to
introduce
a
blank
node
identifier
(here
_:b0
).
{"@context": { "name": "http://example.com/vocab#name","@context": { "@vocab": "http://schema.org/" },"@id": "#homer", "name": "Homer", : [ { "@id": "#bart", "name": "Bart" }, { "@id": "#lisa", "name": "Lisa" } ]"@id": "_:b0", "name": "Manu Sporny", "knows": { "@id": "http://greggkellogg.net/foaf#me", "@type": "Person", "name": "Gregg Kellogg", "knows": {"@id": "_:b0"} } }
Blank node identifiers may be automatically introduced by algorithms such as flattening , but they are also useful for authors to describe such relationships directly.
This section is non-normative.
An
expanded
term
definition
At
times,
it
becomes
necessary
to
be
able
to
express
information
without
being
able
to
uniquely
identify
the
node
can
include
with
an
IRI
.
This
type
of
node
is
called
a
blank
node
.
JSON-LD
does
not
require
all
nodes
to
be
identified
using
.
However,
some
graph
topologies
may
require
identifiers
to
be
serializable.
Graphs
containing
loops,
e.g.,
cannot
be
serialized
using
embedding
alone,
@context
@id
@id
property,
must
be
used
to
connect
the
nodes.
In
these
situations,
one
can
use
blank
node
identifiers
,
which
defines
a
context
look
like
IRIs
(an
embedded
context
using
an
underscore
(
_
)
for
values
as
scheme.
This
allows
one
to
reference
the
node
locally
within
the
document,
but
makes
it
impossible
to
reference
the
node
from
an
external
document.
The
blank
node
identifier
of
properties
defined
using
is
scoped
to
the
document
in
which
it
is
used.
{ ... "@id": "_:n1", "name": "Secret Agent 1", "knows": { "name": "Secret Agent 2", "knows": { "@id": "_:n1" } } }
The
example
above
contains
information
about
two
secret
agents
that
term
cannot
be
identified
with
an
IRI
.
While
expressing
that
agent 1
knows
agent 2
is
possible
without
using
blank
node
identifiers
,
it
is
necessary
to
assign
agent 1
an
identifier
so
that
it
can
be
referenced
from
agent 2
.
It is worth noting that blank node identifiers may be relabeled during processing. If a developer finds that they refer to the blank node more than once, they should consider naming the node using a dereferenceable IRI so that it can also be referenced from other documents.
This
allows
section
is
non-normative.
Sometimes
multiple
property
values
need
to
be
accessed
in
a
more
direct
fashion
than
iterating
though
multiple
array
values.
JSON-LD
provides
an
indexing
mechanism
to
allow
the
use
term
definitions
of
an
intermediate
dictionary
to
associate
specific
indexes
with
associated
values.
See section 4.8 Named Graphs for other uses of indexing in JSON-LD.
This section is non-normative.
Databases are typically used to make access to data more efficient. Developers often extend this sort of functionality into their application data to deliver similar performance gains. Often this data does not have any meaning from a Linked Data standpoint, but is still useful for an application.
JSON-LD
introduces
the
context
notion
of
index
maps
was
that
can
be
used
to
structure
data
into
a
form
that
is
more
efficient
to
access.
The
data
indexing
feature
allows
an
author
to
structure
data
using
a
simple
key-value
map
where
the
keys
do
not
map
to
IRIs
.
This
enables
direct
access
to
data
instead
of
having
to
scan
an
array
in
search
of
a
specific
item.
In
JSON-LD
such
data
can
be
specified
within
by
associating
the
value
itself.
@index
keyword
with
a
@container
declaration
in
the
context:
{ "@context": {, "name": "http://schema.org/name", "interest": { "@id": "http://xmlns.com/foaf/0.1/interest","schema": "http://schema.org/", "name": "schema:name", "body": "schema:articleBody", "words": "schema:wordCount", "post": { "@id": "schema:blogPost", "@container": "@index" } },"name": "Manu Sporny", "interest": { "@id": "https://www.w3.org/TR/json-ld/", "name": "JSON-LD", "topic": "Linking Data" }"@id": "http://example.com/", "@type": "schema:Blog", "name": "World Financial News", "post": { "en": { "@id": "http://example.com/posts/1/en", "body": "World commodities were up today with heavy trading of crude oil...", "words": 1539 }, "de": { "@id": "http://example.com/posts/1/de", "body": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl...", "words": 1204 } } }
In
this
case,
the
social
profile
is
defined
using
example
above,
the
schema.org
vocabulary,
but
interest
is
imported
from
FOAF,
post
term
has
been
marked
as
an
index
map
.
The
en
and
is
used
to
define
de
keys
will
be
ignored
semantically,
but
preserved
syntactically,
by
the
JSON-LD
Processor
.
This
allows
a
node
describing
one
developer
to
access
the
German
version
of
Manu's
interests
where
those
properties
now
come
from
the
FOAF
vocabulary.
post
using
the
following
code
snippet:
obj.post.de
.
Expanding
this
document,
uses
a
combination
The
interpretation
of
terms
defined
the
data
above
is
expressed
in
the
outer
context,
table
below.
Note
how
the
index
keys
do
not
appear
in
the
Linked
Data
below,
but
would
continue
to
exist
if
the
document
were
compacted
or
expanded
(see
section
5.2
Compacted
Document
Form
and
those
defined
specifically
for
section
5.1
Expanded
Document
Form
)
using
a
JSON-LD
processor
:
Subject | Property | Value |
---|---|---|
http://example.com/ | rdf:type | schema:Blog |
http://example.com/ | schema:name | World Financial News |
http://example.com/ | schema:blogPost | http://example.com/posts/1/en |
http://example.com/ | schema:blogPost | http://example.com/posts/1/de |
http://example.com/posts/1/en | schema:articleBody | World commodities were up today with heavy trading of crude oil... |
http://example.com/posts/1/en | schema:wordCount | 1539 |
http://example.com/posts/1/de | schema:articleBody | Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl... |
http://example.com/posts/1/de | schema:wordCount | 1204 |
The
value
of
@container
can
also
be
an
array
containing
both
@index
and
@set
.
When
compacting
,
this
ensures
that
term
a
JSON-LD
Processor
will
use
the
array
form
for
all
values
of
indexes.
{ "@context": { "@version": 1.1, "schema": "http://schema.org/", "name": "schema:name", "body": "schema:articleBody", "words": "schema:wordCount", "post": { "@id": "schema:blogPost", "@container": ["@index", "@set"] } }, "@id": "http://example.com/", "@type": "schema:Blog", "name": "World Financial News", "post": { "en": [{ "@id": "http://example.com/posts/1/en", "body": "World commodities were up today with heavy trading of crude oil...", "words": 1539 }], "de": [{ "@id": "http://example.com/posts/1/de", "body": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl...", "words": 1204 }] } }
If
the
processing
mode
is
set
to
json-ld-1.1
,
the
special
index
@none
is
used
for
indexing
data
which
does
not
have
an
embedded
context
.
associated
index,
which
is
useful
to
maintain
a
normalized
representation.
{ "@context": { "schema": "http://schema.org/", "name": "schema:name", "body": "schema:articleBody", "words": "schema:wordCount", "post": { "@id": "schema:blogPost", "@container": "@index" } }, "@id": "http://example.com/", "@type": "schema:Blog", "name": "World Financial News", "post": { "en": { "@id": "http://example.com/posts/1/en", "body": "World commodities were up today with heavy trading of crude oil...", "words": 1539 }, "de": { "@id": "http://example.com/posts/1/de", "body": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl...", "words": 1204 }, "@none": { "@id": "http://example.com/posts/1/no-language", "body": "Unindexed description", "words": 20 } } }
Scoping
can
also
This
section
is
non-normative.
JSON
which
includes
string
values
in
multiple
languages
may
be
performed
represented
using
a
language
map
to
allow
for
easily
indexing
property
values
by
language
tag
.
This
enables
direct
access
to
language
values
instead
of
having
to
scan
an
array
in
search
of
a
specific
item.
In
JSON-LD
such
data
can
be
specified
by
associating
the
@language
keyword
with
a
@container
declaration
in
the
context:
{ "@context": { "vocab": "http://example.com/vocab/", "label": { "@id": "vocab:label", "@container": "@language"
}
},
"@id": "http://example.com/queen", "label": { "en": "The Queen", "de": [ "Die Königin", "Ihre Majestät" ]
}
}
In
the
example
above,
the
label
term
used
has
been
marked
as
an
language
map
.
The
en
and
de
keys
are
implicitly
associated
with
their
respective
values
by
the
JSON-LD
Processor
.
This
allows
a
developer
to
access
the
German
version
of
the
label
using
the
following
code
snippet:
obj.label.de
.
The
value
of
can
also
be
an
array
containing
both
@type
:
@container
@language
and
@set
.
When
compacting
,
this
ensures
that
a
JSON-LD
Processor
will
use
the
array
form
for
all
values
of
language
tags.
{ "@context": {, "name": "http://schema.org/name", "interest": "http://xmlns.com/foaf/0.1/interest", : { "@id": "http://xmlns.com/foaf/0.1/Document","vocab": "http://example.com/vocab/", "label": { "@id": "vocab:label", "@container": ["@language", "@set"] } },"@type": "Person", "name": "Manu Sporny", "interest": { "@id": "https://www.w3.org/TR/json-ld/", , "name": "JSON-LD", "topic": "Linking Data""@id": "http://example.com/queen", "label": { "en": ["The Queen"], "de": [ "Die Königin", "Ihre Majestät" ] } }
If
the
processing
mode
is
set
to
,
the
special
index
@type
json-ld-1.1
@none
is
useful
when
common
properties
are
used
for
indexing
data
which
does
not
have
a
language,
which
is
useful
to
relate
things
maintain
a
normalized
representation.
{ "@context": { "vocab": "http://example.com/vocab/", "label": { "@id": "vocab:label", "@container": "@language" } }, "@id": "http://example.com/queen", "label": { "en": "The Queen", "de": [ "Die Königin", "Ihre Majestät" ], "@none": "The Queen" } }
This section is non-normative.
In
addition
to
index
maps
,
JSON-LD
introduces
the
notion
of
different
types,
id
maps
for
structuring
data.
The
id
indexing
feature
allows
an
author
to
structure
data
using
a
simple
key-value
map
where
the
vocabularies
keys
map
to
IRIs
.
This
enables
direct
access
to
associated
node
objects
instead
of
having
to
scan
an
array
in
use
within
different
entities
calls
for
different
context
scoping.
For
example,
search
of
a
specific
item.
In
JSON-LD
such
data
can
be
specified
by
associating
the
hasPart
@id
/
keyword
with
a
partOf
@container
may
be
common
terms
used
declaration
in
a
document,
but
mean
different
things
depending
on
the
context.
context:
{ "@context": { "@version": 1.1, "schema": "http://schema.org/", "name": "schema:name", "body": "schema:articleBody", "words": "schema:wordCount", "post": { "@id": "schema:blogPost", "@container": "@id" } }, "@id": "http://example.com/", "@type": "schema:Blog", "name": "World Financial News", "post": { "http://example.com/posts/1/en": { "body": "World commodities were up today with heavy trading of crude oil...", "words": 1539 }, "http://example.com/posts/1/de": { "body": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl...", "words": 1204 } } }
When
expanding,
each
value
of
In
the
example
above,
the
@type
post
is
considered
(ordering
them
lexographically)
where
that
value
is
also
a
term
in
the
active
context
having
its
own
embedded
context
has
been
marked
as
an
id
map
.
If
so,
that
embedded
context
is
applied
to
The
http://example.com/posts/1/en
and
http://example.com/posts/1/de
keys
will
be
interpreted
as
the
active
context
.
When
compacting,
if
a
term
@id
property
of
the
node
object
value.
The
interpretation
of
the
data
above
is
chosen
to
represent
an
IRI
used
exactly
the
same
as
that
in
section
4.6.1
Data
Indexing
using
a
JSON-LD
processor
.
The
value
of
@type
@container
where
that
term
definition
can
also
has
be
an
embedded
context
,
it
is
then
applied
to
array
containing
both
@id
and
@set
.
When
compacting
,
this
ensures
that
a
JSON-LD
processor
will
use
the
active
context
array
to
affect
further
compaction.
form
for
all
values
of
node
identifiers.
{ "@context": { "@version": 1.1, "schema": "http://schema.org/", "name": "schema:name", "body": "schema:articleBody", "words": "schema:wordCount", "post": { "@id": "schema:blogPost", "@container": ["@id", "@set"] } }, "@id": "http://example.com/", "@type": "schema:Blog", "name": "World Financial News", "post": { "http://example.com/posts/1/en": [{ "body": "World commodities were up today with heavy trading of crude oil...", "words": 1539 }], "http://example.com/posts/1/de": [{ "body": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl...", "words": 1204 }] } }
The
values
of
special
index
@type
@none
are
unordered,
so
if
multiple
types
are
listed,
the
order
that
scoped
contexts
are
applied
is
based
on
lexicographical
ordering.
used
for
indexing
node
objects
which
do
not
have
an
@id
,
which
is
useful
to
maintain
a
normalized
representation.
The
@none
index
may
also
be
a
term
which
expands
to
@none
,
such
as
the
term
none
used
in
the
example
below.
{ "@context": { "@version": 1.1, "schema": "http://schema.org/", "name": "schema:name", "body": "schema:articleBody", "words": "schema:wordCount", "post": { "@id": "schema:blogPost", "@container": "@id" }, "none": "@none" }, "@id": "http://example.com/", "@type": "schema:Blog", "name": "World Financial News", "post": { "http://example.com/posts/1/en": { "body": "World commodities were up today with heavy trading of crude oil...", "words": 1539 }, "http://example.com/posts/1/de": { "body": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl...", "words": 1204 }, "none": { "body": "Description for object within an @id", "words": 20 } } }
If
a
term
Id
maps
defines
are
a
scoped
context,
and
then
that
term
new
feature
in
JSON-LD
1.1,
requiring
processing
mode
set
to
json-ld-1.1
.
This
section
is
later
re-defined,
non-normative.
In
addition
to
id
and
index
maps
,
JSON-LD
introduces
the
association
notion
of
type
maps
for
structuring
data.
The
type
indexing
feature
allows
an
author
to
structure
data
using
a
simple
key-value
map
where
the
context
defined
keys
map
to
IRIs
.
This
enables
data
to
be
structured
based
on
the
@type
of
specific
node
objects
.
In
JSON-LD
such
data
can
be
specified
by
associating
the
@type
keyword
with
a
@container
declaration
in
the
earlier
expanded
context:
{ "@context": { "@version": 1.1, "schema": "http://schema.org/", "name": "schema:name", "affiliation": { "@id": "schema:affiliation", "@container": "@type" } }, "name": "Manu Sporny", "affiliation": { "schema:Corporation": { "@id": "https://digitalbazaar.com/", "name": "Digital Bazaar" }, "schema:ProfessionalService": { "@id": "https://spec-ops.io", "name": "Spec-Ops" } } }
In
the
example
above,
the
affiliation
term
definition
is
lost
within
has
been
marked
as
an
type
map
.
The
schema:Corporation
and
schema:ProfessionalService
keys
will
be
interpreted
as
the
scope
@type
property
of
the
node
object
value.
The
value
of
@container
can
also
be
an
array
containing
both
@type
and
@set
.
When
compacting
,
this
ensures
that
re-definition.
This
is
consistent
with
term
definitions
a
JSON-LD
processor
will
use
the
array
form
for
all
values
of
types.
{ "@context": { "@version": 1.1, "schema": "http://schema.org/", "name": "schema:name", "affiliation": { "@id": "schema:affiliation", "@container": ["@type", "@set"] } }, "name": "Manu Sporny", "affiliation": { "schema:Corporation": [{ "@id": "https://digitalbazaar.com/", "name": "Digital Bazaar" }], "schema:ProfessionalService": [{ "@id": "https://spec-ops.io", "name": "Spec-Ops" }] } }
The
special
index
@none
is
used
for
indexing
node
objects
which
do
not
have
an
@type
,
which
is
useful
to
maintain
a
normalized
representation.
The
@none
index
may
also
be
a
term
overriding
previous
term
definitions
from
earlier
less
deeply
nested
definitions,
which
expands
to
@none
,
such
as
discussed
the
term
none
used
in
section
4.8
the
example
below.
{ "@context": { "@version": 1.1, "schema": "http://schema.org/", "name": "schema:name", "affiliation": { "@id": "schema:affiliation", "@container": "@type" }, "none": "@none" }, "name": "Manu Sporny", "affiliation": { "schema:Corporation": { "@id": "https://digitalbazaar.com/", "name": "Digital Bazaar" }, "schema:ProfessionalService": { "@id": "https://spec-ops.io", "name": "Spec-Ops" }, "none": { "@id": "http://greggkellogg.net/", "name": "Gregg Kellogg" } } }
As
with
id
maps
,
when
used
with
@type
,
a
container
may
also
include
@set
to
ensure
that
key
values
are
always
contained
in
an
array.
Scoped
Contexts
Type
maps
are
a
new
feature
in
JSON-LD
1.1,
requiring
processing
mode
set
to
json-ld-1.1
.
This section is non-normative.
JSON-LD serializes directed graphs . That means that every property points from a node to another node or value . However, in some cases, it is desirable to serialize in the reverse direction. Consider for example the case where a person and its children should be described in a document. If the used vocabulary does not provide a children property but just a parent property , every node representing a child would have to be expressed with a property pointing to the parent as in the following example.
[ { "@id": "#homer", "http://example.com/vocab#name": "Homer" }, { "@id": "#bart", "http://example.com/vocab#name": "Bart", "http://example.com/vocab#parent": { "@id": "#homer" } }, { "@id": "#lisa", "http://example.com/vocab#name": "Lisa", "http://example.com/vocab#parent": { "@id": "#homer" } } ]
Expressing
such
data
is
much
simpler
by
using
JSON-LD's
@reverse
keyword
:
{ "@id": "#homer", "http://example.com/vocab#name": "Homer", "@reverse": { "http://example.com/vocab#parent": [ { "@id": "#bart", "http://example.com/vocab#name": "Bart" }, { "@id": "#lisa", "http://example.com/vocab#name": "Lisa" } ] } }
The
@reverse
keyword
can
also
be
used
in
expanded
term
definitions
to
create
reverse
properties
as
shown
in
the
following
example:
{ "@context": { "name": "http://example.com/vocab#name", "children": { "@reverse": "http://example.com/vocab#parent" } }, "@id": "#homer", "name": "Homer", "children": [ { "@id": "#bart", "name": "Bart" }, { "@id": "#lisa", "name": "Lisa" } ] }
This section is non-normative.
At
times,
it
is
necessary
to
make
statements
about
a
graph
itself,
rather
than
just
a
single
node
.
This
can
be
done
by
grouping
a
set
of
nodes
using
the
@graph
keyword
.
A
developer
may
also
name
data
expressed
using
the
@graph
keyword
by
pairing
it
with
an
@id
keyword
as
shown
in
the
following
example:
{
"@context": {
"generatedAt": {
"@id": "http://www.w3.org/ns/prov#generatedAtTime",
"@type": "http://www.w3.org/2001/XMLSchema#date"
},
"Person": "http://xmlns.com/foaf/0.1/Person",
"name": "http://xmlns.com/foaf/0.1/name",
"knows": "http://xmlns.com/foaf/0.1/knows"
},
"@id": "http://example.org/foaf-graph",
"generatedAt": "2012-04-09",
"@graph": [
{
"@id": "http://manu.sporny.org/about#manu",
"@type": "Person",
"name": "Manu Sporny",
"knows": "http://greggkellogg.net/foaf#me"
}, {
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": "http://manu.sporny.org/about#manu"
}
]
}
The
example
above
expresses
a
named
graph
that
is
identified
by
the
IRI
http://example.org/foaf-graph
.
That
graph
is
composed
of
the
statements
about
Manu
and
Gregg.
Metadata
about
the
graph
itself
is
expressed
via
the
generatedAt
property,
which
specifies
when
the
graph
was
generated.
An
alternative
view
of
the
information
above
is
represented
in
table
form
below:
Graph | Subject | Property | Value | Value Type |
---|---|---|---|---|
http://example.org/foaf-graph | prov:generatedAtTime | 2012-04-09 | xsd:date | |
http://example.org/foaf-graph | http://manu.sporny.org/about#manu | xsd:type | foaf:Person | |
http://example.org/foaf-graph | http://manu.sporny.org/about#manu | foaf:name | Manu Sporny | |
http://example.org/foaf-graph | http://manu.sporny.org/about#manu | foaf:knows | http://greggkellogg.net/foaf#me | |
http://example.org/foaf-graph | http://greggkellogg.net/foaf#me | xsd:type | foaf:Person | |
http://example.org/foaf-graph | http://greggkellogg.net/foaf#me | foaf:name | Gregg Kellogg | |
http://example.org/foaf-graph | http://greggkellogg.net/foaf#me | foaf:knows | http://manu.sporny.org/about#manu |
When
a
JSON-LD
document's
top-level
structure
is
an
object
that
contains
no
other
properties
than
@graph
and
optionally
@context
(properties
that
are
not
mapped
to
an
IRI
or
a
keyword
are
ignored),
@graph
is
considered
to
express
the
otherwise
implicit
default
graph
.
This
mechanism
can
be
useful
when
a
number
of
nodes
exist
at
the
document's
top
level
that
share
the
same
context
,
which
is,
e.g.,
the
case
when
a
document
is
flattened
.
The
@graph
keyword
collects
such
nodes
in
an
array
and
allows
the
use
of
a
shared
context.
{ "@context": {...}, "@graph": [ { "@id": "http://manu.sporny.org/about#manu", "@type": "foaf:Person", "name": "Manu Sporny", "knows": "http://greggkellogg.net/foaf#me" }, { "@id": "http://greggkellogg.net/foaf#me", "@type": "foaf:Person", "name": "Gregg Kellogg", "knows": "http://manu.sporny.org/about#manu" } ] }
In
this
case,
embedding
doesn't
work
as
each
node
object
references
the
other.
This
is
equivalent
to
using
multiple
node
objects
in
array
and
defining
the
@context
within
each
node
object
:
[ { "@context": {...}, "@id": "http://manu.sporny.org/about#manu", "@type": "foaf:Person", "name": "Manu Sporny", "knows": "http://greggkellogg.net/foaf#me" }, { "@context": {...}, "@id": "http://greggkellogg.net/foaf#me", "@type": "foaf:Person", "name": "Gregg Kellogg", "knows": "http://manu.sporny.org/about#manu" } ]
In
some
cases,
it
is
useful
to
logically
partition
data
into
separate
graphs,
without
making
this
explicit
within
the
JSON
expression.
For
example,
a
JSON
document
may
contain
data
against
which
other
metadata
is
asserted
and
it
is
useful
to
separate
this
data
in
the
data
model
using
the
notion
of
named
graphs
,
without
the
syntactic
overhead
associated
with
the
@graph
keyword.
An
expanded
term
definition
can
use
@graph
as
the
value
of
@container
.
This
indicates
that
values
of
this
term
should
be
considered
to
be
named
graphs
,
where
the
graph
name
is
an
automatically
assigned
blank
node
identifier
creating
an
implicitly
named
graph
.
When
expanded,
these
become
simple
graph
objects
.
An alternative to our example above could use an anonymously named graph as follows:
{ "@context": { "@version": 1.1, "generatedAt": { "@id": "http://www.w3.org/ns/prov#generatedAtTime", "@type": "http://www.w3.org/2001/XMLSchema#date" }, "Person": "http://xmlns.com/foaf/0.1/Person", "name": "http://xmlns.com/foaf/0.1/name", "knows": "http://xmlns.com/foaf/0.1/knows", "claim": { "@id": "https://w3id.org/credentials#claim", "@container": "@graph" } }, "@id": "http://example.org/foaf-graph", "generatedAt": "2012-04-09", "claim": [ { "@id": "http://manu.sporny.org/about#manu", "@type": "Person", "name": "Manu Sporny", "knows": "http://greggkellogg.net/foaf#me" }, { "@id": "http://greggkellogg.net/foaf#me", "@type": "Person", "name": "Gregg Kellogg", "knows": "http://manu.sporny.org/about#manu" } ] }
The
example
above
expresses
a
named
graph
that
is
identified
by
the
blank
node
identifier
_:b0
.
That
graph
is
composed
of
the
statements
about
Manu
and
Gregg.
Metadata
about
the
graph
itself
is
expressed
via
the
generatedAt
property,
which
specifies
when
the
graph
was
generated.
An
alternative
view
of
the
information
above
is
represented
in
table
form
below:
Graph | Subject | Property | Value | Value Type |
---|---|---|---|---|
http://example.org/foaf-graph | prov:generatedAtTime | 2012-04-09 | xsd:date | |
http://example.org/foaf-graph | cred:claim | _:b0 | ||
_:b0 | http://manu.sporny.org/about#manu | xsd:type | foaf:Person | |
_:b0 | http://manu.sporny.org/about#manu | foaf:name | Manu Sporny | |
_:b0 | http://manu.sporny.org/about#manu | foaf:knows | http://greggkellogg.net/foaf#me | |
_:b0 | http://greggkellogg.net/foaf#me | xsd:type | foaf:Person | |
_:b0 | http://greggkellogg.net/foaf#me | foaf:name | Gregg Kellogg | |
_:b0 | http://greggkellogg.net/foaf#me | foaf:knows | http://manu.sporny.org/about#manu |
The
blank
node
identifier
_:b0
is
automatically
created
to
allow
the
default
graph
to
reference
the
named
graph
as
the
definition
of
the
claim
.
These
are
necessary
for
serialization,
where
nodes
without
explicit
identifiers,
such
as
the
named
graph
in
this
case,
can
be
represented.
Expanding this graph results in the following:
[{ "http://www.w3.org/ns/prov#generatedAtTime": [{ "@value": "2012-04-09", "@type": "http://www.w3.org/2001/XMLSchema#date" }], "@id": "http://example.org/foaf-graph", "https://w3id.org/credentials#claim": [{ "@graph": [{ "@id": "http://manu.sporny.org/about#manu", "@type": ["http://xmlns.com/foaf/0.1/Person"], "http://xmlns.com/foaf/0.1/knows": [{ "@value": "http://greggkellogg.net/foaf#me" }], "http://xmlns.com/foaf/0.1/name": [{ "@value": "Manu Sporny" }] }, { "@id": "http://greggkellogg.net/foaf#me", "@type": ["http://xmlns.com/foaf/0.1/Person"], "http://xmlns.com/foaf/0.1/knows": [{ "@value": "http://manu.sporny.org/about#manu" }], "http://xmlns.com/foaf/0.1/name": [{ "@value": "Gregg Kellogg" }] }] }] }]
Strictly speaking, the value of such a term is not a named graph , rather it is the graph name associated with the named graph , which exists separately within the dataset .
Graph
Containers
are
a
new
feature
in
JSON-LD
1.1,
requiring
processing
mode
set
to
json-ld-1.1
.
In
addition
to
indexing
node
objects
by
index,
graph
objects
may
also
be
indexed
by
an
index.
By
using
the
@graph
container
type,
introduced
in
section
4.15.1
4.8.1
Graph
Containers
in
addition
to
@index
,
an
object
value
of
such
a
property
is
treated
as
a
key-value
map
where
the
keys
do
not
map
to
IRIs
,
but
are
taken
from
an
@index
property
associated
with
named
graphs
which
are
their
values.
When
expanded,
these
must
be
simple
graph
objects
The following example describes a default graph referencing multiple named graphs using an index map .
{ "@context": { "@version": 1.1, "schema": "http://schema.org/", "name": "schema:name", "body": "schema:articleBody", "words": "schema:wordCount", "post": { "@id": "schema:blogPost", "@container": ["@graph", "@index"] } }, "@id": "http://example.com/", "@type": "schema:Blog", "name": "World Financial News", "post": { "en": { "@id": "http://example.com/posts/1/en", "body": "World commodities were up today with heavy trading of crude oil...", "words": 1539 }, "de": { "@id": "http://example.com/posts/1/de", "body": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl...", "words": 1204 } } }
This expands to the following:
[{ "@id": "http://example.com/", "@type": ["http://schema.org/Blog"], "http://schema.org/blogPost": [{ "@graph": [{ "@id": "http://example.com/posts/1/de", "http://schema.org/articleBody": [{ "@value": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl..." }], "http://schema.org/wordCount": [{"@value": 1204}] }], "@index": "de" }, { "@graph": [{ "@id": "http://example.com/posts/1/en", "http://schema.org/articleBody": [{ "@value": "World commodities were up today with heavy trading of crude oil..." }], "http://schema.org/wordCount": [{"@value": 1539}] }], "@index": "en" }], "http://schema.org/name": [{"@value": "World Financial News"}] }]
When expressed as Quads, this becomes the following:
Graph | Subject | Property | Value | Value Type |
---|---|---|---|---|
http://example.com/ | rdf:type | schema:Blog | ||
http://example.com/ | schema:name | World Financial News | ||
http://example.com/ | schema:blogPost | _:b1 | ||
http://example.com/ | schema:blogPost | _:b2 | ||
_:b1 | http://example.com/posts/1/de | schema:wordCount | 1204 | xsd:integer |
_:b1 | http://example.com/posts/1/de | schema:articleBody | Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl... | |
_:b2 | http://example.com/posts/1/en | schema:wordCount | 1539 | xsd:integer |
_:b2 | http://example.com/posts/1/en | schema:articleBody | World commodities were up today with heavy trading of crude oil... |
As
with
index
maps
,
when
used
with
@graph
,
a
container
may
also
include
@set
to
ensure
that
key
values
are
always
contained
in
an
array.
If
the
processing
mode
is
set
to
json-ld-1.1
,
the
special
index
@none
is
used
for
indexing
graphs
which
does
not
have
an
@index
key,
which
is
useful
to
maintain
a
normalized
representation.
Note,
however,
that
compacting
a
document
where
multiple
unidentified
named
graphs
are
compacted
using
the
@none
index
will
result
in
the
content
of
those
graphs
being
merged.
To
prevent
this,
give
each
graph
a
distinct
@index
key.
{ "@context": { "@version": 1.1, "schema": "http://schema.org/", "name": "schema:name", "body": "schema:articleBody", "words": "schema:wordCount", "post": { "@id": "schema:blogPost", "@container": ["@graph", "@index"] } }, "@id": "http://example.com/", "@type": "schema:Blog", "name": "World Financial News", "post": { "en": { "@id": "http://example.com/posts/1/en", "body": "World commodities were up today with heavy trading of crude oil...", "words": 1539 }, "@none": { "@id": "http://example.com/posts/1/no-language", "body": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl...", "words": 1204 } } }
This expands to the following:
[{ "@id": "http://example.com/", "@type": ["http://schema.org/Blog"], "http://schema.org/blogPost": [{ "@graph": [{ "@id": "http://example.com/posts/1/no-language", "http://schema.org/articleBody": [{ "@value": "Die Werte an Warenbörsen stiegen im Sog eines starken Handels von Rohöl..." }], "http://schema.org/wordCount": [{"@value": 1204}] }] }, { "@graph": [{ "@id": "http://example.com/posts/1/en", "http://schema.org/articleBody": [{ "@value": "World commodities were up today with heavy trading of crude oil..." }], "http://schema.org/wordCount": [{"@value": 1539}] }], "@index": "en" }], "http://schema.org/name": [{"@value": "World Financial News"}] }]
In
addition
to
indexing
node
objects
by
identifier,
graph
objects
may
also
be
indexed
by
their
graph
name
.
By
using
the
@graph
container
type,
introduced
in
section
4.15.1
4.8.1
Graph
Containers
in
addition
to
@id
,
an
object
value
of
such
a
property
is
treated
as
a
key-value
map
where
the
keys
represent
the
identifiers
of
named
graphs
which
are
their
values.
The following example describes a default graph referencing multiple named graphs using an id map .
{ "@context": { "@version": 1.1, "generatedAt": { "@id": "http://www.w3.org/ns/prov#generatedAtTime", "@type": "http://www.w3.org/2001/XMLSchema#date" }, "Person": "http://xmlns.com/foaf/0.1/Person", "name": "http://xmlns.com/foaf/0.1/name", "knows": "http://xmlns.com/foaf/0.1/knows", "graphMap": { "@id": "http://example.org/graphMap", "@container": ["@graph", "@id"] } }, "@id": "http://example.org/foaf-graph", "generatedAt": "2012-04-09", "graphMap": { "http://manu.sporny.org/about#manu": { "@id": "http://manu.sporny.org/about#manu", "@type": "Person", "name": "Manu Sporny", "knows": "http://greggkellogg.net/foaf#me" }, "http://greggkellogg.net/foaf#me": { "@id": "http://greggkellogg.net/foaf#me", "@type": "Person", "name": "Gregg Kellogg", "knows": "http://manu.sporny.org/about#manu" } } }
This expands to the following:
[{ "@id": "http://example.org/foaf-graph", "http://example.org/graphMap": [{ "@id": "http://greggkellogg.net/foaf#me", "@graph": [{ "@id": "http://greggkellogg.net/foaf#me", "@type": ["http://xmlns.com/foaf/0.1/Person"], "http://xmlns.com/foaf/0.1/knows": [{"@value": "http://manu.sporny.org/about#manu"}], "http://xmlns.com/foaf/0.1/name": [{"@value": "Gregg Kellogg"}] }] }, { "@id": "http://manu.sporny.org/about#manu", "@graph": [{ "@id": "http://manu.sporny.org/about#manu", "@type": [ "http://xmlns.com/foaf/0.1/Person" ], "http://xmlns.com/foaf/0.1/knows": [ { "@value": "http://greggkellogg.net/foaf#me" } ], "http://xmlns.com/foaf/0.1/name": [ { "@value": "Manu Sporny" } ] }] }], "http://www.w3.org/ns/prov#generatedAtTime": [{ "@value": "2012-04-09", "@type": "http://www.w3.org/2001/XMLSchema#date" }] }]
When expressed as Quads, this becomes the following:
Graph | Subject | Property | Value | Value Type |
---|---|---|---|---|
http://example.org/foaf-graph | prov:generatedAtTime | 2012-04-09 | xsd:date | |
http://example.org/foaf-graph | http://example.org/graphMap | http://manu.sporny.org/about#manu | ||
http://example.org/foaf-graph | http://example.org/graphMap | http://greggkellogg.net/foaf#me | ||
http://manu.sporny.org/about#manu | http://manu.sporny.org/about#manu | xsd:type | foaf:Person | |
http://manu.sporny.org/about#manu | http://manu.sporny.org/about#manu | foaf:name | Manu Sporny | |
http://manu.sporny.org/about#manu | http://manu.sporny.org/about#manu | foaf:knows | http://greggkellogg.net/foaf#me | |
http://greggkellogg.net/foaf#me | http://greggkellogg.net/foaf#me | xsd:type | foaf:Person | |
http://greggkellogg.net/foaf#me | http://greggkellogg.net/foaf#me | foaf:name | Gregg Kellogg | |
http://greggkellogg.net/foaf#me | http://greggkellogg.net/foaf#me | foaf:knows | http://manu.sporny.org/about#manu |
As
with
id
maps
,
when
used
with
@graph
,
a
container
may
also
include
@set
to
ensure
that
key
values
are
always
contained
in
an
array.
As
with
id
maps
,
the
special
index
@none
is
used
for
indexing
named
graphs
which
do
not
have
an
@id
,
which
is
useful
to
maintain
a
normalized
representation.
The
@none
index
may
also
be
a
term
which
expands
to
@none
.
Note,
however,
that
if
multiple
graphs
are
represented
without
an
@id
,
they
will
be
merged
on
expansion.
To
prevent
this,
use
@none
judiciously,
and
consider
giving
graphs
their
own
distinct
identifier.
{
"@context": {
"@version": 1.1,
"generatedAt": {
"@id": "http://www.w3.org/ns/prov#generatedAtTime",
"@type": "http://www.w3.org/2001/XMLSchema#date"
},
"Person": "http://xmlns.com/foaf/0.1/Person",
"name": "http://xmlns.com/foaf/0.1/name",
"knows": "http://xmlns.com/foaf/0.1/knows",
"graphMap": {
"@id": "http://example.org/graphMap",
"@container": ["@graph", "@id"]
}
},
"@id": "http://example.org/foaf-graph",
"generatedAt": "2012-04-09",
"graphMap": {
"@none": [{
"@id": "http://manu.sporny.org/about#manu",
"@type": "Person",
"name": "Manu Sporny",
"knows": "http://greggkellogg.net/foaf#me"
}, {
"@id": "http://greggkellogg.net/foaf#me",
"@type": "Person",
"name": "Gregg Kellogg",
"knows": "http://manu.sporny.org/about#manu"
}]
}
}
Graph
Containers
are
a
new
feature
in
JSON-LD
1.1,
requiring
processing
mode
set
to
json-ld-1.1
.
This section is non-normative.
In
addition
to
id
and
index
maps
,
JSON-LD
introduces
the
notion
of
type
maps
for
structuring
data.
The
type
indexing
feature
allows
an
author
to
structure
As
with
many
data
using
a
simple
key-value
map
where
the
keys
map
formats,
there
is
no
single
correct
way
to
IRIs
.
This
enables
describe
data
to
be
structured
based
on
the
@type
of
specific
node
objects
.
In
in
JSON-LD.
However,
as
JSON-LD
such
data
is
used
for
describing
graphs,
certain
transformations
can
be
specified
by
associating
used
to
change
the
@type
keyword
with
a
@container
declaration
in
shape
of
the
context:
data,
without
changing
its
meaning
as
Linked
Data.
@none
@context
is
This section is non-normative.
The
JSON-LD
1.1
Processing
Algorithms
and
API
specification
[
JSON-LD11-API
]
defines
a
method
for
expanding
a
JSON-LD
document.
Expansion
is
the
process
of
taking
a
JSON-LD
document
and
applying
a
@context
context
such
that
all
IRIs,
types,
and
values
are
expanded
so
that
the
@context
is
no
longer
necessary.
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": [
{ "@value": "Manu Sporny" }
],
"http://xmlns.com/foaf/0.1/homepage": [
{ "@id": "http://manu.sporny.org/" }
]
}
]
JSON-LD's
media
type
defines
a
profile
parameter
which
can
be
used
to
signal
or
request
expanded
document
form.
The
profile
URI
identifying
expanded
document
form
is
http://www.w3.org/ns/json-ld#expanded
.
This section is non-normative.
The JSON-LD 1.1 Processing Algorithms and API specification [ JSON-LD11-API ] defines a method for compacting a JSON-LD document. Compaction is the process of applying a developer-supplied context to shorten IRIs to terms or compact IRIs and JSON-LD values expressed in expanded form to simple values such as strings or numbers . Often this makes it simpler to work with document as the data is expressed in application-specific terms. Compacted documents are also typically easier to read for humans.
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:
{
"@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/"
}
JSON-LD's
media
type
defines
a
profile
parameter
which
can
be
used
to
signal
or
request
compacted
document
form.
The
profile
URI
identifying
compacted
document
form
is
http://www.w3.org/ns/json-ld#compacted
.
This section is non-normative.
The JSON-LD 1.1 Processing Algorithms and API specification [ JSON-LD11-API ] defines a method for flattening a JSON-LD document. Flattening collects all properties of a node in a single JSON object and labels all blank nodes with blank node identifiers . This ensures a shape of the data and consequently may drastically simplify the code required to process JSON-LD in certain applications.
For example, assume the following JSON-LD input document:
{
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"knows": "http://xmlns.com/foaf/0.1/knows"
},
"@id": "http://me.markus-lanthaler.com/",
"name": "Markus Lanthaler",
"knows": [
{
"@id": "http://manu.sporny.org/about#manu",
"name": "Manu Sporny"
}, {
"name": "Dave Longley"
}
]
}
Running the JSON-LD Flattening algorithm against the JSON-LD input document in the example above and using the same context would result in the following output:
{
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"knows": "http://xmlns.com/foaf/0.1/knows"
},
"@graph": [
{
"@id": "_:b0",
"name": "Dave Longley"
}, {
"@id": "http://manu.sporny.org/about#manu",
"name": "Manu Sporny"
}, {
"@id": "http://me.markus-lanthaler.com/",
"name": "Markus Lanthaler",
"knows": [
{ "@id": "http://manu.sporny.org/about#manu" },
{ "@id": "_:b0" }
]
}
]
}
JSON-LD's
media
type
defines
a
profile
parameter
which
can
be
used
to
signal
or
request
flattened
document
form.
The
profile
URI
identifying
flattened
document
form
is
http://www.w3.org/ns/json-ld#flattened
.
It
can
be
combined
with
the
profile
URI
identifying
expanded
document
form
or
compacted
document
from
.
This section is non-normative.
The JSON-LD 1.1 Framing specification [ JSON-LD11-FRAMING ] defines a method for framing a JSON-LD document. Framing is used to shape the data in a JSON-LD document, using an example frame document which is used to both match the flattened data and show an example of how the resulting data should be shaped.
For example, assume the following JSON-LD frame:
{ "@context": {"@vocab": "http://example.org/"}, "@type": "Library", "contains": { "@type": "Book", "contains": { "@type": "Chapter"
}
}
}
This frame document describes an embedding structure that would place objects with type Library at the top, with objects of type Book that were linked to the library object using the contains property embedded as property values. It also places objects of type Chapter within the referencing Book object as embedded values of the Book object.
When using a flattened set of objects that match the frame components:
{ "@context": { "@vocab": "http://example.org/", "contains": {"@type": "@id"}
},
"@graph": [{ "@id": "http://example.org/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"
}]
}
The Frame Algorithm can create a new document which follows the structure of the frame:
{ "@context": {"@vocab": "http://example.org/"}, "@id": "http://example.org/library", "@type": "Library", "contains": { "@id": "http://example.org/library/the-republic", "@type": "Book", "contains": { "@id": "http://example.org/library/the-republic#introduction", "@type": "Chapter", "description": "An introductory chapter on The Republic.", "title": "The Introduction" }, "creator": "Plato", "title": "The Republic" } }
Ordinary
JSON
documents
can
be
interpreted
as
JSON-LD
by
providing
an
explicit
JSON-LD
context
document.
One
way
to
provide
this
is
by
using
referencing
a
JSON-LD
context
document
in
an
HTTP
Link
Header
.
Doing
so
allows
JSON
to
be
unambiguously
machine-readable
without
requiring
developers
to
drastically
change
their
documents
and
provides
an
upgrade
path
for
existing
infrastructure
without
breaking
existing
clients
that
rely
on
the
application/json
media
type
or
a
media
type
with
a
+json
suffix
as
defined
in
[
RFC6839
].
In order to use an external context with an ordinary JSON document, when retrieving an ordinary JSON document via HTTP, processors MUST retrieve any JSON-LD document referenced by a Link Header with:
rel="http://www.w3.org/ns/json-ld#context"
,
and
type="application/ld+json"
.
The
referenced
document
MUST
have
a
top-level
JSON
object
.
The
@context
subtree
within
that
object
is
added
to
the
top-level
JSON
object
of
the
referencing
document.
If
an
array
is
at
the
top-level
of
the
referencing
document
and
its
items
are
JSON
objects
,
the
@context
subtree
is
added
to
all
array
items.
All
extra
information
located
outside
of
the
@context
subtree
in
the
referenced
document
MUST
be
discarded.
Effectively
this
means
that
the
active
context
is
initialized
with
the
referenced
external
context
.
A
response
MUST
NOT
contain
more
than
one
HTTP
Link
Header
[
RFC5988
]
using
the
http://www.w3.org/ns/json-ld#context
link
relation.
Other mechanisms for providing a JSON-LD Context MAY be described for other URI schemes.
The JSON-LD 1.1 Processing Algorithms and API specification [ JSON-LD11-API ] provides for an expandContext option for specifying a context to use when expanding JSON documents programatically.
The following example demonstrates the use of an external context with an ordinary JSON document over HTTP:
GET /ordinary-json-document.json HTTP/1.1 Host: example.com Accept: application/ld+json,application/json,*/*;q=0.1 ==================================== HTTP/1.1 200 OK ... Content-Type: application/json Link: <https://json-ld.org/contexts/person.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json" { "name": "Markus Lanthaler", "homepage": "http://www.markus-lanthaler.com/", "image": "http://twitter.com/account/profile_image/markuslanthaler" }
Please
note
that
JSON-LD
documents
served
with
the
application/ld+json
media
type
MUST
have
all
context
information,
including
references
to
external
contexts,
within
the
body
of
the
document.
Contexts
linked
via
a
http://www.w3.org/ns/json-ld#context
HTTP
Link
Header
MUST
be
ignored
for
such
documents.
This section is non-normative.
HTML
script
tags
can
be
used
to
embed
blocks
of
data
in
documents.
This
way,
JSON-LD
content
can
be
easily
embedded
in
HTML
by
placing
it
in
a
script
element
with
the
type
attribute
set
to
application/ld+json
.
<script type="application/ld+json"> { "@context": "https://json-ld.org/contexts/person.jsonld", "@id": "http://dbpedia.org/resource/John_Lennon", "name": "John Lennon", "born": "1940-10-09", "spouse": "http://dbpedia.org/resource/Cynthia_Lennon" } </script>
Depending on how the HTML document is served, certain strings may need to be escaped.
Defining how such data may be used is beyond the scope of this specification. The embedded JSON-LD document might be extracted as is or, e.g., be interpreted as RDF.
If JSON-LD content is extracted as RDF [ RDF11-CONCEPTS ], it should be expanded into an RDF Dataset using the Deserialize JSON-LD to RDF Algorithm [ JSON-LD11-API ].
JSON-LD
is
a
serialization
format
for
Linked
Data
based
on
JSON.
It
is
therefore
important
to
distinguish
between
the
syntax,
which
is
defined
by
JSON
in
[
RFC7159
],
and
the
data
model
which
is
an
extension
of
the
RDF
data
model
[
RDF11-CONCEPTS
].
The
precise
details
of
how
JSON-LD
relates
to
the
RDF
data
model
are
given
in
section
7.
10.
Relationship
to
RDF
.
To ease understanding for developers unfamiliar with the RDF model, the following summary is provided:
{
"@id": "http://example.org/1"
}
@id
.
A
document
may
have
nodes
which
are
unrelated,
as
long
as
one
or
more
properties
are
defined,
or
the
node
is
referenced
from
another
node
object
.
_:
.
xsd:string
),
a
number
(
numbers
with
a
non-zero
fractional
part,
i.e.,
the
result
of
a
modulo‑1
operation,
are
interpreted
as
typed
values
with
type
xsd:double
,
all
other
numbers
are
interpreted
as
typed
values
with
type
xsd:integer
),
true
or
false
(which
are
interpreted
as
typed
values
with
type
xsd:boolean
),
or
a
language-tagged
string
.
JSON-LD documents MAY contain data that cannot be represented by the data model defined above. Unless otherwise specified, such data is ignored when a JSON-LD document is being processed. One result of this rule is that properties which are not mapped to an IRI , a blank node , or keyword will be ignored.
Additionally, the JSON serialization format is internally represented using the JSON-LD internal representation , which uses the generic concepts of arrays , dictionaries , strings , numbers , booleans , and null to describe the data represented by a JSON document.
Figure 1: An illustration of the data model.
This appendix restates the syntactic conventions described in the previous sections more formally.
A JSON-LD document MUST be valid JSON text as described in [ RFC7159 ], or some format that can be represented in the JSON-LD internal representation that is equivalent to valid JSON text .
A
JSON-LD
document
MUST
be
a
single
node
object
,
a
JSON
object
consisting
of
only
the
members
@context
and/or
@graph
,
or
an
array
or
zero
or
more
node
objects
.
In contrast to JSON, in JSON-LD the keys in objects MUST be unique.
JSON-LD
allows
keywords
to
be
aliased
(see
section
4.17
4.1.5
Aliasing
Keywords
for
details).
Whenever
a
keyword
is
discussed
in
this
grammar,
the
statements
also
apply
to
an
alias
for
that
keyword
.
For
example,
if
the
active
context
defines
the
term
id
as
an
alias
for
@id
,
that
alias
may
be
legitimately
used
as
a
substitution
for
@id
.
Note
that
keyword
aliases
are
not
expanded
during
context
processing.
A term is a short-hand string that expands to an IRI or a blank node identifier .
A term MUST NOT equal any of the JSON-LD keywords .
When
used
as
the
prefix
in
a
Compact
IRI
,
to
avoid
the
potential
ambiguity
of
a
prefix
being
confused
with
an
IRI
scheme,
terms
SHOULD
NOT
come
from
the
list
of
URI
schemes
as
defined
in
[
IANA-URI-SCHEMES
].
Similarly,
to
avoid
confusion
between
a
Compact
IRI
and
a
term
,
terms
SHOULD
NOT
include
a
colon
(
:
)
and
SHOULD
be
restricted
to
the
form
of
isegment-nz-nc
as
defined
in
[
RFC3987
].
To
avoid
forward-compatibility
issues,
a
term
SHOULD
NOT
start
with
an
@
character
as
future
versions
of
JSON-LD
may
introduce
additional
keywords
.
Furthermore,
the
term
MUST
NOT
be
an
empty
string
(
""
)
as
not
all
programming
languages
are
able
to
handle
empty
JSON
keys.
See section 3.1 The Context and section 3.2 IRIs for further discussion on mapping terms to IRIs .
A node object represents zero or more properties of a node in the graph serialized by the JSON-LD document . A JSON object is a node object if it exists outside of a JSON-LD context and:
@graph
and
@context
,
@value
,
@list
,
or
@set
keywords,
and
The properties of a node in a graph may be spread among different node objects within a document. When that happens, the keys of the different node objects need to be merged to create the properties of the resulting node .
A node object MUST be a JSON object . All keys which are not IRIs , compact IRIs , terms valid in the active context , or one of the following keywords (or alias of such a keyword) MUST be ignored when processed:
@context
,
@id
,
@graph
,
@nest
,
@type
,
@reverse
,
or
@index
If
the
node
object
contains
the
@context
key,
its
value
MUST
be
null
,
an
absolute
IRI
,
a
relative
IRI
,
a
context
definition
,
or
an
array
composed
of
any
of
these.
If
the
node
object
contains
the
@id
key,
its
value
MUST
be
an
absolute
IRI
,
a
relative
IRI
,
or
a
compact
IRI
(including
blank
node
identifiers
).
See
section
3.3
Node
Identifiers
,
section
4.4
4.1.4
Compact
IRIs
,
and
section
4.16
4.5.1
Identifying
Blank
Nodes
for
further
discussion
on
@id
values.
If
the
node
object
contains
the
@graph
key,
its
value
MUST
be
a
node
object
or
an
array
of
zero
or
more
node
objects
.
If
the
node
object
contains
an
@id
keyword,
its
value
is
used
as
the
graph
name
of
a
named
graph
.
See
section
4.15
4.8
Named
Graphs
for
further
discussion
on
@graph
values.
As
a
special
case,
if
a
JSON
object
contains
no
keys
other
than
@graph
and
@context
,
and
the
JSON
object
is
the
root
of
the
JSON-LD
document,
the
JSON
object
is
not
treated
as
a
node
object
;
this
is
used
as
a
way
of
defining
node
objects
that
may
not
form
a
connected
graph.
This
allows
a
context
to
be
defined
which
is
shared
by
all
of
the
constituent
node
objects
.
If
the
node
object
contains
the
@type
key,
its
value
MUST
be
either
an
absolute
IRI
,
a
relative
IRI
,
a
compact
IRI
(including
blank
node
identifiers
),
a
term
defined
in
the
active
context
expanding
into
an
absolute
IRI
,
or
an
array
of
any
of
these.
See
section
3.4
Specifying
the
Type
for
further
discussion
on
@type
values.
If
the
node
object
contains
the
@reverse
key,
its
value
MUST
be
a
JSON
object
containing
members
representing
reverse
properties.
Each
value
of
such
a
reverse
property
MUST
be
an
absolute
IRI
,
a
relative
IRI
,
a
compact
IRI
,
a
blank
node
identifier
,
a
node
object
or
an
array
containing
a
combination
of
these.
If
the
node
object
contains
the
@index
key,
its
value
MUST
be
a
string
.
See
section
4.18
4.6.1
Data
Indexing
for
further
discussion
on
@index
values.
If
the
node
object
contains
the
@nest
key,
its
value
MUST
be
an
JSON
object
or
an
array
of
JSON
objects
which
MUST
NOT
include
a
value
object
.
See
section
6.10
9.10
Property
Nesting
for
further
discussion
on
@nest
values.
Keys in a node object that are not keywords MAY expand to an absolute IRI using the active context . The values associated with keys that expand to an absolute IRI MUST be one of the following:
A
graph
object
represents
a
named
graph
,
which
MAY
include
include
an
explicit
graph
name
.
A
JSON
object
is
a
graph
object
if
it
exists
outside
of
a
JSON-LD
context
,
it
is
not
a
node
object
,
it
is
not
the
top-most
JSON
object
in
the
JSON-LD
document,
and
it
consists
of
no
members
other
than
@graph
,
@index
,
@id
and
@context
,
or
an
alias
of
one
of
these
keywords
.
If
the
graph
object
contains
the
@context
key,
its
value
MUST
be
null
,
an
absolute
IRI
,
a
relative
IRI
,
a
context
definition
,
or
an
array
composed
of
any
of
these.
If
the
graph
object
contains
the
@id
key,
its
value
is
used
as
the
identifier
(
graph
name
)
of
a
named
graph
,
and
MUST
be
an
absolute
IRI
,
a
relative
IRI
,
or
a
compact
IRI
(including
blank
node
identifiers
).
See
section
3.3
Node
Identifiers
,
section
4.4
4.1.4
Compact
IRIs
,
and
section
4.16
4.5.1
Identifying
Blank
Nodes
for
further
discussion
on
@id
values.
A
graph
object
without
an
@id
member
is
also
a
simple
graph
object
and
represents
a
named
graph
without
an
explicit
identifier,
although
in
the
data
model
it
still
has
a
graph
name
,
which
is
an
implicitly
allocated
blank
node
identifier
.
The
value
of
the
@graph
key
MUST
be
a
node
object
or
an
array
of
zero
or
more
node
objects
.
See
section
4.15
4.8
Named
Graphs
for
further
discussion
on
@graph
values..
A value object is used to explicitly associate a type or a language with a value to create a typed value or a language-tagged string .
A
value
object
MUST
be
a
JSON
object
containing
the
@value
key.
It
MAY
also
contain
an
@type
,
an
@language
,
an
@index
,
or
an
@context
key
but
MUST
NOT
contain
both
an
@type
and
an
@language
key
at
the
same
time.
A
value
object
MUST
NOT
contain
any
other
keys
that
expand
to
an
absolute
IRI
or
keyword
.
The
value
associated
with
the
@value
key
MUST
be
either
a
string
,
a
number
,
true
,
false
or
null
.
The
value
associated
with
the
@type
key
MUST
be
a
term
,
a
compact
IRI
,
an
absolute
IRI
,
a
string
which
can
be
turned
into
an
absolute
IRI
using
the
vocabulary
mapping
,
or
null
.
The
value
associated
with
the
@language
key
MUST
have
the
lexical
form
described
in
[
BCP47
],
or
be
null
.
The
value
associated
with
the
@index
key
MUST
be
a
string
.
See
section
4.5
4.2.1
Typed
Values
and
section
4.10
4.2.3
String
Internationalization
for
more
information
on
value
objects
.
A
list
represents
an
ordered
set
of
values.
A
set
represents
an
unordered
set
of
values.
Unless
otherwise
specified,
arrays
are
unordered
in
JSON-LD.
As
such,
the
@set
keyword,
when
used
in
the
body
of
a
JSON-LD
document,
represents
just
syntactic
sugar
which
is
optimized
away
when
processing
the
document.
However,
it
is
very
helpful
when
used
within
the
context
of
a
document.
Values
of
terms
associated
with
an
@set
or
@list
container
will
always
be
represented
in
the
form
of
an
array
when
a
document
is
processed—even
if
there
is
just
a
single
value
that
would
otherwise
be
optimized
to
a
non-array
form
in
compact
document
form
.
This
simplifies
post-processing
of
the
data
as
the
data
is
always
in
a
deterministic
form.
A
list
object
MUST
be
a
JSON
object
that
contains
no
keys
that
expand
to
an
absolute
IRI
or
keyword
other
than
@list
,
@context
,
and
@index
.
A
set
object
MUST
be
a
JSON
object
that
contains
no
keys
that
expand
to
an
absolute
IRI
or
keyword
other
than
@set
,
@context
,
and
@index
.
Please
note
that
the
@index
key
will
be
ignored
when
being
processed.
In
both
cases,
the
value
associated
with
the
keys
@list
and
@set
MUST
be
one
of
the
following
types:
See
section
4.12
4.3
Sets
and
Lists
Value
Ordering
for
further
discussion
on
sets
and
lists.
A
language
map
is
used
to
associate
a
language
with
a
value
in
a
way
that
allows
easy
programmatic
access.
A
language
map
may
be
used
as
a
term
value
within
a
node
object
if
the
term
is
defined
with
@container
set
to
@language
,
or
an
array
containing
both
@language
and
@set
.
The
keys
of
a
language
map
MUST
be
strings
representing
[
BCP47
]
language
codes,
the
keyword
@none
,
or
a
term
which
expands
to
@none
,
and
the
values
MUST
be
any
of
the
following
types:
See
section
4.10
4.2.3
String
Internationalization
for
further
discussion
on
language
maps.
An
index
map
allows
keys
that
have
no
semantic
meaning,
but
should
be
preserved
regardless,
to
be
used
in
JSON-LD
documents.
An
index
map
may
be
used
as
a
term
value
within
a
node
object
if
the
term
is
defined
with
@container
set
to
@index
,
or
an
array
containing
both
@index
and
@set
.
The
values
of
the
members
of
an
index
map
MUST
be
one
of
the
following
types:
See
section
4.18
4.6.1
Data
Indexing
for
further
information
on
this
topic.
Index
Maps
may
also
be
used
to
map
indexes
to
associated
named
graphs
,
if
the
term
is
defined
with
@container
set
to
an
array
containing
both
@graph
and
@index
,
and
optionally
including
@set
.
The
value
consists
of
the
node
objects
contained
within
the
named
graph
which
is
named
using
the
referencing
key,
which
can
be
represented
as
a
simple
graph
object
.
An
id
map
is
used
to
associate
an
IRI
with
a
value
that
allows
easy
programmatic
access.
An
id
map
may
be
used
as
a
term
value
within
a
node
object
if
the
term
is
defined
with
@container
set
to
@id
,
or
an
array
containing
both
@id
and
@set
.
The
keys
of
an
id
map
MUST
be
IRIs
(
relative
IRI
,
compact
IRI
(including
blank
node
identifiers
),
or
absolute
IRI
),
the
keyword
@none
,
or
a
term
which
expands
to
@none
,
and
the
values
MUST
be
node
objects
.
If
the
value
contains
a
property
expanding
to
@id
,
it's
value
MUST
be
equivalent
to
the
referencing
key.
Otherwise,
the
property
from
the
value
is
used
as
the
@id
of
the
node
object
value
when
expanding.
Id
Maps
may
also
be
used
to
map
graph
names
to
their
named
graphs
,
if
the
term
is
defined
with
@container
set
to
an
array
containing
both
@graph
and
@id
,
and
optionally
including
@set
.
The
value
consists
of
the
node
objects
contained
within
the
named
graph
which
is
named
using
the
referencing
key.
A
type
map
is
used
to
associate
an
IRI
with
a
value
that
allows
easy
programmatic
access.
A
type
map
may
be
used
as
a
term
value
within
a
node
object
if
the
term
is
defined
with
@container
set
to
@type
,
or
an
array
containing
both
@type
and
@set
.
The
keys
of
a
type
map
MUST
be
IRIs
(
relative
IRI
,
compact
IRI
(including
blank
node
identifiers
),
or
absolute
IRI
),
the
keyword
@none
,
or
a
term
which
expands
to
@none
,
and
the
values
MUST
be
node
objects
.
If
the
value
contains
a
property
expanding
to
@type
,
and
it's
value
is
contains
the
referencing
key
after
suitable
expansion
of
both
the
referencing
key
and
the
value,
then
the
node
object
already
contains
the
type.
Otherwise,
the
property
from
the
value
is
added
as
a
@type
of
the
node
object
value
when
expanding.
A nested property is used to gather properties of a node object in a separate JSON object , or array of JSON objects which are not value objects . It is semantically transparent and is removed during the process of expansion . Property nesting is recursive, and collections of nested properties may contain further nesting.
Semantically, nesting is treated as if the properties and values were declared directly within the containing node object .
A context definition defines a local context in a node object .
A
context
definition
MUST
be
a
JSON
object
whose
keys
MUST
be
either
terms
,
compact
IRIs
,
absolute
IRIs
,
or
one
of
the
keywords
@language
,
@base
,
@vocab
,
or
@version
.
If
the
context
definition
has
an
@language
key,
its
value
MUST
have
the
lexical
form
described
in
[
BCP47
]
or
be
null
.
If
the
context
definition
has
an
@base
key,
its
value
MUST
be
an
absolute
IRI
,
a
relative
IRI
,
or
null
.
If
the
context
definition
has
an
@vocab
key,
its
value
MUST
be
a
absolute
IRI
,
a
compact
IRI
,
a
blank
node
identifier
,
an
empty
string
(
""
)
,
a
term
,
or
null
.
If
the
context
definition
has
an
@version
key,
its
value
MUST
be
a
number
with
the
value
1.1
.
The value of keys that are not keywords MUST be either an absolute IRI , a compact IRI , a term , a blank node identifier , a keyword , null , or an expanded term definition .
An expanded term definition is used to describe the mapping between a term and its expanded identifier, as well as other properties of the value associated with the term when it is used as key in a node object .
An
expanded
term
definition
MUST
be
a
JSON
object
composed
of
zero
or
more
keys
from
@id
,
@reverse
,
@type
,
@language
,
@context
,
@prefix
,
or
@container
.
An
expanded
term
definition
SHOULD
NOT
contain
any
other
keys.
If
the
term
being
defined
is
not
a
compact
IRI
or
absolute
IRI
and
the
active
context
does
not
have
an
@vocab
mapping,
the
expanded
term
definition
MUST
include
the
@id
key.
If
the
expanded
term
definition
contains
the
@id
keyword
,
its
value
MUST
be
null
,
an
absolute
IRI
,
a
blank
node
identifier
,
a
compact
IRI
,
a
term
,
or
a
keyword
.
If
an
expanded
term
definition
has
an
@reverse
member,
it
MUST
NOT
have
@id
or
@nest
members
at
the
same
time,
its
value
MUST
be
an
absolute
IRI
,
a
blank
node
identifier
,
a
compact
IRI
,
or
a
term
.
If
an
@container
member
exists,
its
value
MUST
be
null
,
@set
,
or
@index
.
If
the
expanded
term
definition
contains
the
@type
keyword
,
its
value
MUST
be
an
absolute
IRI
,
a
compact
IRI
,
a
term
,
null
,
or
one
of
the
keywords
@id
or
@vocab
.
If
the
expanded
term
definition
contains
the
@language
keyword
,
its
value
MUST
have
the
lexical
form
described
in
[
BCP47
]
or
be
null
.
If
the
expanded
term
definition
contains
the
@container
keyword
,
its
value
MUST
be
either
@list
,
@set
,
@language
,
@index
,
@id
,
@graph
,
@type
,
or
be
null
or
an
array
containing
exactly
any
one
of
those
keywords,
or
a
combination
of
@set
and
any
of
@index
,
@id
,
@graph
,
@type
,
@language
in
any
order
.
@container
may
also
be
an
array
containing
@graph
along
with
either
@id
or
@index
and
also
optionally
including
@set
.
If
the
value
is
@language
,
when
the
term
is
used
outside
of
the
@context
,
the
associated
value
MUST
be
a
language
map
.
If
the
value
is
@index
,
when
the
term
is
used
outside
of
the
@context
,
the
associated
value
MUST
be
an
index
map
.
If
an
expanded
term
definition
has
an
@context
member,
it
MUST
be
a
valid
context
definition
.
If
the
expanded
term
definition
contains
the
@nest
keyword
,
its
value
MUST
be
either
@nest
,
or
a
term
which
expands
to
@nest
.
If
the
expanded
term
definition
contains
the
@prefix
keyword
,
its
value
MUST
be
true
or
false
.
Terms MUST NOT be used in a circular manner. That is, the definition of a term cannot depend on the definition of another term if that other term also depends on the first term.
See section 3.1 The Context for further discussion on contexts.
JSON-LD
is
a
concrete
RDF
syntax
as
described
in
[
RDF11-CONCEPTS
].
Hence,
a
JSON-LD
document
is
both
an
RDF
document
and
a
JSON
document
and
correspondingly
represents
an
instance
of
an
RDF
data
model.
model
.
However,
JSON-LD
also
extends
the
RDF
data
model
to
optionally
allow
JSON-LD
to
serialize
generalized
RDF
Datasets
.
The
JSON-LD
extensions
to
the
RDF
data
model
are:
Summarized, these differences mean that JSON-LD is capable of serializing any RDF graph or dataset and most, but not all, JSON-LD documents can be directly interpreted as RDF as described in RDF 1.1 Concepts [ RDF11-CONCEPTS ].
For authors and developers working with blank nodes as properties when deserializing to RDF, three potential approaches are suggested:
The normative algorithms for interpreting JSON-LD as RDF and serializing RDF as JSON-LD are specified in the JSON-LD 1.1 Processing Algorithms and API specification [ JSON-LD11-API ].
Even though JSON-LD serializes generalized RDF Datasets , it can also be used as a RDF graph source . In that case, a consumer MUST only use the default graph and ignore all named graphs . This allows servers to expose data in languages such as Turtle and JSON-LD using content negotiation.
Publishers supporting both dataset and graph syntaxes have to ensure that the primary data is stored in the default graph to enable consumers that do not support datasets to process the information.
This section is non-normative.
The process of serializing RDF as JSON-LD and deserializing JSON-LD to RDF depends on executing the algorithms defined in RDF Serialization-Deserialization Algorithms in the JSON-LD 1.1 Processing Algorithms and API specification [ JSON-LD11-API ]. It is beyond the scope of this document to detail these algorithms any further, but a summary of the necessary operations is provided to illustrate the process.
The procedure to deserialize a JSON-LD document to RDF involves the following steps:
For example, consider the following JSON-LD document in compact form:
{
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"knows": "http://xmlns.com/foaf/0.1/knows"
},
"@id": "http://me.markus-lanthaler.com/",
"name": "Markus Lanthaler",
"knows": [
{
"@id": "http://manu.sporny.org/about#manu",
"name": "Manu Sporny"
}, {
"name": "Dave Longley"
}
]
}
Running the JSON-LD Expansion and Flattening algorithms against the JSON-LD input document in the example above would result in the following output:
[
{
"@id": "_:b0",
"http://xmlns.com/foaf/0.1/name": "Dave Longley"
}, {
"@id": "http://manu.sporny.org/about#manu",
"http://xmlns.com/foaf/0.1/name": "Manu Sporny"
}, {
"@id": "http://me.markus-lanthaler.com/",
"http://xmlns.com/foaf/0.1/name": "Markus Lanthaler",
"http://xmlns.com/foaf/0.1/knows": [
{ "@id": "http://manu.sporny.org/about#manu" },
{ "@id": "_:b0" }
]
}
]
Deserializing this to RDF now is a straightforward process of turning each node object into one or more RDF triples. This can be expressed in Turtle as follows:
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
_:b0 foaf:name "Dave Longley" .
<http://manu.sporny.org/about#manu> foaf:name "Manu Sporny" .
<http://me.markus-lanthaler.com/> foaf:name "Markus Lanthaler" ;
foaf:knows
<http:
//manu.sporny.org/about#manu>,
_:b0
.
The process of serializing RDF as JSON-LD can be thought of as the inverse of this last step, creating an expanded JSON-LD document closely matching the triples from RDF, using a single node object for all triples having a common subject, and a single property for those triples also having a common predicate. The result may then be framed by using the Framing Algorithm described in [ JSON-LD11-FRAMING ] to create the desired object embedding.
This section is non-normative.
@version
member
which
is
used
to
set
the
processing
mode
.
@context
property,
which
defines
a
context
used
for
values
of
a
property
identified
with
such
a
term
.
@container
values
within
an
expanded
term
definition
may
now
include
@id
,
@graph
and
@type
,
corresponding
to
id
maps
and
type
maps
.
@nest
property,
which
identifies
a
term
expanding
to
@nest
which
is
used
for
containing
properties
using
the
same
@nest
mapping.
When
expanding,
the
values
of
a
property
expanding
to
@nest
are
treated
as
if
they
were
contained
within
the
enclosing
node
object
directly.
@none
value,
but
JSON-LD
1.0
only
allowed
string
values.
This
has
been
updated
to
allow
(and
ignore)
@null
values.
@container
in
an
expanded
term
definition
can
also
be
an
array
containing
any
appropriate
container
keyword
along
with
@set
(other
than
@list
).
This
allows
a
way
to
ensure
that
such
property
values
will
always
be
expressed
in
array
form.
@prefix
member
with
the
value
true
.
The
1.0
algorithm
has
been
updated
to
only
consider
terms
that
map
to
a
value
that
ends
with
a
URI
gen-delim
character.
@container
set
to
@graph
are
interpreted
as
implicitly
named
graphs
,
where
the
associated
graph
name
is
assigned
from
a
new
blank
node
identifier
.
Other
combinations
include
["@container",
"@id"]
,
["@container",
"@index"]
each
also
may
include
"@set"
,
which
create
maps
from
the
graph
identifier
or
index
value
similar
to
index
maps
and
id
maps
.
""
)
has
been
added
as
a
possible
value
for
@vocab
in
a
context.
When
this
is
set,
vocabulary-relative
IRIs,
such
as
the
keys
of
node
objects
,
are
expanded
or
compacted
relative
to
the
base
IRI
using
string
concatenation.
This section is non-normative.
The following is a list of issues open at the time of publication.
This section is non-normative.
The JSON-LD examples below demonstrate how JSON-LD can be used to express semantic data marked up in other linked data formats such as Turtle, RDFa, Microformats, and Microdata. These sections are merely provided as evidence that JSON-LD is very flexible in what it can express across different Linked Data approaches.
This section is non-normative.
The following are examples of transforming RDF expressed in Turtle [ TURTLE ] into JSON-LD.
The
JSON-LD
context
has
direct
equivalents
for
the
Turtle
@prefix
declaration:
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<http://manu.sporny.org/about#manu> a foaf:Person;
foaf:name "Manu Sporny";
foaf:homepage
<http:
//manu.sporny.org/>
.
{
"@context": {
"foaf": "http://xmlns.com/foaf/0.1/"
},
"@id": "http://manu.sporny.org/about#manu",
"@type": "foaf:Person",
"foaf:name": "Manu Sporny",
"foaf:homepage": { "@id": "http://manu.sporny.org/" }
}
Both Turtle and JSON-LD allow embedding, although Turtle only allows embedding of blank nodes .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<http://manu.sporny.org/about#manu>
a foaf:Person;
foaf:name "Manu Sporny";
foaf
:knows
[
a
foaf:Person;
foaf:name
"Gregg
Kellogg"
]
.
{
"@context": {
"foaf": "http://xmlns.com/foaf/0.1/"
},
"@id": "http://manu.sporny.org/about#manu",
"@type": "foaf:Person",
"foaf:name": "Manu Sporny",
"foaf:knows": {
"@type": "foaf:Person",
"foaf:name": "Gregg Kellogg"
}
}
In
JSON-LD
numbers
and
boolean
values
are
native
data
types.
While
Turtle
has
a
shorthand
syntax
to
express
such
values,
RDF's
abstract
syntax
requires
that
numbers
and
boolean
values
are
represented
as
typed
literals.
Thus,
to
allow
full
round-tripping,
the
JSON-LD
1.1
Processing
Algorithms
and
API
specification
[
JSON-LD11-API
]
defines
conversion
rules
between
JSON-LD's
native
data
types
and
RDF's
counterparts.
Numbers
without
fractions
are
converted
to
xsd:integer
-typed
literals,
numbers
with
fractions
to
xsd:double
-typed
literals
and
the
two
boolean
values
true
and
false
to
a
xsd:boolean
-typed
literal.
All
typed
literals
are
in
canonical
lexical
form.
{
"@context": {
"ex": "http://example.com/vocab#"
},
"@id": "http://example.com/",
"ex:numbers": [ 14, 2.78 ],
"ex:booleans": [ true, false ]
}
@prefix ex: <http://example.com/vocab#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://example.com/>
ex:numbers "14"^^xsd:integer, "2.78E0"^^xsd:double ;
ex
:booleans
"
true
"^^
xsd
:boolean
,
"
false
"^^
xsd
:boolean
.
Both JSON-LD and Turtle can represent sequential lists of values.
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
<http://example.org/people#joebob> a foaf:Person;
foaf:name "Joe Bob";
foaf:nick
(
"joe"
"bob"
"jaybee"
)
.
{
"@context": {
"foaf": "http://xmlns.com/foaf/0.1/"
},
"@id": "http://example.org/people#joebob",
"@type": "foaf:Person",
"foaf:name": "Joe Bob",
"foaf:nick": {
"@list": [ "joe", "bob", "jaybee" ]
}
}
This section is non-normative.
The following example describes three people with their respective names and homepages in RDFa [ RDFA-CORE ].
<div prefix="foaf: http://xmlns.com/foaf/0.1/"> <ul> <li typeof="foaf:Person"> <a property="foaf:homepage" href="http://example.com/bob/"> <span property="foaf:name">Bob</span> </a> </li> <li typeof="foaf:Person"> <a property="foaf:homepage" href="http://example.com/eve/"> <span property="foaf:name">Eve</span> </a> </li> <li typeof="foaf:Person"> <a property="foaf:homepage" href="http://example.com/manu/"> <span property="foaf:name">Manu</span> </a> </li> </ul> </div>
An example JSON-LD implementation using a single context is described below.
{
"@context": {
"foaf": "http://xmlns.com/foaf/0.1/"
},
"@graph": [
{
"@type": "foaf:Person",
"foaf:homepage": "http://example.com/bob/",
"foaf:name": "Bob"
}, {
"@type": "foaf:Person",
"foaf:homepage": "http://example.com/eve/",
"foaf:name": "Eve"
}, {
"@type": "foaf:Person",
"foaf:homepage": "http://example.com/manu/",
"foaf:name": "Manu"
}
]
}
This section is non-normative.
The following example uses a simple Microformats hCard example to express how Microformats [ MICROFORMATS ] are represented in JSON-LD.
<div class="vcard">
<a class="url fn" href="http://tantek.com/">Tantek Çelik</a>
<
/div>
The
representation
of
the
hCard
expresses
the
Microformat
terms
in
the
context
and
uses
them
directly
for
the
url
and
fn
properties.
Also
note
that
the
Microformat
to
JSON-LD
processor
has
generated
the
proper
URL
type
for
http://tantek.com/
.
{
"@context": {
"vcard": "http://microformats.org/profile/hcard#vcard",
"url": {
"@id": "http://microformats.org/profile/hcard#url",
"@type": "@id"
},
"fn": "http://microformats.org/profile/hcard#fn"
},
"@type": "vcard",
"url": "http://tantek.com/",
"fn": "Tantek Çelik"
}
This section is non-normative.
The HTML Microdata [ MICRODATA ] example below expresses book information as a Microdata Work item.
<dl itemscope
itemtype="http://purl.org/vocab/frbr/core#Work"
itemid="http://purl.oreilly.com/works/45U8QJGZSQKDH8N">
<dt>Title</dt>
<dd><cite itemprop="http://purl.org/dc/terms/title">Just a Geek</cite></dd>
<dt>By</dt>
<dd><span itemprop="http://purl.org/dc/terms/creator">Wil Wheaton</span></dd>
<dt>Format</dt>
<dd itemprop="http://purl.org/vocab/frbr/core#realization"
itemscope
itemtype="http://purl.org/vocab/frbr/core#Expression"
itemid="http://purl.oreilly.com/products/9780596007683.BOOK">
<link itemprop="http://purl.org/dc/terms/type" href="http://purl.oreilly.com/product-types/BOOK">
Print
</dd>
<dd itemprop="http://purl.org/vocab/frbr/core#realization"
itemscope
itemtype="http://purl.org/vocab/frbr/core#Expression"
itemid="http://purl.oreilly.com/products/9780596802189.EBOOK">
<link itemprop="http://purl.org/dc/terms/type" href="http://purl.oreilly.com/product-types/EBOOK">
Ebook
</dd>
</
dl
>
Note that the JSON-LD representation of the Microdata information stays true to the desires of the Microdata community to avoid contexts and instead refer to items by their full IRI .
[
{
"@id": "http://purl.oreilly.com/works/45U8QJGZSQKDH8N",
"@type": "http://purl.org/vocab/frbr/core#Work",
"http://purl.org/dc/terms/title": "Just a Geek",
"http://purl.org/dc/terms/creator": "Whil Wheaton",
"http://purl.org/vocab/frbr/core#realization":
[
"http://purl.oreilly.com/products/9780596007683.BOOK",
"http://purl.oreilly.com/products/9780596802189.EBOOK"
]
}, {
"@id": "http://purl.oreilly.com/products/9780596007683.BOOK",
"@type": "http://purl.org/vocab/frbr/core#Expression",
"http://purl.org/dc/terms/type": "http://purl.oreilly.com/product-types/BOOK"
}, {
"@id": "http://purl.oreilly.com/products/9780596802189.EBOOK",
"@type": "http://purl.org/vocab/frbr/core#Expression",
"http://purl.org/dc/terms/type": "http://purl.oreilly.com/product-types/EBOOK"
}
]
This section has been submitted to the Internet Engineering Steering Group (IESG) for review, approval, and registration with IANA.
profile
A
non-empty
list
of
space-separated
URIs
identifying
specific
constraints
or
conventions
that
apply
to
a
JSON-LD
document
according
to
[
RFC6906
].
A
profile
does
not
change
the
semantics
of
the
resource
representation
when
processed
without
profile
knowledge,
so
that
clients
both
with
and
without
knowledge
of
a
profiled
resource
can
safely
use
the
same
representation.
The
profile
parameter
MAY
be
used
by
clients
to
express
their
preferences
in
the
content
negotiation
process.
If
the
profile
parameter
is
given,
a
server
SHOULD
return
a
document
that
honors
the
profiles
in
the
list
which
are
recognized
by
the
server.
It
is
RECOMMENDED
that
profile
URIs
are
dereferenceable
and
provide
useful
documentation
at
that
URI.
For
more
information
and
background
please
refer
to
[
RFC6906
].
This
specification
defines
three
values
for
the
profile
parameter.
To
request
or
specify
expanded
JSON-LD
document
form
,
the
URI
http://www.w3.org/ns/json-ld#expanded
SHOULD
be
used.
To
request
or
specify
compacted
JSON-LD
document
form
,
the
URI
http://www.w3.org/ns/json-ld#compacted
SHOULD
be
used.
To
request
or
specify
flattened
JSON-LD
document
form
,
the
URI
http://www.w3.org/ns/json-ld#flattened
SHOULD
be
used.
Please
note
that,
according
[
HTTP11
],
the
value
of
the
profile
parameter
has
to
be
enclosed
in
quotes
(
"
)
because
it
contains
special
characters
and,
if
multiple
profiles
are
combined,
whitespace.
When processing the "profile" media type parameter, it is important to note that its value contains one or more URIs and not IRIs. In some cases it might therefore be necessary to convert between IRIs and URIs as specified in section 3 Relationship between IRIs and URIs of [ RFC3987 ].
Since
JSON-LD
is
intended
to
be
a
pure
data
exchange
format
for
directed
graphs,
the
serialization
SHOULD
NOT
be
passed
through
a
code
execution
mechanism
such
as
JavaScript's
eval()
function
to
be
parsed.
An
(invalid)
document
may
contain
code
that,
when
executed,
could
lead
to
unexpected
side
effects
compromising
the
security
of
a
system.
When processing JSON-LD documents, links to remote contexts are typically followed automatically, resulting in the transfer of files without the explicit request of the user for each one. If remote contexts are served by third parties, it may allow them to gather usage patterns or similar information leading to privacy concerns. Specific implementations, such as the API defined in the JSON-LD 1.1 Processing Algorithms and API specification [ JSON-LD11-API ], may provide fine-grained mechanisms to control this behavior.
JSON-LD contexts that are loaded from the Web over non-secure connections, such as HTTP, run the risk of being altered by an attacker such that they may modify the JSON-LD active context in a way that could compromise security. It is advised that any application that depends on a remote context for mission critical purposes vet and cache the remote context before allowing the system to use it.
Given that JSON-LD allows the substitution of long IRIs with short terms, JSON-LD documents may expand considerably when processed and, in the worst case, the resulting data might consume all of the recipient's resources. Applications should treat any data with due skepticism.
Fragment identifiers used with application/ld+json are treated as in RDF syntaxes, as per RDF 1.1 Concepts and Abstract Syntax [ RDF11-CONCEPTS ].
Consider requirements from Self-Review Questionnaire: Security and Privacy .