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 [ MICROFORMATS ] 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 replacement for SOAP. In an attempt to harmonize the representation of Linked Data in JSON, this specification outlines a common JSON representation format for Linked Data that can be used to represent objects specified via RDFa, Microformats and Microdata.
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.
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 this specification you must first be familiar with JSON, which is detailed in [ RFC4627 ].
Need
Write
the
introduction
once
all
of
the
technical
details
are
hammered
out.
Explain
why
JSON-LD
is
designed
as
a
light-weight
mechanism
to
write
introduction...
express
RDFa,
Microformats
and
Microdata.
It
is
primarily
intended
as
a
way
to
express
Linked
Data
in
Javascript
environments
as
well
as
a
way
to
pass
Linked
Data
to
and
from
Web
services.
It
is
designed
to
be
as
simple
as
possible,
utilizing
the
large
number
of
JSON
parsers
(and
understanding)
that
is
out
there
already.
It
is
designed
to
be
able
to
express
key-value
pairs,
RDF
data,
Microformats
data,
and
Microdata
(that
is,
every
data
model
currently
in
use)
using
one
unified
format.
It
does
not
require
anyone
to
change
their
JSON,
but
easily
add
meaning
by
adding
context
in
a
way
that
is
out-of-band
-
it
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
tiny
memory
footprint
in
order
to
operate.
A number of design considerations were explored during the creation of this markup language:
The following section outlines the rationale behind the JSON-LD markup language.
Establishing a mechanism to map JSON values to IRIs will help in the mapping of JSON objects to RDF. This does not mean that JSON-LD must be restrictive in declaring a set of terms, rather, experimentation and innovation should be supported as part of the core design of JSON-LD. There are, however, a number of very small design criterial that can ensure that developers will generate good RDF data that will create value for the greater semantic web community and JSON/REST-based Web Services community.
We will be using the following JSON object as the example for this section:
{"a" : "Person", "name" : "Manu Sporny", "homepage" : "http://manu.sporny.org/"}{ "a": "Person", "name": "Manu Sporny", "homepage": "http://manu.sporny.org/" }
A default context is used in RDFa to allow developers to use keywords as aliases for IRIs. So, for instance, the keyword name above could refer to the IRI http://xmlns.com/foaf/0.1/name . The semantic web, just like the document-based web, uses IRIs for unambiguous identification. The idea is that these terms mean something, which you will eventually want to query. The semantic web specifies this via Vocabulary Documents . The IRI http://xmlns.com/foaf/0.1/ specifies a Vocabulary Document, and name is a term in that vocabulary. Paste the two items together and you have an unambiguous identifier for a term.
Developers, and machines, would be 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 need the same sort of dictionary of terms, and URIs provide a way to ensure that these terms are unambiguous.
Non-prefixed terms should have term mappings declared in the default context so that they may be expanded later.
If a set of terms, like Person , name , and homepage , are pre-defined in the default context, and that context is used to resolve the names in JSON objects, machines could automatically expand the terms to something meaningful and unambiguous, like this:
{"", "" : "Manu Sporny", " http://xmlns.com/foaf/0.1/homepage " : " < http://manu.sporny.org > "}{ "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": "http://xmlns.com/foaf/0.1/Person", "http://xmlns.com/foaf/0.1/name": "Manu Sporny", "http://xmlns.com/foaf/0.1/homepage": "<http://manu.sporny.org>" }
In order to differentiate between plain text and IRIs, the < and > are used around IRIs.
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.
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:
A
JSON-LD
Web
Service
could
define
these
as
prefix
es
in
their
default
context
beside
the
terms
that
are
already
defined.
Using
this
feature,
developers
could
also
do
express
markup
like
this:
{"", "" : "Manu Sporny", ", "sioc:avatar" : "<http://twitter.com/account/profile_image/manusporny>"{ "rdf:type": "foaf:Person", "foaf:name": "Manu Sporny", "foaf:homepage": "<http://manu.sporny.org/>", "sioc:avatar": "<http://twitter.com/account/profile_image/manusporny>" }
Developers
could
can
also
be
allowed
to
specify
their
own
Vocabulary
documents
by
modifying
the
default
context,
context
in-line
using
the
#
character,
like
so:
[{"a" : "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:credits" : 500} ]{ "#": { "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:credits": 500 }
Think
of
the
#
character
as
a
"hashtable",
which
maps
one
string
to
another
string.
In
the
example
above,
the
myvocab
string
is
replaced
with
"
http://example.org/myvocab#
"
when
it
is
detected
above.
In
the
example
above,
"
myvocab:credits
"
would
expand
to
"
http://example.org/myvocab#credits
".
This mechanism is a short-hand for RDF, and if defined, will give developers an unambiguous way to map any JSON value to RDF.
To
be
clear,
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.
A
JSON-LD
aware
Web
Service
could
may
define
a
default
context
like
context.
For
example,
the
following:
following
default
context
could
apply
to
all
incoming
Web
Service
calls
previously
accepting
only
JSON
data:
{"a" : "Context", "__vocab__" : "http://example.org/default-vocab#", "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"{ "#": { "__vocab__": "http://example.org/default-vocab#", "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" } }
The
__vocab__
prefix
is
a
special
prefix
that
states
that
any
term
that
doesn't
resolve
to
a
term
or
a
prefix
should
be
appended
to
the
__vocab__
IRI.
This
is
done
to
ensure
that
terms
can
be
transformed
to
an
IRI
at
all
times.
The processing algorithm described in this section is provided in order to demonstrate how one might implement a JSON-LD 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.
Write
The
Processing
Algorithm
is
a
work
in
progress,
there
are
still
major
bugs
in
the
algorithm
and
it's
difficult
to
follow.
It's
provided
only
to
very
early
implementers
to
give
them
an
idea
of
how
to
implement
a
processor.
#
key.
The
algorithm
below
is
designed
for
streaming
(SAX-based)
implementations.
Implementers
will
find
that
non-streaming
(document-based)
implementations
will
be
much
easier
to
implement
as
full
access
to
the
JSON
object
model
eliminates
some
introductory
stuff
about
of
the
steps
that
are
necessary
for
streaming
implementations.
A
conforming
JSON-LD
processor
must
implement
a
processing
algorithm
that
results
in
the
same
default
graph
that
the
following
algorithm
generates:
#
key
is
found,
the
processor
merges
each
key-value
pair
in
the
local
context
into
the
active
context
,
overwriting
any
duplicate
values
in
the
active
context
.
Process
each
object
in
the
list
of
unprocessed
items
,
starting
at
Step
2.2
.
@
key
is
found,
the
processor
sets
the
active
subject
to
the
value
after
Object
Processing
has
been
performed.
a
key
is
found,
set
the
active
property
to
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
.
#
,
@
,
or
a
is
found,
set
the
active
property
by
performing
Property
Processing
on
the
key.
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 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>
Representation:
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.
[{ "a" : "Context", "foaf" : "http://xmlns.com/foaf/0.1/" },[ {"@" : "_:bnode1", "a" : "foaf:Person", "foaf:homepage" : "<http://example.com/bob/>", "foaf:name" : "Bob""#": { "foaf": "http://xmlns.com/foaf/0.1/" }, "@": "_: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""#": { "foaf": "http://xmlns.com/foaf/0.1/" }, "@": "_:bnode2", "a": "foaf:Person", "foaf:homepage": "<http://example.com/eve/>", "foaf:name": "Eve" }, {"@" : "_:bnode2", "a" : "foaf:Person", "foaf:homepage" : "<http://example.com/manu/>", "foaf:name" : "Manu""#": { "foaf": "http://xmlns.com/foaf/0.1/" }, "@": "_:bnode3", "a": "foaf:Person", "foaf:homepage": "<http://example.com/manu/>", "foaf:name": "Manu" } ]
The following example uses a 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>
Representation:
The
representation
of
the
hCard
expresses
the
Microformat
terms
in
the
context
and
uses
them
directly
for
the
url
and
fn
properties.
Also
note
that
the
Microformat
to
JSON-LD
processor
has
generated
the
proper
URL
type
for
http://tantek.com
.
[{ "a" : "Context", "vcard" : "http://microformats.org/profile/hcard#vcard" "url" : "http://microformats.org/profile/hcard#url" "fn" : "http://microformats.org/profile/hcard#fn" }, { "@" : "_:bnode1", "a" : "vcard", "url" : "<http://tantek.com/>", "fn" : "Tantek Çelik" } ]{ "#": { "vcard": "http://microformats.org/profile/hcard#vcard" "url": "http://microformats.org/profile/hcard#url" "fn": "http://microformats.org/profile/hcard#fn" }, "@": "_: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>
Representation:
Note
that
the
JSON-LD
representation
of
the
Microdata
information
stays
true
to
the
desires
of
the
Microdata
community
to
avoid
contexts
and
instead
refer
to
items
by
their
full
IRI.
[{ "a" : "Context", "__vocab__" : "http://www.w3.org/1999/xhtml/microdata#", "frbr" : "http://purl.org/vocab/frbr/core#", "dc" : "http://purl.org/dc/terms/" }, { "a" : "frbr:Work", "@" : "<http://purl.oreilly.com/works/45U8QJGZSQKDH8N>", "dc:title" : "Just a Geek", "dc:creator" : "Whil Wheaton", "frbr:realization" : ["<http://purl.oreilly.com/products/9780596007683.BOOK>", "<http://purl.oreilly.com/products/9780596802189.EBOOK>"] }, { "a" : "frbr:Expression", "@" : "<http://purl.oreilly.com/products/9780596007683.BOOK>", "dc:type" : "<http://purl.oreilly.com/product-types/BOOK>" }, { "a" : "frbr:Expression", "@" : "<http://purl.oreilly.com/products/9780596802189.EBOOK>", "dc:type" : "<http://purl.oreilly.com/product-types/EBOOK>" }[ { "@": "<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>" } ]
JSON-LD
is
designed
to
write
introduction
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
can
become
Linked
Data
with
the
simple
addition
of
a
context.
Since
RDF
Concepts
is
also
an
important
sub-community
of
the
Linked
Data
movement,
it
is
important
that
all
RDF
concepts
are
well-represented
in
this
specification.
This
section
details
how
each
RDF
concept
can
be
expressed
in
JSON-LD.
Expressing
IRIs
are
fundamental
to
Linked
Data
as
that
is
how
most
subjects
and
many
objects
are
identified.
IRIs
can
be
expressed
by
wrapping
a
text
string
with
the
<
and
>
characters.
{ ..."foaf:homepage" : "","foaf:homepage": "<http://manu.sporny.org>", ... }
The
example
above
would
set
the
object
to
an
IRI
with
the
value
of
http://manu.sporny.org
.
Wrapping
IRIs
with
the
<
and
>
characters
are
only
necessary
when
IRIs
are
specified
as
objects.
At
no
other
point
do
you
need
to
wrap
an
IRI.
You
do
not
need
to
wrap
IRIs
when
declaring
a
property,
declaring
a
CURIE,
or
describing
key-value
pairs
in
a
context.
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,
predicate,
object)
tuple,
also
known
as
a
triple.
{ ..."","@": "<http://example.org/people#joebob>", ... }
The
example
above
would
set
the
subject
to
.
The
type
of
a
particular
subject
can
be
specified
using
the
a
key.
Specifying
the
type
in
this
way
will
generate
a
triple
of
the
form
(subject,
type,
type-url).
{ ..."","@": "<http://example.org/people#joebob>", "a": "<http://xmlns.com/foaf/0.1/Person>", ... }
The example above would generate the following triple (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 "plain literals" in RDF and are easily expressed using regular JSON strings.
{ ..."foaf:name" : "","foaf:name": "Mark Birbeck", ... }
JSON-LD
attempts
to
make
sure
that
it
is
easy
to
express
triples
in
other
languages
while
simultaneously
ensuring
that
hefty
data
structures
aren't
required
to
accomplish
simple
language
markup.
When
the
@
symbol
is
used
in
a
literal,
the
JSON-LD
processor
tags
the
literal
text
with
the
language
tag
that
follows
the
@
symbol.
{ ..."foaf:name" : "","foaf:name": "花澄@ja", ... }
The
example
above
would
generate
a
plain
literal
for
花澄
and
associate
the
ja
language
tag
with
the
triple
that
is
generated.
Languages
must
be
expressed
in
[
BCP47
]
format.
Literals
may
also
be
typed
in
JSON-LD
by
using
the
^^
sequence
at
the
end
of
the
text
string.
{ ..."dc:modified" : "","dc:modified": "2010-05-29T14:17:39+02:00^^xsd:dateTime", ... }
The
example
above
would
generate
an
object
with
the
value
of
2010-05-29T14:17:39+02:00
and
the
datatype
of
http://www.w3.org/2001/XMLSchema#dateTime
.
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.
{ ..."foaf:nick" : ,"@": "<http://example.org/people#joebob>", "foaf:nick": ["stu", "groknar", "radface"], ... }
The markup shown above would generate the following triples:
<http://example.org/people#joebob> <http://xmlns.com/foaf/0.1/> "stu" . <http://example.org/people#joebob> <http://xmlns.com/foaf/0.1/> "groknar" . <http://example.org/people#joebob> <http://xmlns.com/foaf/0.1/> "radface" .
Multiple typed literals are expressed very much in the same way as multiple properties:
{ ..."dc:modified" : ],"@": "<http://example.org/articles/8>", "dcterms:modified": ["2010-05-29T14:17:39+02:00^^xsd:dateTime", "2010-05-30T09:21:28-04:00^^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
the
subject.
Typically,
this
is
where
blank
nodes
come
into
play.
In
JSON-LD,
blank
node
identifiers
are
automatically
created
if
a
subject
is
not
specified
using
the
@
key.
However,
authors
may
name
blank
nodes
by
using
the
special
_
CURIE
prefix.
{ ..."@" : "","@": "_:foo", ... }
The
example
above
would
set
the
subject
to
_:foo
,
which
can
then
be
used
later
on
in
the
JSON-LD
markup
to
refer
back
to
the
named
blank
node.
Special characters in property values must be escaped in order to not be interpreted as CURIEs, IRIs, language tags, or TypedLiterals.
The
special
characters
in
JSON-LD
are:
<
,
>
,
@
,
#
,:
and
^
.
{ ..."example:code" : ,"example:code": "\\<foobar\\^\\^2\\>", ... }
Since JSON is capable of expressing typed information such as decimals, integers and boolean values, JSON-LD utilizes that information to create Typed Literals .
{ ...// This value is automatically converted to having a type of xsd:decimal "measure:cups" : , // This value is automatically converted to having a type of xsd:integer "chem:protons" : , // This value is automatically converted to having a type of xsd:boolean "sensor:active" : ,// This value is automatically converted to having a type of xsd:decimal "measure:cups": 5.3, // 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, ... }
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 taken with a grain of salt; 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> . </section>
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:
{ "#": { "foaf": "http://xmlns.com/foaf/0.1/" }, "@": [ { "@": "<http://example.org/people#john>", "a": "foaf:Person" }, { "@": "<http://example.org/people#jane>", "a": "foaf:Person" } ] }
The editor would like to thank Mark Birbeck, who provided a great deal of the rationale and reasoning behind the JSON-LD work via his work on RDFj, Dave Longley who reviewed and provided feedback on the overall specification and contexts, and Ian Davis, who created RDF/JSON.