This document is also available in this non-normative format: diff to previous version .
This document is licensed under a Creative Commons Attribution 3.0 License .
Developers
that
embed
structured
data
in
their
Web
pages
can
choose
among
a
number
of
languages
such
as
RDFa
[
RDFA-CORE
],
Microformats
JSON
[
MICROFORMATS
RFC4627
]
and
Microdata
[
MICRODATA
].
Each
of
these
structured
data
languages,
while
incompatible
at
the
syntax
level,
can
be
easily
mapped
to
RDF.
JSON
has
proven
to
be
a
highly
useful
object
serialization
and
messaging
format.
In
an
attempt
to
harmonize
the
representation
of
Linked
Data
in
JSON,
this
specification
outlines
a
common
JSON
representation
format
for
expressing
directed
graphs;
mixing
both
Linked
Data
that
can
be
used
to
represent
objects
specified
via
RDFa,
Microformats
and
Microdata.
non-Linked
Data
in
a
single
document.
This document is merely a public working draft of a potential specification. It has no official standing of any kind and does not represent the support or consensus of any standards organisation.
This document is an experimental work in progress.
JSON, as specified in [ RFC4627 ], is a simple language for representing data on the Web. Linked Data is a technique for describing content across different documents or Web sites. Web resources are described using IRI s, and typically are dereferencable entities that may be used to find more information, creating a "Web of Knowledge". JSON-LD is intended to be a simple publishing method for expressing not only Linked Data in JSON, but for adding semantics to existing JSON.
JSON-LD
is
designed
as
a
light-weight
syntax
that
can
be
used
to
express
Linked
Data.
It
is
primarily
intended
to
be
a
way
to
express
Linked
Data
in
Javascript
and
other
Web-based
programming
environments.
It
is
also
useful
when
building
interoperable
Web
Services
and
when
storing
Linked
Data
in
JSON-based
document
storage
engines.
It
is
practical
and
designed
to
be
as
simple
as
possible,
utilizing
the
large
number
of
JSON
parsers
and
existing
code
that
is
in
use
today.
It
is
designed
to
be
able
to
express
key-value
pairs,
RDF
data,
RDFa
[
RDFA-CORE
]
data,
Microformats
[
MICROFORMATS
]
data,
and
Microdata.
Microdata
[
MICRODATA
].
That
is,
it
supports
every
major
Web-based
structured
data
model
in
use
today.
It
The
syntax
does
not
require
anyone
many
applications
to
change
their
JSON,
but
easily
add
meaning
by
adding
context
in
a
way
that
is
either
in-band
or
out-of-band.
The
syntax
is
designed
to
not
disturb
already
deployed
systems
running
on
JSON,
but
provide
a
smooth
migration
path
from
JSON
to
JSON
with
added
semantics.
Finally,
the
format
is
intended
to
be
fast
to
parse,
fast
to
generate,
stream-based
and
document-based
processing
compatible,
and
require
a
very
small
memory
footprint
in
order
to
operate.
This document is a detailed specification for a serialization of JSON for Linked data. The document is primarily intended for the following audiences:
To
understand
the
basics
in
this
specification
you
must
first
be
familiar
with
JSON,
which
is
detailed
in
[
RFC4627
].
To
understand
the
API
and
how
it
is
intended
to
operate
in
a
programming
environment,
it
is
useful
to
have
working
knowledge
of
the
JavaScript
programming
language
[
ECMA-262
]
and
WebIDL
[
WEBIDL
].
To
understand
how
JSON-LD
maps
to
RDF,
it
is
helpful
to
be
familiar
with
the
basic
RDF
as
described
in
concepts
[
RDF-CONCEPTS
].
Examples may contain references to existing vocabularies and use abbreviations in CURIEs and source code. The following is a list of all vocabularies and their abbreviations, as used in this document:
dc
,
e.g.,
dc:title
)
foaf
,
e.g.,
foaf:knows
)
rdf
,
e.g.,
rdf:type
)
xsd
,
e.g.,
xsd:integer
)
There are a number of ways that one may participate in the development of this specification:
The following section outlines the design goals and rationale behind the JSON-LD markup language.
A number of design considerations were explored during the creation of this markup language:
The following definition for Linked Data is the one that will be used for this specification.
Note that the definition for Linked Data above is silent on the topic of unlabeled nodes. Unlabeled nodes are not considered Linked Data . However, this specification allows for the expression of unlabled nodes, as most graph-based data sets on the Web contain a number of associated nodes that are not named and thus are not directly de-referenceable.
An
Internationalized
Resource
Identifier
(
IRI
)
),
as
described
in
[
RFC3987
],
is
a
mechanism
for
representing
unique
identifiers
on
the
web.
In
Linked
Data,
IRIs
(or
URI
references)
are
Data
,
an
IRI
is
commonly
used
for
describing
entities
and
properties.
expressing
a
subject
,
a
property
or
an
object
.
Establishing
JSON-LD
defines
a
mechanism
to
map
JSON
values
to
IRIs
will
help
in
the
mapping
of
JSON
objects
to
RDF.
IRIs.
This
does
not
mean
that
JSON-LD
must
requires
every
key
or
value
to
be
restrictive
in
declaring
a
set
of
terms,
rather,
experimentation
an
IRI,
but
rather
ensures
that
keys
and
innovation
should
values
can
be
supported
as
part
of
mapped
to
IRIs
if
the
core
design
of
JSON-LD.
developer
so
desires
to
transform
their
data
into
Linked
Data.
There
are,
however,
are
a
number
of
very
small
design
criteria
few
techniques
that
can
ensure
that
developers
will
generate
good
RDF
data
that
will
create
value
Linked
Data
for
the
greater
semantic
web
community
and
JSON/REST-based
Web
Services
community.
Web.
JSON-LD
formalizes
those
techniques.
We
will
be
using
the
following
JSON
object
markup
as
the
example
for
the
rest
of
this
section:
{"a": "Person","name": "Manu Sporny","homepage": "http://manu.sporny.org/""homepage": "http://manu.sporny.org/", "avatar": "http://twitter.com/account/profile_image/manusporny" }
A
In
JSON-LD,
a
context
is
used
to
allow
developers
to
use
aliases
for
map
term
s
to
IRI
s.
A
term
is
a
short
word
that
may
be
expanded
to
an
IRI
.
The
semantic
web,
just
like
the
document-based
web,
uses
IRIs
for
unambiguous
identification.
The
idea
is
that
these
terms
term
s
mean
something,
which
you
will
eventually
want
to
query.
A
context
allows
the
expression
of
a
number
something
that
may
be
of
terms
which
map
directly
use
to
IRI
s.
other
developers.
For
example,
the
term
name
may
map
directly
to
the
IRI
http://xmlns.com/foaf/0.1/name
.
This
allows
JSON-LD
documents
to
be
constructed
using
the
common
JSON
syntax
practice
of
using
simple
name/value
pairs.
pairs
while
ensuring
that
the
data
is
useful
outside
of
the
database
or
page
in
which
it
resides.
To
reduce
These
Linked
Data
term
s
are
typically
collected
in
a
context
and
then
used
by
adding
a
single
line
to
the
number
of
different
JSON
markup
above:
{
"@context": "http://example.org/json-ld-contexts/person",
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/",
"avatar": "http://twitter.com/account/profile_image/manusporny"
}
The
addition
above
transforms
the
previous
JSON
document
into
a
JSON
document
with
added
semantics
because
the
@context
specifies
how
the
name
,
homepage
,
and
avatar
terms
that
must
be
defined,
JSON-LD
also
map
to
IRIs.
Mapping
those
keys
to
IRIs
gives
the
data
global
context.
If
two
developers
use
the
same
IRI
to
describe
a
property,
they
are
more
than
likely
expressing
the
same
concept.
This
allows
terms
both
developers
to
be
used
re-use
each
others
data
without
having
to
expand
Compact
URIs
(
CURIE
).
agree
to
how
their
data
will
inter-operate
on
a
site-by-site
basis.
The
semantic
web
specifies
this
via
uses
a
special
type
of
document
called
a
Web
Vocabulary
Documents
,
in
which
to
define
term
s.
A
context
is
a
type
of
Web
vocabulary.
Typically,
these
Web
Vocabulary
documents
have
prefix
is
es
associated
with
a
document,
them
and
contain
a
suffix
number
of
term
declarations.
A
prefix
,
like
a
term
,
is
used
a
short
word
that
expands
to
create
an
IRI
based
on
this
a
Web
Vocabulary
IRI.
Prefix
es
are
helpful
when
a
developer
wants
to
mix
multiple
vocabularies
together
in
a
context,
but
does
not
want
to
go
to
the
trouble
of
defining
every
single
term
in
every
single
vocabulary.
Some
Web
Vocabularies
may
have
10-20
terms
defined.
If
a
developer
wants
to
use
3-4
different
vocabularies,
the
number
of
terms
that
would
have
to
be
declared
in
a
single
context
would
become
quite
large.
To
reduce
the
number
of
different
terms
that
must
be
defined,
JSON-LD
also
allows
prefixes
to
be
used
to
compact
IRIs.
For
example,
the
IRI
http://xmlns.com/foaf/0.1/
specifies
a
Web
Vocabulary
Document,
and
which
may
be
represented
using
the
foaf
prefix
.
The
foaf
Web
Vocabulary
contains
a
term
called
name
.
If
you
join
the
foaf
prefix
with
the
name
is
suffix,
you
can
build
a
term
in
compact
IRI
that
vocabulary.
Join
the
two
items
together
and
you
have
will
expand
out
into
an
unambiguous
identifier
absolute
IRI
for
a
the
http://xmlns.com/foaf/0.1/name
vocabulary
term.
The
Compact
URI
Expression,
That
is,
the
compact
IRI,
or
short-form,
is
foaf:name
and
the
expanded-form
is
http://xmlns.com/foaf/0.1/name
.
This
vocabulary
term
identifies
the
given
name
for
something,
for
example
-
is
used
to
specify
a
person's
name.
Developers,
and
machines,
would
be
are
able
to
use
this
IRI
(plugging
it
directly
into
a
web
browser,
for
instance)
to
go
to
the
term
and
get
a
definition
of
what
the
term
means.
Much
like
we
can
use
WordNet
today
to
see
the
definition
of
words
in
the
English
language.
Machines
Developers
and
machines
need
the
same
sort
of
dictionary
of
terms,
and
URIs
terms.
IRIs
provide
a
way
to
ensure
that
these
terms
are
unambiguous.
The
context
provides
a
collection
of
vocabulary
terms
term
s
and
prefix
es
that
can
be
used
for
a
to
expand
JSON
object.
keys
and
values
into
IRI
s.
In
the
names
in
JSON
objects,
machines
could
automatically
expand
previous
section,
the
terms
developer
used
the
@context
keyword
to
pull
in
an
external
context.
That
context
document,
if
de-referenced,
would
look
something
meaningful
and
unambiguous,
like
this:
{"", "": "Manu Sporny", "": "http://manu.sporny.org" "": "http://twitter.com/account/profile_image/manusporny""name": "http://xmlns.com/foaf/0.1/name", "homepage": "http://xmlns.com/foaf/0.1/homepage", "avatar": "http://xmlns.com/foaf/0.1/avatar" }
Doing
this
would
mean
that
JSON
would
start
to
become
unambiguously
machine-readable,
play
well
with
the
semantic
web,
and
basic
markup
wouldn't
be
that
much
more
complex
than
basic
JSON
markup.
A
win,
all
around.
2.5
Mashing
Up
Vocabularies
Developers
would
also
benefit
by
allowing
other
vocabularies
to
be
used
automatically
with
their
JSON
API.
There
are
over
200
Vocabulary
Documents
that
are
available
for
use
on
the
Web
today.
Some
of
these
vocabularies
are:
RDF
-
for
describing
information
about
objects
on
the
semantic
web.
RDFS
-
for
expressing
things
like
labels
and
comments.
XSD
-
for
specifying
basic
types
like
strings,
integers,
dates
and
times.
Dublin
Core
-
for
describing
creative
works.
FOAF
-
for
describing
social
networks.
Calendar
-
for
specifying
events.
SIOC
-
for
describing
discussions
on
blogs
and
websites.
CCrel
-
for
describing
Creative
Commons
and
other
types
of
licenses.
GEO
-
for
describing
geographic
location.
VCard
-
for
describing
organizations
and
people.
DOAP
-
for
describing
projects.
Since
these
vocabularies
are
very
popular,
they
are
pre-defined
in
something
called
the
default
JSON-LD
context
,
which
document
is
a
set
of
vocabulary
prefixes
that
are
pre-loaded
in
all
JSON-LD
processors.
The
contents
of
the
default
context
simple
mapping
from
term
are
provided
later
in
this
document.
Using
the
default
context
s
and
prefix
allows
developers
es
to
express
data
unambiguously,
like
so:
{
"",
"": "Manu Sporny",
"": "http://manu.sporny.org/",
"": "http://twitter.com/account/profile_image/manusporny"
}
Developers
can
expanded
values
such
as
IRIs
or
keywords.
Contexts
may
also
specify
their
own
Vocabulary
documents
by
modifying
the
active
context
contain
datatype
information
for
certain
term
in-line
using
the
@context
keyword,
like
so:
{
,
"a": "foaf:Person",
"foaf:name": "Manu Sporny",
"foaf:homepage": "http://manu.sporny.org/",
"sioc:avatar": "http://twitter.com/account/profile_image/manusporny",
"myvocab:personality": "friendly"
}
The
@context
keyword
is
used
to
change
how
the
JSON-LD
processor
evaluates
key-value
pairs.
In
this
case,
it
was
used
to
map
one
string
('myvocab')
to
another
string,
which
is
interpreted
s
as
a
IRI
.
In
the
example
above,
the
myvocab
string
is
replaced
with
"
http://example.org/myvocab#
"
when
it
is
detected.
In
well
as
other
processing
instructions
for
the
example
above,
"
myvocab:personality
"
would
expand
to
"
http://example.org/myvocab#personality
".
JSON-LD
processor.
Contexts
may
be
specified
in-line.
This
mechanism
is
a
short-hand
for
RDF,
called
ensures
that
JSON-LD
documents
can
be
processed
when
a
CURIE,
and
provides
developers
an
unambiguous
way
to
map
any
JSON
value
JSON-LD
processor
does
not
have
access
to
RDF.
the
Web.
JSON-LD
strives
to
ensure
that
developers
don't
have
to
change
the
JSON
that
is
going
into
and
being
returned
from
their
Web
applications.
This
means
that
developers
can
also
specify
a
context
for
JSON
data
in
an
out-of-band
fashion
via
the
API.
The
API
is
described
later
in
this
document.
A
JSON-LD
aware
Web
Service
may
also
define
a
known
context.
For
example,
the
following
default
context
could
apply
to
all
incoming
Web
Service
calls
previously
accepting
only
JSON
data:
{
"@context":
{
"@vocab": "http://example.org/default-vocab#",
"@base": "http://example.org/baseurl/",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"dc": "http://purl.org/dc/terms/",
"foaf": "http://xmlns.com/foaf/0.1/",
"sioc": "http://rdfs.org/sioc/ns#",
"cc": "http://creativecommons.org/ns#",
"geo": "http://www.w3.org/2003/01/geo/wgs84_pos#",
"vcard": "http://www.w3.org/2006/vcard/ns#",
"cal": "http://www.w3.org/2002/12/cal/ical#",
"doap": "http://usefulinc.com/ns/doap#",
"Person": "http://xmlns.com/foaf/0.1/Person",
"name": "http://xmlns.com/foaf/0.1/name",
"homepage": "http://xmlns.com/foaf/0.1/homepage"
"@coerce":
{
"xsd:anyURI": ["rdf:type", "rdf:rest", "foaf:homepage", "foaf:member"],
"xsd:integer": "foaf:age"
}
}
}
The
@vocab
string
is
a
special
keyword
that
states
that
any
term
that
doesn't
resolve
to
a
term
or
a
prefix
should
will
be
appended
pre-loaded
for
all
calls
to
the
@vocab
IRI.
service.
This
is
done
to
ensure
that
terms
can
be
transformed
to
an
IRI
at
all
times.
The
@base
string
is
a
special
keyword
that
states
allows
services
that
any
relative
IRI
must
be
appended
to
the
string
specified
by
@base
.
The
@coerce
keyword
is
used
to
specify
type
coercion
rules
for
the
data.
For
each
key
in
the
map,
the
key
is
the
type
to
be
coerced
to
have
previously
been
publishing
and
the
value
is
the
vocabulary
term
receiving
JSON
data
to
be
coerced.
Type
coercion
for
the
key
xsd:anyURI
asserts
that
all
vocabulary
terms
listed
should
undergo
coercion
accept
JSON-LD
data
without
requiring
client
software
to
an
IRI,
including
@base
processing
for
relative
IRIs
and
CURIE
processing
for
compact
URI
Expressions
such
as
foaf:homepage
.
change.
The
following
example
describes
three
people
with
their
respective
names
If
a
set
of
terms
such
as,
name
,
homepage
,
and
homepages.
<div >
<ul>
<li >
<a >Bob</a>
</li>
<li >
<a >Eve</a>
</li>
<li >
<a >Manu</a>
</li>
</ul>
</div>
An
example
JSON-LD
implementation
is
described
below,
however,
there
avatar
,
are
other
ways
to
mark-up
this
information
such
defined
in
a
context,
and
that
the
context
is
not
repeated.
[
{
"@": "_:bnode1",
"a": "foaf:Person",
"foaf:homepage": "http://example.com/bob/",
"foaf:name": "Bob"
},
{
"@": "_:bnode2",
"a": "foaf:Person",
"foaf:homepage": "http://example.com/eve/",
"foaf:name": "Eve"
},
{
"@": "_:bnode3",
"a": "foaf:Person",
"foaf:homepage": "http://example.com/manu/",
"foaf:name": "Manu"
}
]
3.2
Microformats
The
following
example
uses
a
simple
Microformats
hCard
example
used
to
express
how
resolve
the
Microformat
is
represented
names
in
JSON-LD.
<div class="vcard">
<a class="url fn" href="http://tantek.com/">Tantek Çelik</a>
</div>
The
representation
of
the
hCard
expresses
JSON
objects,
machines
are
able
to
automatically
expand
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
.
something
meaningful
and
unambiguous,
like
this:
{"@context": { "vcard": "http://microformats.org/profile/hcard#vcard", "url": "http://microformats.org/profile/hcard#url", "fn": "http://microformats.org/profile/hcard#fn", "@coerce": { "xsd:anyURI": "url" } }, "@": "_:bnode1", "a": "vcard", "url": "http://tantek.com/", "fn": "Tantek Çelik""http://xmlns.com/foaf/0.1/name": "Manu Sporny", "http://xmlns.com/foaf/0.1/homepage": "http://manu.sporny.org" "http://rdfs.org/sioc/ns#avatar": "http://twitter.com/account/profile_image/manusporny" }
Note
that
the
JSON-LD
representation
of
the
Microdata
information
stays
true
to
the
desires
of
the
Microdata
community
Doing
this
allows
JSON
to
avoid
contexts
and
instead
refer
be
unambiguously
machine-readable
without
requiring
developers
that
use
JSON
to
items
by
drastically
change
their
full
IRI.
workflow.
JSON-LD
is
designed
to
ensure
that
most
Linked
Data
concepts
can
be
marked
up
in
a
way
that
is
simple
to
understand
and
author
by
Web
developers.
In
many
cases,
Javascript
objects
regular
JSON
markup
can
become
Linked
Data
with
the
simple
addition
of
a
context.
Since
RDF
is
also
an
important
sub-community
of
the
Linked
Data
movement,
it
is
important
that
all
RDF
concepts
As
more
JSON-LD
features
are
well-represented
in
this
specification.
This
section
details
how
each
RDF
concept
can
be
expressed
in
JSON-LD.
used,
more
semantics
are
added
to
the
JSON
markup.
Expressing
IRIs
are
fundamental
to
Linked
Data
as
that
is
how
most
subjects
subject
s
and
many
objects
object
are
identified.
named.
IRIs
can
be
expressed
in
a
variety
of
different
ways
in
JSON-LD.
@context
and
when
dealing
with
keys
that
start
with
the
@
@subject
character.
@
@subject
,
if
it
is
a
string.
a
@type
.
@iri
keyword.
@coerce
rules
in
effect
for
@iri
.
An
example
of
IRI
generation
for
a
IRIs
can
be
expressed
directly
in
the
key
outside
of
a
@context
:
position
like
so:
{
...
"http://xmlns.com/foaf/0.1/name": "Manu Sporny",
...
}
In
the
example
above,
the
key
http://xmlns.com/foaf/0.1/name
is
interpreted
as
an
IRI,
as
opposed
to
being
interpreted
as
a
string..
Term expansion occurs for IRIs if a term is defined within the active context :
{ "@context": {"name": "http://xmlns.com/foaf/0.1/name"}, ... "name": "Manu Sporny", ... }
CURIE
expansion
also
occurs
for
keys
Prefix
es
are
expanded
when
used
in
JSON-LD:
keys:
{ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"}, ... "foaf:name": "Manu Sporny", ... }
foaf:name
above
will
automatically
expand
out
to
the
IRI
http://xmlns.com/foaf/0.1/name
.
An
IRI
is
generated
when
a
value
is
associated
with
a
key
using
the
@iri
keyword:
{
...
"foaf:homepage": { "@iri": "http://manu.sporny.org" }
...
}
If
type
coercion
rules
are
specified
in
the
@context
for
a
particular
vocabulary
term,
an
IRI
is
generated:
{ "@context":{{ ... "@coerce": {"xsd:anyURI": "foaf:homepage" }"@iri": "foaf:homepage" } } ..."foaf:homepage": "http://manu.sporny.org","foaf:homepage": "http://manu.sporny.org/", ... }
Even
though
the
value
http://manu.sporny.org/
is
a
string,
the
type
coercion
rules
will
transform
the
value
into
an
IRI
when
processed
by
a
JSON-LD
Processor
A
subject
is
declared
using
the
key.
The
subject
is
the
first
piece
of
information
needed
by
the
JSON-LD
processor
in
order
to
create
the
(subject,
property,
object)
tuple,
also
known
as
a
triple.
@
@subject
{ ..."","@subject": "http://example.org/people#joebob", ... }
The
example
above
would
set
the
subject
to
the
IRI
http://example.org/people#joebob
.
The
type
of
a
particular
subject
can
be
specified
using
the
key.
Specifying
the
type
in
this
way
will
generate
a
triple
of
the
form
(subject,
type,
type-url).
a
@type
{ ..."@": "http://example.org/people#joebob", "","@subject": "http://example.org/people#joebob", "@type": "http://xmlns.com/foaf/0.1/Person", ... }
The example above would generate the following triple if the JSON-LD document is mapped to RDF (in N-Triples notation):
<http://example.org/people#joebob> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
Regular
text
strings
are
called
a
strings,
also
refered
to
as
plain
literal
in
RDF
and
s,
are
easily
expressed
using
regular
JSON
strings.
{
...
"foaf:name": "Mark Birbeck",
...
}
JSON-LD
makes
an
assumption
that
plain
literal
s
strings
with
associated
language
encoding
information
is
are
not
very
common
when
used
in
JavaScript
and
Web
Services.
Thus,
it
takes
a
little
more
effort
to
express
plain
literals
in
a
specified
language.
strings
with
associated
language
information.
{
...
"foaf:name":
{
"@literal": "花澄",
"@language": "ja"
}
...
}
The
example
above
would
generate
a
plain
literal
for
花澄
and
associate
the
ja
language
tag
code
with
the
triple
that
is
generated.
Languages
must
be
expressed
in
[
BCP47
]
format.
A
value
with
an
associated
datatype,
also
known
as
a
typed
literal
,
is
indicated
by
attaching
a
IRI
to
the
end
of
associating
a
plain
literal
,
and
this
with
an
IRI
which
indicates
the
typed
literal's
datatype.
Literals
Typed
literals
may
be
typed
expressed
in
JSON-LD
in
three
ways:
@coerce
keyword.
The
first
example
uses
the
@coerce
keyword
to
express
a
typed
literal:
{
"@context":
{
{
"dc": "http://purl.org/dc/terms/",
"xsd": "http://www.w3.org/2001/XMLSchema#"
"@coerce":
{
"xsd:dateTime": "dc:modified"
}
}
...
"dc:modified": "2010-05-29T14:17:39+02:00",
...
}
The second example uses the expanded form for specifying objects:
{
...
"dc:modified":
{
"@literal": "2010-05-29T14:17:39+02:00",
"@datatype": "xsd:dateTime"
}
...
}
Both
examples
above
would
generate
an
object
with
the
literal
value
of
2010-05-29T14:17:39+02:00
and
the
datatype
of
http://www.w3.org/2001/XMLSchema#dateTime
.
The third example uses a built-in native JSON type, a number, to express a datatype:
{
...
"@subject": "http://example.org/people#joebob",
"foaf:age": 31
...
}
The example above would generate the following triple:
<http://example.org/people#joebob> <http://xmlns.com/foaf/0.1/age> "31"^^<http://www.w3.org/2001/XMLSchema#integer> .
A JSON-LD author can express multiple triples in a compact way by using arrays. If a subject has multiple values for the same property, the author may express each property as an array.
In JSON-LD, Multiple objects on a property are not ordered. This is because typically graphs are not inherently ordered data structures. To see more on creating ordered collections in JSON-LD, see Lists .
{ ..."@": "http://example.org/people#joebob","@subject": "http://example.org/people#joebob", "foaf:nick": ["joe", "bob", "jaybee"], ... }
The markup shown above would generate the following triples:
<http://example.org/people#joebob> <http://xmlns.com/foaf/0.1/nick> "joe" . <http://example.org/people#joebob> <http://xmlns.com/foaf/0.1/nick> "bob" . <http://example.org/people#joebob> <http://xmlns.com/foaf/0.1/nick> "jaybee" .
Multiple typed literal s may also be expressed using the expanded form for objects:
{ ..."@": "http://example.org/articles/8","@subject": "http://example.org/articles/8", "dcterms:modified": [ { "@literal": "2010-05-29T14:17:39+02:00", "@datatype": "xsd:dateTime" }, { "@literal": "2010-05-30T09:21:28-04:00", "@datatype": "xsd:dateTime" } ] ... }
The markup shown above would generate the following triples:
<http://example.org/articles/8> <http://purl.org/dc/terms/modified> "2010-05-29T14:17:39+02:00"^^http://www.w3.org/2001/XMLSchema#dateTime . <http://example.org/articles/8> <http://purl.org/dc/terms/modified> "2010-05-30T09:21:28-04:00"^^http://www.w3.org/2001/XMLSchema#dateTime .
At
times,
it
becomes
necessary
to
be
able
to
express
information
without
being
able
Expansion
is
the
process
of
taking
a
JSON-LD
document
and
applying
a
context
such
that
all
IRI,
datatypes,
and
literal
values
are
expanded
so
that
the
context
is
no
longer
necessary.
JSON-LD
document
expansion
is
typically
used
when
re-mapping
JSON-LD
documents
to
specify
application-specific
JSON
documents
or
as
a
part
of
the
subject.
Typically,
this
Normalization
process.
For example, assume the following JSON-LD input document:
{ "name": "Manu Sporny", "homepage": "http://manu.sporny.org/", "@context": { "name": "http://xmlns.com/foaf/0.1/name", "homepage": "http://xmlns.com/foaf/0.1/homepage", "@coerce": { "@iri": "homepage" } } }
Running the JSON-LD Expansion algorithm against the JSON-LD input document provided above would result in the following output:
{ "http://xmlns.com/foaf/0.1/name": "Manu Sporny", "http://xmlns.com/foaf/0.1/homepage": { "@iri": "http://manu.sporny.org/" } }
Compaction
is
where
blank
nodes
come
into
play.
In
JSON-LD,
blank
node
identifiers
the
process
of
taking
a
JSON-LD
document
and
applying
a
context
such
that
the
most
compact
form
of
the
document
is
generated.
JSON
is
typically
expressed
in
a
very
compact,
key-value
format.
That
is,
full
IRIs
are
automatically
created
if
rarely
used
as
keys.
At
times,
a
subject
JSON-LD
document
may
be
received
that
is
not
specified
using
in
its
most
compact
form.
JSON-LD,
via
the
@
keyword.
However,
authors
may
name
blank
nodes
by
using
API,
provides
a
way
to
compact
a
JSON-LD
document.
For
example,
assume
the
special
_
CURIE
prefix.
following
JSON-LD
input
document:
{... "@": "", ..."http://xmlns.com/foaf/0.1/name": "Manu Sporny", "http://xmlns.com/foaf/0.1/homepage": { "@iri": "http://manu.sporny.org/" } }
The
example
Additionally,
assume
the
following
developer-supplied
JSON-LD
context:
{ "name": "http://xmlns.com/foaf/0.1/name", "homepage": "http://xmlns.com/foaf/0.1/homepage", "@coerce": { "@iri": ["homepage"] } }
Running
the
JSON-LD
Compaction
algorithm
given
the
context
supplied
above
against
the
JSON-LD
input
document
provided
above
would
set
result
in
the
subject
following
output:
{ "name": "Manu Sporny", "homepage": "http://manu.sporny.org/", "@context": { "name": "http://xmlns.com/foaf/0.1/name", "homepage": "http://xmlns.com/foaf/0.1/homepage", "@coerce": { "@iri": "homepage" } } }
The
compaction
algorithm
also
enables
the
developer
to
map
any
expanded
format
into
an
application-specific
compacted
format.
While
the
context
provided
above
mapped
to
name
,
it
could
have
also
mapped
it
to
any
arbitrary
string
provided
by
the
developer.
_:foo
,
which
http://xmlns.com/foaf/0.1/name
A
JSON-LD
document
is
a
representation
of
a
directed
graph.
A
single
directed
graph
can
have
many
different
serializations,
each
expressing
exactly
the
same
information.
Developers
typically
work
with
trees,
also
called
associative
arrays,
when
dealing
with
JSON.
While
mapping
a
graph
to
a
tree
can
be
done,
the
layout
of
the
end
result
must
be
specified
in
advance.
A
Frame
can
then
be
used
later
by
a
developer
on
a
JSON-LD
document
to
specify
a
deterministic
layout
for
a
graph.
Framing is the process of taking a JSON-LD document, which expresses a graph of information, and applying a specific graph layout (called a Frame ).
The JSON-LD document below expresses a library, a book and a chapter:
{ "@coerce": { "dc": "http://purl.org/dc/terms/", "ex": "http://example.org/" }, "@subject": [{ "@subject": "http://example.org/library", "@type": "ex:Library", "ex:contains": "http://example.org/library/the-republic" }, { "@subject": "http://example.org/library/the-republic", "@type": "ex:Book", "dc:creator": "Plato", "dc:title": "The Republic", "ex:contains": "http://example.org/library/the-republic#introduction" }, { "@subject": "http://example.org/library/the-republic#introduction", "@type": "ex:Chapter", "dc:description": "An introductory chapter on The Republic.", "dc:title": "The Introduction" }], "@context": { "@coerce": { "@iri": "ex:contains" }, "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#" } }
Developers typically like to operate on items in a hierarchical, tree-based fashion. Ideally, a developer would want the data above sorted into top-level libraries, then the books that are contained in each library, and then the chapters contained in each book. To achieve that layout, the developer can define the following frame :
{ "@context": { "dc": "http://purl.org/dc/elements/1.1/", "ex": "http://example.org/vocab#" }, "@type": "ex:Library", "ex:contains": { "@type": "ex:Book", "ex:contains": { "@type": "ex:Chapter" } } }
When
the
framing
algorithm
is
run
against
the
previously
defined
JSON-LD
markup
document,
paired
with
the
frame
above,
the
following
JSON-LD
document
is
the
end
result:
{ "@context": { "ex": "http://example.org/vocab#", "dc": "http://purl.org/dc/terms/", } "@subject": "http://example.org/library", "@type": "ex:Library", "ex:contains": { "@subject": "http://example.org/library/the-republic", "@type": "ex:Book", "dc:creator": "Plato", "dc:title": "The Republic", "ex:contains": { "@subject": "http://example.org/library/the-republic#introduction", "@type": "ex:Chapter", "dc:description": "An introductory chapter on The Republic.", "dc:title": "The Introduction" }, }, }
The
JSON-LD
framing
algorithm
allows
developers
to
refer
back
query
by
example
and
force
a
specific
tree
layout
to
the
named
blank
node.
a
JSON-LD
document.
JSON-LD
has
a
number
of
features
that
provide
functionality
above
and
beyond
the
core
functionality
provided
by
RDF.
described
above.
The
following
sections
outline
the
features
that
are
specific
to
JSON-LD.
Since JSON is capable of expressing typed information such as doubles, integers, and boolean values. As demonstrated below, JSON-LD utilizes that information to create typed literal s:
{ ... // The following two values are automatically converted to a type of xsd:double // and both values are equivalent to each other. "measure:cups": 5.3, "measure:cups": 5.3e0, // The following value is automatically converted to a type of xsd:double as well "space:astronomicUnits": 6.5e73, // The following value should never be converted to a language-native type "measure:stones": { "@literal": "4.8", "@datatype": "xsd:decimal" }, // This value is automatically converted to having a type of xsd:integer "chem:protons": 12, // This value is automatically converted to having a type of xsd:boolean "sensor:active": true, ... }
When
dealing
with
a
number
of
modern
programming
languages,
including
JavaScript
ECMA-262,
there
is
no
distinction
between
xsd:decimal
and
xsd:double
values.
That
is,
the
number
5.3
and
the
number
5.3e0
are
treated
as
if
they
were
the
same.
When
converting
from
JSON-LD
to
a
language-native
format
and
back,
datatype
information
is
lost
in
a
number
of
these
languages.
Thus,
one
could
say
that
5.3
is
a
xsd:decimal
and
5.3e0
is
an
xsd:double
in
JSON-LD,
but
when
both
values
are
converted
to
a
language-native
format
the
datatype
difference
between
the
two
is
lost
because
the
machine-level
representation
will
almost
always
be
a
double
.
Implementers
should
be
aware
of
this
potential
round-tripping
issue
between
xsd:decimal
and
xsd:double
.
Specifically
objects
with
a
datatype
of
xsd:decimal
must
not
be
converted
to
a
language
native
type.
JSON-LD
supports
the
coercion
of
types
values
to
ensure
that
the
zero-edit
goal
of
JSON-LD
can
be
accomplished.
particular
data
types.
Type
coercion
allows
someone
deploying
JSON-LD
to
coerce
and
the
incoming
or
outgoing
types
to
the
proper
RDF
data
type
based
on
a
mapping
of
data
type
IRIs
to
RDF
property
types.
Using
type
conversion,
coercion,
one
may
convert
simple
JSON
data
to
properly
typed
RDF
data.
The example below demonstrates how a JSON-LD author can coerce values to plain literal s, typed literal s and IRIs.
{ "@context": { "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "xsd": "http://www.w3.org/2001/XMLSchema#", "name": "http://xmlns.com/foaf/0.1/name", "age": "http://xmlns.com/foaf/0.1/age", "homepage": "http://xmlns.com/foaf/0.1/homepage", "@coerce": { "xsd:integer": "age","xsd:anyURI": "homepage","@iri": "homepage" } }, "name": "John Smith", "age": "41", "homepage": "http://example.org/home/" }
The example above would generate the following triples:
_:bnode1 <http://xmlns.com/foaf/0.1/name> "John Smith" . _:bnode1 <http://xmlns.com/foaf/0.1/age> "41"^^http://www.w3.org/2001/XMLSchema#integer . _:bnode1 <http://xmlns.com/foaf/0.1/homepage> <http://example.org/home/> .
The
JSON-LD
Processing
Model
describes
processing
rules
for
extracting
RDF
from
Object
chaining
is
a
JSON-LD
document.
Note
feature
that
many
uses
allows
an
author
to
use
the
definition
of
JSON-LD
may
not
require
generation
of
RDF.
objects
as
property
values.
This
is
a
commonly
used
mechanism
for
creating
a
parent-child
relationship
between
two
subject
s.
The
processing
algorithm
described
in
this
section
is
provided
in
order
to
demonstrate
how
one
might
implement
example
shows
an
two
subjects
related
by
a
JSON-LD
processor.
Conformant
implementations
are
only
required
to
produce
the
same
type
and
number
of
triples
during
property
from
the
output
process
and
are
not
required
to
implement
first
subject:
{ ... "foaf:name": "Manu Sporny", "foaf:knows": { "@type": "foaf:Person", "foaf:name": "Gregg Kellogg", } ... }
An
object
definition,
like
the
algorithm
exactly
one
used
above,
may
be
used
as
described.
The
Processing
Algorithm
is
a
work
JSON
value
at
any
point
in
progress.
JSON-LD.
This
section
is
non-normative.
JSON-LD
is
intended
At
times,
it
becomes
necessary
to
have
an
easy
be
able
to
parse
grammar
that
closely
models
existing
practice
in
using
JSON
for
describing
object
representations.
This
allows
express
information
without
being
able
to
specify
the
use
subject.
Typically,
this
type
of
existing
libraries
for
parsing
JSON
in
a
document-oriented
fashion,
node
is
called
an
unlabeled
node
or
can
allow
for
stream-based
parsing
similar
to
SAX.
As
with
other
grammars
used
for
describing
linked
data,
a
key
concept
is
that
of
blank
node.
In
JSON-LD,
unlabeled
node
identifiers
are
automatically
created
if
a
resource
.
Resources
subject
is
not
specified
using
the
@subject
keyword.
However,
authors
may
be
of
three
basic
types:
IRI
s,
for
describing
externally
named
entities,
BNodes
,
resources
provide
identifiers
for
unlabeled
nodes
by
using
the
special
_
(underscore)
CURIE
prefix.
{
...
"@subject": "_:foo",
...
}
The
example
above
would
set
the
subject
to
_:foo
,
which
an
external
name
does
not
exist,
or
can
then
be
used
later
on
in
the
JSON-LD
markup
to
refer
back
to
the
unlabeled
node.
This
practice,
however,
is
not
known,
and
Literals,
which
describe
terminal
entities
such
as
strings,
dates
and
other
representations
having
usually
frowned
upon
when
generating
Linked
Data.
If
a
lexical
representation
possibly
including
an
explicit
language
or
datatype.
developer
finds
that
they
refer
to
the
unlabeled
node
more
than
once,
they
should
consider
naming
the
node
using
a
resolve-able
IRI.
Data
described
with
JSON-LD
may
allows
all
of
the
syntax
keywords,
except
for
@context
,
to
be
considered
overridden.
This
feature
allows
more
legacy
JSON
content
to
be
the
representation
of
a
graph
made
up
of
subject
and
object
resources
related
via
a
predicate
resource.
However,
specific
implementations
may
choose
supported
by
JSON-LD.
It
also
allows
developers
to
operate
on
design
domain-specific
implementations
using
only
the
document
as
JSON-LD
context.
{ "@context": { "url": "@subject", "a": "@type", "name": "http://schema.org/name" }, "url": "http://example.com/about#gregg", "a": "http://schema.org/Person", "name": "Gregg Kellogg" }
In
the
example
above,
the
@subject
and
@type
keywords
have
been
overridden
by
url
and
a
normal
JSON
description
of
objects
having
attributes.
,
respectively.
Normalization
is
specified
to
the
process
of
taking
JSON-LD
processing
algorithm
before
processing
begins.
default
graph
input
and
performing
a
deterministic
transformation
on
that
input
that
results
in
a
JSON-LD
output
that
any
conforming
JSON-LD
processor
would
have
generated
given
the
destination
same
input.
The
problem
is
a
fairly
difficult
technical
problem
to
solve
because
it
requires
a
directed
graph
for
to
be
ordered
into
a
set
of
nodes
and
edges
in
a
deterministic
way.
This
is
easy
to
do
when
all
triples
generated
by
JSON-LD
markup.
active
subject
of
the
currently
active
subject
that
nodes
have
unique
names,
but
very
difficult
to
do
when
some
of
the
processor
should
use
nodes
are
not
labeled.
Normalization
is
useful
when
comparing
two
graphs
against
one
another,
when
generating
triples.
active
property
the
currently
active
property
that
the
processor
should
use
a
detailed
list
of
differences
between
two
graphs,
and
when
generating
triples.
active
object
the
currently
active
object
that
the
processor
should
use
a
cryptographic
digital
signature
for
information
contained
in
a
graph
or
when
generating
triples.
active
context
a
context
that
is
used
to
resolve
CURIEs
while
hash
of
the
processing
algorithm
information
contained
in
a
graph.
The
example
below
is
running.
an
un-normalized
JSON-LD
document:
{ "name": "Manu Sporny", "homepage": "http://manu.sporny.org/", "@context": { "name": "http://xmlns.com/foaf/0.1/name", "homepage": "http://xmlns.com/foaf/0.1/homepage", "xsd": "http://www.w3.org/2001/XMLSchema#", "@coerce": { "@iri": ["homepage"] } } }
The
active
context
example
below
is
the
context
contained
within
normalized
form
of
the
processor
state
.
local
context
a
context
that
JSON-LD
document
above:
Whitespace
is
specified
at
the
JSON
associative-array
level,
specified
via
used
below
to
aid
readability.
The
normalization
algorithm
for
JSON-LD
remove
all
unnecessary
whitespace
in
the
@context
keyword.
processor
state
fully
normalized
form.
[{ "@subject": { "@iri": "_:c14n0" }, "http://xmlns.com/foaf/0.1/homepage": { "@iri": "http://manu.sporny.org/" }, "http://xmlns.com/foaf/0.1/name": "Manu Sporny" }]
Notice
how
all
of
the
processor
state
,
which
includes
term
s
have
been
expanded
and
sorted
in
alphabetical
order.
Also,
notice
how
the
active
context
,
current
subject
,
and
current
property
.
The
processor
state
is
managed
as
a
stack
has
been
labeled
with
elements
from
the
previous
processor
state
copied
into
a
new
processor
state
when
entering
a
new
associative
array.
blank
node
identifier
.
Normalization
ensures
that
any
arbitrary
graph
containing
exactly
the
same
information
would
be
normalized
to
exactly
the
same
form
shown
above.
All algorithms described in this section are intended to operate on language-native data structures. That is, the serialization to a text-based JSON document isn't required as input or output to any of these algorithms and language-native data structures must be used where applicable.
JSON-LD specifies a number of syntax tokens and keywords that are using in all algorithms described in this section:
@context
@base
@profile
A
reference
to
a
remote
context
description
used
to
set
the
local
context
.
@vocab
@coerce
@literal
@iri
@language
@datatype
:
@
@subject
a
@type
@type
@context
Processing
of
JSON-LD
data
structure
is
managed
recursively
using
a
process
described
in
Sequence
.
recursively.
During
processing,
each
rule
is
applied
using
information
provided
by
the
active
context
.
Processing
begins
by
pushing
a
new
processor
state
onto
the
processor
state
stack
and
initializing
the
active
context
with
the
default
initial
context
.
If
a
local
context
is
encountered,
information
from
the
local
context
is
merged
into
the
active
context
.
The active context is used for expanding keys and values of an associative array (or elements of a list (see List Processing )).
A
local
context
is
identified
within
an
associative
array
having
a
key
of
@context
with
string
or
an
associative
array
value.
When
processing
a
local
context
,
special
processing
rules
apply:
@base
key,
it
must
have
a
value
of
a
simple
string
with
the
lexical
form
of
Turtle
allows
@base
to
perform
term
mapping
as
described
in
be
relative.
If
we
did
this,
we
would
have
to
add
IRI
Processing
Expansion
.
@vocab
key,
it
must
have
a
value
of
a
simple
string
with
the
lexical
form
of
@coerce
key,
it
must
have
a
value
of
an
associative
array.
@coerce
mapping
to
the
local
context
performing
IRI
Expansion
on
the
associated
value(s).
@coerce
mapping
into
the
active
context
's
@profile
@coerce
@coerce
mapping
from
the
local
context
to
the
active
context
overwriting
any
duplicate
values.
Map
each
key-value
pair
in
the
local
context
's
@coerce
mapping
into
the
active
context
's
@coerce
mapping,
overwriting
any
duplicate
values
in
the
active
context
's
@coerce
mapping.
The
@coerce
mapping
has
a
either
of
a
single
CURIE
or
of
an
array
of
CURIEs.
When
merging
with
an
existing
mapping
in
the
active
context
,
map
all
CURIE
values
to
array
form
and
replace
with
the
union
of
the
value
from
the
local
context
and
the
value
of
the
active
context
.
If
the
result
is
an
array
with
a
single
CURIE,
the
processor
may
represent
this
as
a
string
value.
Object
chaining
The
initial
context
is
a
JSON-LD
feature
that
allows
an
author
to
use
the
definition
of
JSON-LD
objects
initialized
as
property
values.
This
follows:
@base
is
set
using
@coerce
is
set
with
a
@iri
to
@type
.{... "foaf:name": "Manu Sporny", "": { "", "", } ..."@base": document-location, "@context": { "@iri": "@type" } }
Keys and some values are evaluated to produce an IRI. This section defines an algorithm for transforming a value representing an IRI into an actual IRI.
IRIs
may
be
represented
as
an
explicit
string,
or
as
a
CURIE,
as
a
value
relative
to
@base
or
@vocab
.
CURIEs are defined more formally in [ RDFA-CORE ] section 6 "CURIE Syntax Definition" . Generally, a CURIE is composed of a prefix and a suffix separated by a ':'. In JSON-LD, either the prefix may be the empty string, denoting the default prefix .
The
procedure
algorithm
for
generating
an
IRI
is:
@coerce
mapping)
and
the
active
context
has
a
@vocab
mapping,
join
the
mapped
value
to
the
suffix
using
@base
mapping,
join
the
mapped
value
to
the
suffix
using
the
method
described
in
[
Some keys and values are expressed using IRIs. This section defines an algorithm for transforming an IRI to a compact IRI using the term s and prefix es specified in the local context .
The algorithm for generating a compacted IRI is:
Some values in JSON-LD can be expressed in a compact form. These values are required to be expanded at times when processing JSON-LD documents.
The algorithm for expanding a value is:
@iri
,
expand
the
value
by
adding
a
new
key-value
pair
where
the
key
is
@iri
and
the
value
is
the
expanded
IRI
according
to
the
IRI
Expansion
rules.
@literal
and
the
unexpanded
value.
The
second
key-value
pair
will
be
@datatype
and
the
associated
coercion
datatype
expanded
according
to
the
IRI
Expansion
rules.
Some values, such as IRIs and typed literals, may be expressed in an expanded form in JSON-LD. These values are required to be compacted at times when processing JSON-LD documents.
The algorithm for compacting a value is:
@iri
,
the
compacted
value
is
the
value
associated
with
the
@iri
key,
processed
according
to
the
IRI
Compaction
steps.
@literal
key.
This algorithm is a work in progress, do not implement it.
As stated previously, expansion is the process of taking a JSON-LD input and expanding all IRIs and typed literals to their fully-expanded form. The output will not contain a single context declaration and will have all IRIs and typed literals fully expanded.
This algorithm is a work in progress, do not implement it.
As stated previously, compaction is the process of taking a JSON-LD input and compacting all IRIs using a given context. The output will contain a single top-level context declaration and will only use term s and prefix es and will ensure that all typed literals are fully compacted.
This algorithm is a work in progress, do not implement it.
A JSON-LD document is a representation of a directed graph. A single directed graph can have many different serializations, each expressing exactly the same information. Developers typically don't work directly with graphs, but rather, prefer trees when dealing with JSON. While mapping a graph to a tree can be done, the layout of the end result must be specified in advance. This section defines an algorithm for mapping a graph to a tree given a frame .
The framing algorithm takes JSON-LD input that has been normalized according to the Normalization Algorithm ( normalized input ), an input frame that has been expanded according to the Expansion Algorithm ( expanded frame ), and a number of options and produces JSON-LD output . The following series of steps is the recursive portion of the framing algorithm:
null
.
Invalid
Frame
Format
exception.
Add
each
matching
item
from
the
normalized
input
to
the
matches
array
and
decrement
the
match
limit
by
1
if:
rdf:type
that
exists
in
the
item's
list
of
rdf:type
s.
Note:
the
rdf:type
can
be
an
array,
but
only
one
value
needs
to
be
in
common
between
the
item
and
the
expanded
frame
for
a
match.
rdf:type
property,
but
every
property
in
the
expanded
frame
exists
in
the
item.
@embed
keyword,
set
the
object
embed
flag
to
its
value.
If
the
match
frame
contains
an
@explicit
keyword,
set
the
explicit
inclusion
flag
to
its
value.
Note:
if
the
keyword
exists,
but
the
value
is
neither
true
or
false
,
set
the
associated
flag
to
true
.
@subject
property,
replace
the
item
with
the
value
of
the
@subject
property.
@subject
property,
and
its
IRI
is
in
the
map
of
embedded
subjects
,
throw
a
Duplicate
Embed
exception.
@subject
property
and
its
IRI
is
not
in
the
map
of
embedded
subjects
:
@subject
.
rdf:type
:
@iri
value
that
exists
in
the
normalized
input
,
replace
the
object
in
the
recusion
input
list
with
a
new
object
containing
the
@subject
key
where
the
value
is
the
value
of
the
@iri
,
and
all
of
the
other
key-value
pairs
for
that
subject.
Set
the
recursion
match
frame
to
the
value
associated
with
the
match
frame
's
key.
Replace
the
value
associated
with
the
key
by
recursively
calling
this
algorithm
using
recursion
input
list
,
recursion
match
frame
as
input.
null
otherwise.
null
,
process
the
omit
missing
properties
flag
:
@omitDefault
keyword,
set
the
omit
missing
properties
flag
to
its
value.
Note:
if
the
keyword
exists,
but
the
value
is
neither
true
or
false
,
set
the
associated
flag
to
true
.
@default
keyword
is
set
in
the
property
frame
set
the
item's
value
to
the
value
of
@default
.
null
set
it
to
the
item,
otherwise,
append
the
item
to
the
JSON-LD
output
.This algorithm is a work in progress, do not implement it.
Normalization is the process of taking JSON-LD input and performing a deterministic transformation on that input that results in all aspects of the graph being fully expanded and named in the JSON-LD output . The normalized output is generated in such a way that any conforming JSON-LD processor will generate identical output given the same input. The problem is a fairly difficult technical problem to solve because it requires a directed graph to be ordered into a set of nodes and edges in a deterministic way. This is easy to do when all of the nodes have unique names, but very difficult to do when some of the nodes are not labeled.
In time, there may be more than one normalization algorithm that will need to be identified. For identification purposes, this algorithm is named UGNA2011 .
c14n
.
The
prefix
is
used
to
temporarily
name
nodes
during
the
normalization
algorithm
in
a
way
that
doesn't
collide
with
the
names
that
already
exist
as
well
as
the
names
that
will
be
generated
by
the
normalization
algorithm.
c14n
.
The
prefix
is
used
to
temporarily
name
nodes
during
the
normalization
algorithm
in
a
way
that
doesn't
collide
with
the
names
that
already
exist
as
well
as
the
names
that
will
be
generated
by
the
normalization
algorithm.
The normalization algorithm expands the JSON-LD input , flattens the data structure, and creates an initial set of names for all nodes in the graph. The flattened data structure is then processed by the node labeling algorithm in order to get a fully expanded and named list of nodes.
@subject
values
that
start
with
the
text
string
_:c14n
.
If
a
match
is
found,
rename
the
subject
and
all
references
to
the
subject
by
concatenating
_:
with
the
naming
base
string
and
a
unique
identifier,
such
as
an
incremented
counter
value.
@subject
,
name
it
by
concatenating
_:
with
the
naming
base
string
and
a
unique
identifier,
such
as
an
incremented
counter
value.
@subject
in
the
object.
@subject
key
associated
with
a
value
starting
with
_:
according
to
the
steps
in
the
Node
Labeling
Algorithm
.The node labeling algorithm takes the list of expanded nodes and sorts the list, deterministically naming all of the unlabeled nodes in the graph.
The shallow comparison algorithm takes two unlabeled nodes, alpha and beta , as input and determines which one should come first in a sorted list. The following algorithm determines the steps that are executed in order to determine the node that should come first in a list:
The object comparison algorithm is designed to compare two graph node property values, alpha and beta , against the other. The algorithm is useful when sorting two lists of graph node properties.
@literal
is
first.
@datatype
is
first.
@language
is
first.
@iri
is
first.
DeepCompare(bnodeA, bnodeB):
SerializeNode(bnode, mapping, dir):
SerializeCombos(top, mapping, mapped, notMapped, dir):
SerializeMapping(mapping): (This function incrementally updates the relation serialization for a mapping)
NameNode(bnode):
When
normalizing
xsd:double
values,
implementers
must
ensure
that
the
normalized
value
is
a
string.
In
order
to
generate
the
string
from
a
double
value,
output
equivalent
to
the
printf("%1.6e",
value)
function
in
C
must
be
used
where
"%1.6e"
is
the
string
formatter
and
value
is
the
value
to
be
converted.
To convert the a double value in JavaScript, implementers can use the following snippet of code:
// the variable 'value' below is the JavaScript native double value that is to be converted (value).toExponential(6).replace(/(e(?:\+|-))([0-9])$/, '$10$2')
When data needs to be normalized, JSON-LD authors should not use values that are going to undergo automatic conversion. This is due to the lossy nature of xsd:double values.
Round-tripping data can be problematic if we mix and match @coerce rules with JSON-native datatypes, like integers. Consider the following code example:
var myObj = { "@context" : { "number" : "http://example.com/vocab#number", "@coerce": { "xsd:nonNegativeInteger": "number" } }, "number" : 42 }; // Map the language-native object to JSON-LD var jsonldText = jsonld.normalize(myObj); // Convert the normalized object back to a JavaScript object var myObj2 = jsonld.parse(jsonldText);
At this point, myObj2 and myObj will have different values for the "number" value. myObj will be the number 42, while myObj2 will be the string "42". This type of data round-tripping error can bite developers. We are currently wondering if having a "coerce validation" phase in the parsing/normalization phases would be a good idea. It would prevent data round-tripping issues like the one mentioned above.
A JSON-LD document may be converted to any other RDF-compatible document format using the algorithm specified in this section.
The JSON-LD Processing Model describes processing rules for extracting RDF from a JSON-LD document. Note that many uses of JSON-LD may not require generation of RDF.
The processing algorithm described in this section is provided in order to demonstrate how one might implement a JSON-LD to RDF processor. Conformant implementations are only required to produce the same type and number of triples during the output process and are not required to implement the algorithm exactly as described.
The RDF Conversion Algorithm is a work in progress.
This section is non-normative.
JSON-LD is intended to have an easy to parse grammar that closely models existing practice in using JSON for describing object representations. This allows the use of existing libraries for parsing JSON in a document-oriented fashion, or can allow for stream-based parsing similar to SAX.
As with other grammars used for describing Linked Data , a key concept is that of a resource . Resources may be of three basic types: IRI s, for describing externally named entities, BNodes , resources for which an external name does not exist, or is not known, and Literals, which describe terminal entities such as strings, dates and other representations having a lexical representation possibly including an explicit language or datatype.
Data described with JSON-LD may be considered to be the representation of a graph made up of subject and object resources related via a property resource. However, specific implementations may choose to operate on the document as a normal JSON description of objects having attributes.
The
algorithm
below
is
designed
for
in-memory
implementations
with
random
access
to
associative
array
elements.
For
a
description
of
a
streaming
implementation,
see
Appendix
B
.
A conforming JSON-LD processor implementing RDF conversion must implement a processing algorithm that results in the same default graph that the following algorithm generates:
@context
key,
process
the
local
context
as
described
in
Context
.
@iri
key,
set
the
active
object
by
performing
IRI
@iri
really
just
behaves
the
same
as
@subject
,
consider
consolidating
them.
@literal
key,
set
the
active
object
to
a
literal
value
as
follows:
@datatype
key
after
performing
IRI
@datatype
.
@language
key,
use
it's
value
to
set
the
language
of
the
plain
literal.
@
@subject
key:
@
@subject
key,
set
the
active
object
to
newly
generated
blank
node
identifier
a
@type
,
set
the
active
property
to
rdf:type
.
@iri
coercion,
set
the
active
xsd:integer
or
xsd:double
,
depending
on
if
the
value
contains
a
fractional
and/or
an
exponential
component.
Generate
a
triple
using
the
active
subject
,
active
xsd:boolean
.
There are a few advanced concepts where it is not clear whether or not the JSON-LD specification is going to support the complexity necessary to support each concept. The entire section on Advanced Concepts should be considered as discussion points; it is merely a list of possibilities where all of the benefits and drawbacks have not been explored.
When serializing an RDF graph that contains two or more sections of the graph which are entirely disjoint, one must use an array to express the graph as two graphs. This may not be acceptable to some authors, who would rather express the information as one graph. Since, by definition, disjoint graphs require there to be two top-level objects, JSON-LD utilizes a mechanism that allows disjoint graphs to be expressed using a single graph.
Assume the following RDF graph:
<http://example.org/people#john> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> . <http://example.org/people#jane> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
Since the two subjects are entirely disjoint with one another, it is impossible to express the RDF graph above using a single JSON-LD associative array.
In JSON-LD, one can use the subject to express disjoint graphs as a single graph:
{"@":"@coerce": { "foaf": "http://xmlns.com/foaf/0.1/" }, "@subject": [ {"@": "http://example.org/people#john", "a": "foaf:Person""@subject": "http://example.org/people#john", "@type": "foaf:Person" }, {"@": "http://example.org/people#jane", "a": "foaf:Person""@subject": "http://example.org/people#jane", "@type": "foaf:Person" } ] }
A disjoint graph could also be expressed like so:
[ {"@": "http://example.org/people#john", "a": "foaf:Person""@subject": "http://example.org/people#john", "@type": "http://xmlns.com/foaf/0.1/Person" }, {"@": "http://example.org/people#jane", "a": "foaf:Person""@subject": "http://example.org/people#jane", "@type": "http://xmlns.com/foaf/0.1/Person" } ]
This
API
provides
a
clean
mechanism
that
enables
developers
to
convert
JSON-LD
data
into
a
format
that
is
easier
to
work
with
Because
graphs
do
not
describe
ordering
for
links
between
nodes,
multi-valued
properties
in
various
programming
languages.
JSON
do
not
provide
an
ordering
of
the
listed
objects.
For
example,
consider
the
following
simple
document:
{
...
"@subject": "http://example.org/people#joebob",
"foaf:nick": ["joe", "bob", "jaybee"],
...
}
This
results
in
three
triples
being
generated,
each
relating
the
data
into
subject
to
an
Graph,
which
is
compatible
individual
object,
with
the
RDF
Interfaces
API
specification
no
inherent
order.
To
address
this
issue,
RDF-based
languages,
such
as
[
RDF-INTERFACES
TURTLE
].
This
method
will
return
null
if
there
are
any
errors,
or
if
]
use
the
RDF
Interfaces
API
is
not
available
for
use.
Parameter
Type
Nullable
Optional
Description
jsonld
concept
of
an
(as
described
in
[
DOMString
rdf:List
✘
✘
The
JSON-LD
string
to
parse
into
the
RDFGraph.
callback
JSONLDParserCallback
RDF-SCHEMA
✔
✔
A
callback
that
is
called
whenever
]).
This
uses
a
processing
error
occurs
on
the
given
JSON-LD
string.
No
exceptions.
Return
type:
Graph
toProjection
Parses
sequence
of
unlabeled
nodes
with
properties
describing
a
value,
a
null-terminated
next
property.
Without
specific
syntactical
support,
this
could
be
represented
in
JSON-LD
text
into
an
RDF
API
Projection
object
as
specified
by
follows:
{ ... "@subject": "http://example.org/people#joebob", "foaf:nick": {, "@first": "joe", "@rest": { "@first": "bob", "@rest": { "@first": "jaybee", "@rest": "@nil" } } } }, ... }
As
this
notation
is
rather
unwieldy
and
the
RDF
API
specification
[
RDF-API
].
If
there
are
any
errors,
null
notion
of
ordered
collections
is
returned.
Parameter
Type
Nullable
Optional
Description
jsonld
DOMString
✘
✘
The
JSON-LD
string
rather
important
in
data
modeling,
it
is
useful
to
parse
into
have
specific
language
support.
In
JSON-LD,
a
list
may
be
represented
using
the
Projection.
template
object
@list
✔
✘
The
Projection
template
to
use
when
building
keyword
as
follows:
{
...
"@subject": "http://example.org/people#joebob",
"foaf:nick": {"@list": ["joe", "bob", "jaybee"]},
...
}
This
describes
the
Projection.
subject
DOMString
✔
✘
The
subject
to
use
when
building
the
Projection.
callback
JSONLDParserCallback
✔
✔
A
callback
that
of
this
array
as
being
ordered,
and
order
is
called
whenever
maintained
through
normalization
and
RDF
conversion.
If
every
use
of
a
processing
error
occurs
on
the
given
JSON-LD
string.
No
exceptions.
Return
type:
object
The
JSONLDParserCallback
multi-valued
property
is
called
whenever
a
processing
error
occurs
on
input
data.
list,
this
may
be
abbreviated
by
adding
an
@coerce
term:
{ "@context": { ... "@context": { "@list": ["foaf:nick"] } }, ... "@subject": "http://example.org/people#joebob", "foaf:nick": ["joe", "bob", "jaybee"], ... }
TBD.
TBD.
To
support
RDF
Conversion
of
key-value
pairs
that
should
be
converted
to
a
JSON-LD
string.
It
is
assumed
that
a
map
already
exists
for
the
data.
No
exceptions.
Return
type:
DOMString
The
Normalization
lists,
RDF
Conversion
Algorithm
This
algorithm
is
very
rough,
untested,
and
probably
contains
many
bugs.
Use
at
your
own
risk.
It
will
change
in
the
coming
months.
The
JSON-LD
normalization
algorithm
is
updated
as
follows:
@context
@list
key
and
@list
coercion,
and
the
rdf:first
and
rdf:next
,
terminating
the
rdf:nil
using
the
rdf:nil
.
rdf:first
as
the
active
property
.
rdf:nil
.
rdf:rest
and
rest
blank
node
identifier
.
The
JSON-LD
markup
examples
below
demonstrate
how
JSON-LD
can
be
used
to
express
semantic
data
marked
up
in
other
languages
such
as
RDFa,
Microformats,
and
Microdata.
These
sections
are
merely
provided
as
proof
that
contain
non-named
blank
nodes
JSON-LD
is
supported.
very
flexible
in
what
it
can
express
across
different
Linked
Data
approaches.
After
the
code
in
the
The
following
example
above
has
executed,
the
jsonldText
value
will
be
(line-breaks
added
for
readability):
describes
three
people
with
their
respective
names
and
homepages.
[{"http://xmlns.com/foaf/0.1/age":{"@datatype":"http://www.w3.org/2001/XMLSchema#nonNegativeInteger","@literal":"42"}, "http://xmlns.com/foaf/0.1/homepage":{"@iri":"http://example.org/people/joe"}, "http://xmlns.com/foaf/0.1/name":"Joe Jackson"}]<div prefix="foaf: http://xmlns.com/foaf/0.1/"> <ul> <li typeof="foaf:Person"> <a rel="foaf:homepage" href="http://example.com/bob/" property="foaf:name" >Bob</a> </li> <li typeof="foaf:Person"> <a rel="foaf:homepage" href="http://example.com/eve/" property="foaf:name" >Eve</a> </li> <li typeof="foaf:Person"> <a rel="foaf:homepage" href="http://example.com/manu/" property="foaf:name" >Manu</a> </li> </ul> </div>
When
normalizing
xsd:double
values,
implementers
must
ensure
An
example
JSON-LD
implementation
is
described
below,
however,
there
are
other
ways
to
mark-up
this
information
such
that
the
normalized
value
context
is
not
repeated.
{ "@context": { "foaf": "http://xmlns.com/foaf/0.1/"}, "@subject": [ { "@subject": "_:bnode1", "@type": "foaf:Person", "foaf:homepage": "http://example.com/bob/", "foaf:name": "Bob" }, { "@subject": "_:bnode2", "@type": "foaf:Person", "foaf:homepage": "http://example.com/eve/", "foaf:name": "Eve" }, { "@subject": "_:bnode3", "@type": "foaf:Person", "foaf:homepage": "http://example.com/manu/", "foaf:name": "Manu" } ] }
The
following
example
uses
a
string.
In
order
simple
Microformats
hCard
example
to
generate
express
how
the
string
from
a
double
value,
output
equivalent
to
Microformat
is
represented
in
JSON-LD.
<div class="vcard"> <a class="url fn" href="http://tantek.com/">Tantek Çelik</a> </div>
The
representation
of
the
printf("%1.6e",
value)
function
hCard
expresses
the
Microformat
terms
in
C
must
be
used
where
"%1.6e"
is
the
string
formatter
context
and
value
is
uses
them
directly
for
the
value
url
and
fn
properties.
Also
note
that
the
Microformat
to
be
converted.
JSON-LD
processor
has
generated
the
proper
URL
type
for
http://tantek.com
.
{ "@context": { "vcard": "http://microformats.org/profile/hcard#vcard", "url": "http://microformats.org/profile/hcard#url", "fn": "http://microformats.org/profile/hcard#fn", "@coerce": { "xsd:anyURI": "url" } }, "@subject": "_:bnode1", "@type": "vcard", "url": "http://tantek.com/", "fn": "Tantek Çelik" }
To
convert
the
The
Microdata
example
below
expresses
book
information
as
a
double
value
in
JavaScript,
implementers
can
use
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
following
snippet
JSON-LD
representation
of
code:
the
Microdata
information
stays
true
to
the
desires
of
the
Microdata
community
to
avoid
contexts
and
instead
refer
to
items
by
their
full
IRI.
// the variable 'value' below is the JavaScript native double value that is to be converted (value).toExponential(6).replace(/(e(?:\+|-))([0-9])$/, '$10$2')[ { "@subject": "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"] }, { "@subject": "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" }, { "@subject": "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" } ]
Developers
would
also
benefit
by
allowing
other
vocabularies
to
be
normalized,
JSON-LD
authors
should
not
use
values
used
automatically
with
their
JSON
API.
There
are
over
200
Vocabulary
Documents
that
are
going
to
undergo
automatic
conversion.
This
is
due
to
available
for
use
on
the
lossy
nature
Web
today.
Some
of
xsd:double
values.
these
vocabularies
are:
You
can
bite
developers.
We
are
currently
wondering
if
having
a
"coerce
validation"
phase
use
these
vocabularies
in
the
parsing/normalization
phases
would
be
a
good
idea.
It
would
prevent
data
round-tripping
issues
combination,
like
the
one
mentioned
above.
so:
{ "@type": "foaf:Person", "foaf:name": "Manu Sporny", "foaf:homepage": "http://manu.sporny.org/", "sioc:avatar": "http://twitter.com/account/profile_image/manusporny" }
The
default
context
is
provided
to
ensure
that
there
are
a
reasonable
set
of
prefixes
and
terms
available
to
all
JSON-LD
developers.
Mappings
specified
Developers
can
also
specify
their
own
Vocabulary
documents
by
modifying
the
default
active
context
should
not
be
overwritten
by
JSON-LD
authors.
All
JSON-LD
processors
must
load
the
following
context
in
as
in-line
using
the
intial
context
before
processing
JSON-LD
text.
@context
keyword,
like
so:
{"@context": { "@vocab": "", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "owl": "http://www.w3.org/2002/07/owl#", "xsd": "http://www.w3.org/2001/XMLSchema#", "dcterms": "http://purl.org/dc/terms/", "foaf": "http://xmlns.com/foaf/0.1/", "cal": "http://www.w3.org/2002/12/cal/ical#", "vcard": "http://www.w3.org/2006/vcard/ns# ", "geo": "http://www.w3.org/2003/01/geo/wgs84_pos#", "cc": "http://creativecommons.org/ns#", "sioc": "http://rdfs.org/sioc/ns#", "doap": "http://usefulinc.com/ns/doap#", "com": "http://purl.org/commerce#", "ps": "http://purl.org/payswarm#", "gr": "http://purl.org/goodrelations/v1#", "sig": "http://purl.org/signature#", "ccard": "http://purl.org/commerce/creditcard#" "@coerce": { "xsd:anyURI": ["rdf:type", "rdf:rest", "foaf:homepage", "foaf:member"], "xsd:integer": "foaf:age" } }"@context": { "myvocab": "http://example.org/myvocab#" }, "@type": "foaf:Person", "foaf:name": "Manu Sporny", "foaf:homepage": "http://manu.sporny.org/", "sioc:avatar": "http://twitter.com/account/profile_image/manusporny", "myvocab:personality": "friendly" }
The
@context
keyword
is
used
to
change
how
the
JSON-LD
processor
evaluates
key-value
pairs.
In
this
case,
it
was
used
to
map
one
string
('myvocab')
to
another
string,
which
is
interpreted
as
a
IRI
.
In
the
example
above,
the
myvocab
string
is
replaced
with
"
http://example.org/myvocab#
"
when
it
is
detected.
In
the
example
above,
"
myvocab:personality
"
would
expand
to
"
http://example.org/myvocab#personality
".
This mechanism is a short-hand for RDF, called a CURIE, and provides developers an unambiguous way to map any JSON value to RDF.
The
editor
editors
would
like
to
thank
Mark
Birbeck,
who
provided
a
great
deal
of
the
rationale
and
reasoning
initial
push
behind
the
JSON-LD
work
via
his
work
on
RDFj,
Dave
Longley
Longley,
Dave
Lehn
and
Mike
Johnson
who
reviewed,
provided
feedback,
and
performed
several
implementation
on
implementations
of
the
specification,
and
Ian
Davis,
who
created
RDF/JSON.
Thanks
also
to
Nathan
Rixham,
Bradley
P.
Allen
Allen,
Kingsley
Idehen,
Glenn
McDonald,
Alexandre
Passant,
Danny
Ayers,
Ted
Thibodeau
Jr.,
Olivier
Grisel,
Niklas
Lindström,
Markus
Lanthaler,
and
Richard
Cyganiak
for
their
input
on
the
specification.
Another
huge
thank
you
goes
out
to
Dave
Longley
who
designed
many
of
the
algorithms
used
in
this
specification,
including
the
normalization
algorithm
which
was
a
monumentally
difficult
design
challenge.