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
].
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:
{ "name": "Manu Sporny", "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:
{ "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
IRIs.
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:
{ "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" }
The
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
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
@
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":
{
"@iri": "foaf:homepage"
}
}
...
"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
{ ... "@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":
{
"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
...
}
d
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.
{
...
"@": "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",
"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
to
specify
Compaction
is
the
subject.
Typically,
this
process
of
taking
a
JSON-LD
document
and
applying
a
context
such
that
the
most
compact
form
of
the
document
is
where
blank
nodes
come
into
play.
In
JSON-LD,
blank
node
identifiers
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
API,
provides
a
way
to
compact
a
JSON-LD
document.
For example, assume the following JSON-LD input document:
{ "http://xmlns.com/foaf/0.1/name": "Manu Sporny", "http://xmlns.com/foaf/0.1/homepage": { "@iri": "http://manu.sporny.org/" } }
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 result in the 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
@
http://xmlns.com/foaf/0.1/name
keyword.
However,
authors
may
to
name
blank
nodes
,
it
could
have
also
mapped
it
to
any
arbitrary
string
provided
by
using
the
special
_
CURIE
prefix.
developer.
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 application-specific JSON documents or as a part of the 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" } } }
The
example
Running
the
JSON-LD
Expansion
algorithm
against
the
JSON-LD
input
document
provided
above
would
set
result
in
the
subject
following
output:
{ "http://xmlns.com/foaf/0.1/name": "Manu Sporny", "http://xmlns.com/foaf/0.1/homepage": { "@iri": "http://manu.sporny.org/" } }
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
_:foo
,
which
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:
{ "@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/elements/1.1/" } "@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", "@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/> .
Object chaining is a JSON-LD feature that allows an author to use the definition of JSON-LD objects as property values. This is a commonly used mechanism for creating a parent-child relationship between two subject s.
The example shows an two subjects related by a property from the first subject:
{ ... "foaf:name": "Manu Sporny", "foaf:knows": { "@type": "foaf:Person", "foaf:name": "Gregg Kellogg", } ... }
An object definition, like the one used above, may be used as a JSON value at any point in JSON-LD.
At
times,
it
becomes
necessary
to
be
able
to
express
information
without
being
able
to
specify
the
subject.
Typically,
this
type
of
node
is
called
an
unlabeled
node
or
a
blank
node.
In
JSON-LD,
unlabeled
node
identifiers
are
automatically
created
if
a
subject
is
not
specified
using
the
@subject
keyword.
However,
authors
may
provide
identifiers
for
unlabeled
nodes
by
using
the
special
_
(underscore)
CURIE
prefix.
{
...
"@subject": "_:foo",
...
}
The
example
above
would
set
the
subject
to
_:foo
,
which
can
then
be
used
later
on
in
the
JSON-LD
Processing
Algorithm
markup
to
refer
back
to
the
unlabeled
node.
This
practice,
however,
is
usually
frowned
upon
when
generating
Linked
Data.
If
a
developer
finds
that
they
refer
to
the
unlabeled
node
more
than
once,
they
should
consider
naming
the
node
using
a
resolve-able
IRI.
JSON-LD
allows
all
of
the
syntax
keywords,
except
for
@context
,
to
be
overridden.
This
feature
allows
more
legacy
JSON
content
to
be
supported
by
JSON-LD.
It
also
allows
developers
to
design
domain-specific
implementations
using
only
the
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
,
respectively.
Normalization is the process of taking a JSON-LD document and performing a deterministic transformation on that document that results in a final document that any conforming JSON-LD processor would have generated given the same input document. 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 unlabeled.
Normalization is useful when comparing two graphs against one another, when generating a detailed list of differences between two graphs, and when generating a cryptographic digital signature for information contained in a graph or when generating a hash of the information contained in a graph.
The example below is an un-normalized JSON-LD document:
{ "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 example below is the normalized form of the JSON-LD document above:
Whitespace is used below to aid readability. The normalization algorithm for JSON-LD remove all unnecessary whitespace in the 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 term s have been expanded and sorted in alphabetical order. Also, notice how the subject has been labeled with a blank node identifier. Normalization ensures that any arbitrary graph containing exactly the same information would be normalized to exactly the same form shown above.
TBD: Explain compaction algorithm.
TBD: Explain expansion algorithm.
TBD: Explain framing algorithm.
TBD: Explain normalization algorithm.
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
Processing
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,
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
predicate
property
resource.
However,
specific
implementations
may
choose
to
operate
on
the
document
as
a
normal
JSON
description
of
objects
having
attributes.
@context
keyword.
@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
Processing
of
JSON-LD
is
managed
recursively
using
a
process
described
in
Sequence
.
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
.
Should
the
document
URL
be
used
as
the
default
for
@base
in
the
default
initial
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
an
associative
array
value.
When
processing
a
local
context
,
special
rules
apply:
@base
must
have
a
value
of
a
simple
string
with
the
lexical
form
of
IRI
and
is
saved
in
the
active
context
to
perform
term
mapping
as
described
in
IRI
Processing
.
@vocab
must
have
a
value
of
a
simple
string
with
the
lexical
form
of
IRI
and
is
saved
in
the
active
context
to
perform
term
mapping
as
described
in
IRI
Processing
.
@coerce
must
have
a
value
of
an
associative
array.
Processing
of
the
associative
array
is
described
below
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.
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 for generating an IRI is:
@coerce
mapping)
and
the
active
context
has
a
@vocab
mapping,
join
the
mapped
value
to
the
suffix
using
the
method
described
in
[
RFC3987
].
@base
mapping,
join
the
mapped
value
to
the
suffix
using
the
method
described
in
[
RFC3987
].
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 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
Processing
on
the
associated
value.
Generate
a
triple
representing
the
active
subject
,
the
active
property
and
the
active
object
.
Return
the
active
object
to
the
calling
location.
@literal
key,
set
the
active
object
to
a
literal
value
as
follows:
@datatype
key
after
performing
IRI
Processing
on
the
specified
@datatype
.
@language
key,
use
it's
value
to
set
the
language
of
the
plain
literal.
@
key:
@
key,
set
the
active
object
to
newly
generated
blank
node
identifier
.
Generate
a
triple
representing
the
active
subject
,
the
active
property
and
the
active
object
.
Set
the
active
subject
to
the
active
object
.
a
,
set
the
active
property
to
rdf:type
.
rdf:first
and
rdf:next
,
terminating
the
list
with
rdf:nil
using
the
following
sequence:
rdf:nil
.
rdf:first
as
the
active
property
.
rdf:nil
.
rdf:rest
and
rest
bnode
.
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
object
and
the
generated
typed
literal.
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:
{ "@": [ { "@": "http://example.org/people#john", "a": "foaf:Person" }, { "@": "http://example.org/people#jane", "a": "foaf:Person" } ] }
A disjoint graph could also be expressed like so:
[ { "@": "http://example.org/people#john", "a": "foaf:Person" }, { "@": "http://example.org/people#jane", "a": "foaf:Person" } ]
This API provides a clean mechanism that enables developers to convert JSON-LD data into a format that is easier to work with in various programming languages.
[NoInterfaceObject]
interface JSONLDProcessor {
object toProjection (in DOMString jsonld, in object? template, in DOMString? subject, in optional JSONLDParserCallback? callback);
Graph toGraph (in DOMString jsonld, in optional JSONLDParserCallback? callback);
};
toGraph
null
if
there
are
any
errors,
or
if
the
RDF
Interfaces
API
is
not
available
for
use.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
jsonld |
DOMString
|
|
|
The JSON-LD string to parse into the RDFGraph. |
callback |
JSONLDParserCallback
|
|
|
A callback that is called whenever a processing error occurs on the given JSON-LD string. |
Graph
toProjection
null
is
returned.
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
jsonld |
DOMString
|
|
|
The JSON-LD string to parse into the Projection. |
template |
object
|
|
|
The Projection template to use when building the Projection. |
subject |
DOMString
|
|
|
The subject to use when building the Projection. |
callback |
JSONLDParserCallback
|
|
|
A callback that is called whenever a processing error occurs on the given JSON-LD string. |
object
The JSONLDParserCallback is called whenever a processing error occurs on input data.
[NoInterfaceObject Callback]
interface JSONLDProcessorCallback {
void error (in DOMString error);
};
The following example demonstrates how to convert JSON-LD to a projection that is directly usable in a programming environment:
// retrieve JSON-LD from a Web Service var jsonldString = fetchPerson(); // This map, usually defined once per script, defines how to map incoming // JSON-LD to JavaScript objects var myTemplate = { "http://xmlns.com/foaf/0.1/name" : "name", "http://xmlns.com/foaf/0.1/age" : "age", "http://xmlns.com/foaf/0.1/homepage" : "homepage" }; // Map the JSON-LD to a language-native object var person = jsonld.toProjection(jsonldString, myTemplate); // Use the language-native object alert(person.name + " is " + person.age + " years old. " + "Their homepage is: " + person.homepage);
A
JSON-LD
Serializer
is
also
available
to
map
a
language-native
object
to
JSON-LD.
]
interface {
};
[NoInterfaceObject]
interface JSONLDSerializer {
DOMString normalize (in object obj);
};
normalize
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
obj |
object
|
|
|
An associative array of key-value pairs that should be converted to a JSON-LD string. It is assumed that a map already exists for the data. |
DOMString
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 as follows:
@context
key
and
preserve
it
as
the
transformation
map
while
running
this
algorithm.
Note that normalizing named blank nodes is impossible at present since one would have to specify a blank node naming algorithm. For the time being, you cannot normalize graphs that contain named blank nodes. However, normalizing graphs that contain non-named blank nodes is supported.
var myObj = { "@context" : { "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:nonNegativeInteger": "age", "xsd:anyURI": "homepage" } }, "name" : "Joe Jackson", "age" : "42", "homepage" : "http://example.org/people/joe" }; // Map the language-native object to JSON-LD var jsonldText = jsonld.normalize(myObj);
After the code in the example above has executed, the jsonldText value will be (line-breaks added for readability):
[{"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"}]
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.
The
default
context
is
provided
JSON-LD
markup
examples
below
demonstrate
how
JSON-LD
can
be
used
to
ensure
express
semantic
data
marked
up
in
other
languages
such
as
RDFa,
Microformats,
and
Microdata.
These
sections
are
merely
provided
as
proof
that
JSON-LD
is
very
flexible
in
what
it
can
express
across
different
Linked
Data
approaches.
The following example describes three people with their respective names and homepages.
<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>
An example JSON-LD implementation is described below, however, there are other ways to mark-up this information such 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" } ]
The
following
example
uses
a
reasonable
set
simple
Microformats
hCard
example
to
express
how
the
Microformat
is
represented
in
JSON-LD.
<div class="vcard"> <a class="url fn" href="http://tantek.com/">Tantek Çelik</a> </div>
The
representation
of
prefixes
and
the
hCard
expresses
the
Microformat
terms
available
to
all
JSON-LD
developers.
Mappings
specified
by
in
the
default
context
should
not
be
overwritten
by
and
uses
them
directly
for
the
url
and
fn
properties.
Also
note
that
the
Microformat
to
JSON-LD
authors.
All
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" } }, "@": "_:bnode1", "a": "vcard", "url": "http://tantek.com/", "fn": "Tantek Çelik" }
The 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
processors
must
load
representation
of
the
following
context
Microdata
information
stays
true
to
the
desires
of
the
Microdata
community
to
avoid
contexts
and
instead
refer
to
items
by
their
full
IRI.
[ { "@": "http://purl.oreilly.com/works/45U8QJGZSQKDH8N", "a": "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"] }, { "@": "http://purl.oreilly.com/products/9780596007683.BOOK", "a": "http://purl.org/vocab/frbr/core#Expression", "http://purl.org/dc/terms/type": "http://purl.oreilly.com/product-types/BOOK" }, { "@": "http://purl.oreilly.com/products/9780596802189.EBOOK", "a": "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 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:
You
can
use
these
vocabularies
in
as
combination,
like
so:
{ "rdf:type": "foaf:Person", "foaf:name": "Manu Sporny", "foaf:homepage": "http://manu.sporny.org/", "sioc:avatar": "http://twitter.com/account/profile_image/manusporny" }
Developers
can
also
specify
their
own
Vocabulary
documents
by
modifying
the
intial
active
context
before
processing
JSON-LD
text.
in-line
using
the
@context
keyword,
like
so:
{ "@context": { "myvocab": "http://example.org/myvocab#" }, "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
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.