Abstract

JSON [RFC4627] has proven to be a highly useful object serialization and
messaging format. JSON-LD [JSON-LD] harmonizes the representation of
Linked Data in JSON by outlining a common JSON representation format for
expressing directed graphs; mixing both Linked Data and non-Linked Data in
a single document. This document outlines an Application Programming
Interface and a set of algorithms for programmatically transforming
JSON-LD documents in order to make them easier to work with in programming
environments like JavaScript, Python, and Ruby.

This document has been under development for over 18 months in the
JSON for Linking Data Community Group. The document has recently been
approved for transfer into the RDF Working Group for
review with the intent to publish the
document along the W3C
Recommendation track. This specification has undergone significant
development, review, and changes during the course of the last 18
months and is being published as a Final Community Group Specification so that
it may gain wider review and feedback.

There are currently
five interoperable implementations
of this specification. There is
a fairly complete test suite
and a
live JSON-LD editor
that is capable of demonstrating the features described in
this document. While development on implementations, the test suite
and the live editor will continue, they are believed to be mature enough
to be integrated into a non-production system at this point in time with
the expectation that they could be used in a production system within the
next year.

Issue 1

It is important for readers to understand that the scope of this document is
currently under debate and new features may be added to the specification.
Existing features may be modified heavily or removed entirely from the
specification upon further review and feedback from the broader community.
This is a work in progress and publication as a First Public Working Draft
does not require that all Working Group members agree on the content of the
document.

1. Preface

This document is a detailed specification for an Application Programming
Interface for the JSON-LD Syntax. The document is primarily intended for
the following audiences:

Web authors and developers that want a very detailed view of how
a JSON-LD processor and the API operates.

Software developers that want to implement processors and APIs for
JSON-LD.

To understand the basics in this specification you must first be familiar with
JSON, which is detailed in [RFC4627]. You must also understand the
JSON-LD Syntax [JSON-LD], which is the base syntax used by all of the
algorithms in this document. To understand the API and how it is
intended to operate in a programming environment, it is useful to have working
knowledge of the JavaScript programming language [ECMA-262] and
WebIDL [WEBIDL]. To understand how JSON-LD maps to RDF, it is helpful to be
familiar with the basic RDF concepts [RDF-CONCEPTS].

1.1 Contributing

There are a number of ways that one may participate in the development of
this specification:

If you want to make sure that your feedback is formally addressed by
the RDF Working Group, you should send it to public-rdf-comments:
public-rdf-comments@w3.org

The #json-ld
IRC channel is available for real-time discussion on irc.freenode.net.

2. Introduction

The JSON-LD Syntax specification [JSON-LD] outlines a language that may be
used to express Linked Data in JSON. Often, it is useful to be able to
transform JSON-LD documents so that they may be easily processed in
a programming environment like JavaScript, Python or Ruby.

There are three major types of transformation that are discussed in this
document; compaction, expansion, and RDF conversion.

2.1 Expansion

Software algorithms are easiest to write when the data that they are processing
have a regular form. Since information can be represented by JSON-LD in a
variety of different ways, transforming all of these methods into a uniform
structure allows the developer to simplify their processing code. For example,
note that the following input uses only terms and is fairly
compact:

While both inputs are valid JSON-LD, writing a program to handle every
permutation of possible inputs can be difficult, especially when the incoming
context could change as well. To ensure that the data can be given a more
uniform structure, JSON-LD introduces the notion of expansion.
Expansion performs two important operations. The first is to
expand all values that are IRIs to their fully expanded form.
The second is to express all values in expanded form. To
transform both inputs above to the same representation, the developer could
do the following:

Example 3

function expansionCallback(output) {
console.log(output);
}
// the second parameter is 'null' because the developer does not wish to
// inject another context value
jsonld.expand(input1, null, expansionCallback);
jsonld.expand(input2, null, expansionCallback);

Note that in the example above; all context definitions have
been removed, all term and prefixes have been expanded to full
IRIs, and all literals are expressed in expanded form.
While the output is more difficult for a human to read, it is easier for a
software program to process because of its very regular structure.

2.2 Compaction

While expansion expands a given input as much as possible, compaction performs
the opposite operation - expressing a given input as succinctly as possible.
While expansion is meant to produce something that is easy to process by
software programs, compaction is meant to produce something that is easy to
ready by software developers. Compaction uses a developer-supplied
context to compresses all IRIs to terms
or prefixes, and compacts all literals expressed
in expanded form as much as possible.

The following example expresses input that has already been fully expanded:

Note that all of the terms have been compressed and
the context has been injected into the output. While compacted
output is most useful to humans, it can also be carefully used to generate
structures that are easy to use for developers to program against as well.

2.3 Conversion to and from RDF

JSON-LD can be used to losslessly express the RDF data model as described in
the RDF Concepts document [RDF-CONCEPTS]. This ensures that
data can be round-tripped from any RDF syntax, like N-Triples or TURTLE,
without any loss in the fidelity of the data. Assume the following RDF input
in N-Triples format:

2.4 Framing and Normalization

Issue 2

There are currently two other API methods that are in active development and
were not ready for publication at the time this document was published.
Framing allows a developer to force a different layout for the data and
effectively perform query-by-example on JSON-LD documents - this is most
useful when a JSON-LD-based REST API does not know the exact form of the data
it is getting in, but still wants to operate upon it if some bare essentials
are found in the data. JSON-LD normalization allows JSON-LD documents to be
deterministically serialized such that they can be digitally signed or be
used to find the differences between two linked data graphs.
It is expected that framing will be a part of the final API. It is expected
that normalization will be an optional feature that JSON-LD processors may
implement.

3. The Application Programming Interface

This API provides a clean mechanism that enables developers to convert
JSON-LD data into a a variety of output formats that are easier to work
with in various programming languages. If a JSON-LD API is provided in
a programming environment, the entirety of the following API must be
implemented.

3.1 General Terminology

Issue 3

The intent of the Working Group and the Editors of this specification is to
eventually align terminology used in this document with the terminology used
in the RDF Concepts document to the extent to which it makes sense to do so.
In general, if there is an analogue to terminology used in this document in
the RDF Concepts document, the preference is to use the terminology in the
RDF Concepts document.

The following is an explanation of the general terminology used in this
document:

JSON object

An object structure is represented as a pair of curly brackets surrounding zero or
more name-value pairs. A name is a string. A single colon comes after
each name, separating the name from the value. A single comma separates a value
from a following name. The names within an object should be unique.

array

An array is represented as square brackets surrounding zero or more
values that are separated by commas.

string

A string is a sequence of zero or more Unicode (UTF-8) characters,
wrapped in double quotes, using backslash escapes (if necessary). A
character is represented as a single character string.

number

A number is similar to that used in most programming languages, except
that the octal and hexadecimal formats are not used and that leading
zeros are not allowed.

true and false

Values that are used to express one of two possible boolean states.

null

Unless otherwise specified, a JSON-LD processor must act as if a
key-value pair in the body of a JSON-LD document was never declared when
the value equals null. If @value,
@list, or @set is set to null in
expanded form, then the entire JSON object is ignored. If
@context is set to null, the
active context is reset and when used
within a context, it removes any definition associated
with the key, unless otherwise specified.

subject definition

A JSON object used to represent a subject and
one or more properties of that subject. A JSON object is a
subject definition if it does not contain they keys @value,
@list or @set and it has one or more keys
other than @id.

3.2.1 Methods

compact

Compacts the given input using the
context according to the steps in the
Compaction Algorithm. The
inputmust be copied, compacted and returned if there are
no errors. If the compaction fails, an appropriate exception must be
thrown.

Expands the given input according to
the steps in the Expansion Algorithm. The
inputmust be copied, expanded and returned if there are
no errors. If the expansion fails, an appropriate exception must be thrown.

3.4.2 JsonLdOptions

The Base IRI to use when expanding the document. This overrides the value of
input if it is a URL or if it is a object or object[].

boolean optimize

If set to true, the JSON-LD processor is allowed to
optimize the output of the Compaction Algorithm
to produce even compacter representations. The algorithm for compaction
optimization is beyond the scope of this specification and thus
not defined. Consequently, different implementations may implement
different optimization algorithms.

boolean noType

If set to true, the JSON-LD processor will not use the
@type property when generating the output, and will use the
expanded rdf:typeIRI as the property instead of @type.

The following data structures are used for representing data about
RDF quads. They are used for normalization, fromRDF,
and from toRDF interfaces.

3.4.5.1 Attributes

3.4.6 Blank Node

A node in the linked data graph that
does not contain a de-reference-able identifier because it is either
ephemeral in nature or does not contain information that needs to be linked
to from outside of the linked data graph.
A blank node is assigned an identifier starting
with the prefix _: and an implementation dependent,
auto-generated suffix that is unique to all information associated with the
particular blank node.

3.4.6.1 Attributes

The temporary identifier of the blank node.
The identifiermust not be relied upon in any way between two
separate processing runs of the same document or with a different document.

Note

Developers and authors must not assume that the
value of a blank node will remain the same between two
processing runs. BlankNode values are only valid for the
most recent processing run on the document. BlankNode
values will often be generated differently by different processors.

Note

Implementers must ensure that BlankNode values are unique
within the current environment, two BlankNodes are considered equal if, and only
if, their values are strictly equal.

3.4.7 Literal

Literals represent values such as numbers, dates and strings in
RDF data. A Literal is comprised of three attributes:

Literals representing plain text in a natural language may have a
language tag specified by a string token, as specified in
[BCP47], normalized to lowercase
(e.g., 'en', 'fr', 'en-gb').
They also have a datatype attribute such as xsd:string.
If unspecified, the datatype defaults to xsd:string.

Literals representing values with a specific datatype, such as
the integer 72, may have a datatype attribute specified in the form
of a IRI (e.g.,
xsd:integer).

4. Algorithms

All algorithms described in this section are intended to operate on
language-native data structures. That is, the serialization to a text-based
JSON document isn't required as input or output to any of these algorithms and
language-native data structures must be used where applicable.

4.1 Algorithm Terms

initial context

a context that is specified to the algorithm before processing begins. The contents of the
initial context is defined in Appendix A.

active subject

the currently active subject that the processor should use when
processing.

active property

the currently active property that the processor should use when
processing. The active property is represented in the original lexical form, which
is used for finding coercion mappings in the active context.

active object

the currently active object that the processor should use when
processing.

a compact IRI is has the form of prefix and suffix and is used as a way
of expressing an IRI without needing to define separate term definitions for
each IRI contained within a common vocabulary identified by prefix.

The active context is used for expanding properties and values of a JSON object (or elements
of an array) using a term mapping. It is also used to maintain
coercion mappings from terms to datatypes, language mappings from terms to language codes,
and list mappings and set mappings for terms. Processors must use the
lexical form of the property when creating a mapping, as lookup is performed on lexical forms, not
expanded IRI representations.

If the resulting document is a JSON document, extract the top-level @context
element using the JSON Pointer "/@context" as described in [JSON-POINTER]. Set context
to the extracted content and process it by starting at Step 2.1.

If the value has a @language property but no @type property, the value of the
@language property must be a string or null.
Merge the language mapping into the local context using the lexical value of the
property.

It can be difficult to distinguish between a compact IRI and an absolute IRI,
as a compact IRI may seem to be a valid IRIscheme. When performing repeated IRI expansion,
a term used as a prefix may not have a valid mapping due to dependencies in resolving term definitions. By
continuing Step 2.3.2 until no changes are made, mappings to IRIs created
using an undefined term prefix will eventually resolve to absolute IRIs.

Issue 6

Issue 43
concerns performing IRI expansion in the key position of a context definition.

4.3 IRI Expansion

Keys and some values are evaluated to produce an IRI. This section defines an algorithm for
transforming a value representing an IRI into an actual IRI.

An absolute IRI is defined in [RFC3987] containing a scheme along with
path and optional query and fragment segments. A relative IRI is an IRI
that is relative some other absolute IRI; in the case of JSON-LD this is the base location
of the document.

The algorithm for generating an IRI is:

If the active context contains a term mapping for the value using
a case-sensitive comparison, use the mapped value as an IRI.

Otherwise, split the value into a prefix and suffix from the first occurrence of ':'.

If the prefix is a '_' (underscore), the value represents a named blank node.

If the active context contains a term mapping for prefix using
a case-sensitive comparison, and suffix does not does not begin with '//'
(i.e., it does not match a hier-part including
authority (as defined in [RFC3986]), generate an IRI
by prepending the mapped prefix to the (possibly empty) suffix using textual concatenation. Note that an empty
suffix and no suffix (meaning the value contains no ':' string at all) are treated equivalently.

Otherwise, use the value directly as an IRI.

Note

Previous versions of this specification used @base and @vocab to define IRI prefixes
used to resolve relative IRIs. It was determined that this added too much complexity, but the issue
can be re-examined in the future based on community input.

4.4 IRI Compaction

Some keys and values are expressed using IRIs. This section defines an
algorithm for transforming an IRI (iri) to a term or compact IRI using the
terms specified in the active context using an optional value.

If value is a JSON object containing only the property @list
and list container is false and term has a container
set to @list, then set list container to true, clear
terms, set highest rank to rank, and add term to terms.

Otherwise, if rank is greater than or equal to highest rank:

If rank is greater than highest rank, clear terms and set
highest rank to rank.

Otherwise, return the shortest and lexicographically least value in terms.

4.4.2 Term Rank Algorithm

When selecting among multiple possible terms for a given property, it may be that multiple
terms are defined with the same IRI, but differ in @type, @container
or @language. The purpose of this algorithm is to take a term
and a value and give it a term rank. The selection can then be based, partly, on
the term having the highest term rank.

If value has a @type property matching a
@type coercion for term, term rank
is 3, otherwise if term has no @type
coercion and no @language, term rank is
1, otherwise 0.

Otherwise, if @value is not a string, if term has
no @type or @language it is 2, otherwise 1.

Otherwise, if value has no @language property, if term has
@languagenull, or term has no @type or
@language and the active context has no @language,
term rank is 3, otherwise 0.

Otherwise, if value has a @language property matching a
@language definition for term (or
term has no @type or @language definition and
@language in the active context matches the
value@language), term rank is
3, otherwise if term has no @type
coercion and no @language, term rank is
1, otherwise 0.

Otherwise, if term has @type coerced to @id,
term rank is 3, otherwise
if term has no @type coercion and no @language,
term rank is 1, otherwise 0.

If active property is @graph or the target of an @id coercion,
expand the value into an object with a key-value pair where the key is @id and the value is
the expanded IRI according to the IRI Expansion rules.

If value only has one property and the active context has no default language,
then the compacted value is the value of @value.

Otherwise, if active property is @graph, the compacted value is the
value associated with the @id key, processed according to
the IRI Compaction steps.

Otherwise, if the active context contains a coercion target for the
key that matches the expression of the value, compact the value using the
following steps:

If the coercion target is an @id, the compacted
value is the value associated with the @id key,
processed according to the
IRI Compaction steps.

If the coercion target is a typed literal, the compacted
value is the value associated with the @value key.

Otherwise, if value contains an @id key, the compacted value is value with
the value of @id processed according to the
IRI Compaction steps.

Otherwise, if the active context contains a @language, which
matches the @language of the value, or the value has only a @value key, the compacted
value is the value associated with the @value key.

Otherwise, if the value contains a @type key, the compacted value
is value with the @type value processed according to the
IRI Compaction steps.

Otherwise, the value is not modified.

4.7 Expansion

Expansion is the process of taking a JSON-LD document and applying a
context such that all IRI, datatypes, and literal values are expanded so
that the context is no longer necessary. JSON-LD document expansion
is typically used as a part of other JSON-LD API methods.

If element is an array, process each entry in element recursively
using this algorithm, passing copies of the active context and active property.
If has a @container set to @list and any entry in element is an
array, or is a JSON object containing a @list property,
throw an exception, as lists of lists are not allowed.
If the expanded entry is null, drop it. If it's an array, merge its entries with element's entries.

Otherwise, if value is an array, all elements must be either a
string or subject reference. Expand value for each
of its entries using the previous three steps.

Otherwise, if the property is @value or @language the valuemust not be a
JSON object or an array.

Otherwise, if the property is @list or @set expand value
recursively using this algorithm, passing copies of the active context and active property. If the expanded
value is not an array, convert it to an array.
If property is @list and any entry in value is a
JSON object containing an @list property, throw an exception, as
lists of lists are not supported.

If property is not a keyword
and active property has a @container@list
and the expanded value is not null,
convert value to an object with an @list property whose value is
set to value (unless value is already in that form).

Convert value to array form unless value is null or property is
@id, @type, @value, or @language.

If value is not null, either merge value into an existing property property of
element or create a new property property with value as value.

If the processed element has an @value property

elementmust not have more than one other property, which can either be @language or @type
with a string value.

if the value of @value equals null,
replace element with the value of @value.

Otherwise, if element has an @type property and its value is not in the form of an
array, convert it to an array.

If element has an @set or @list property, it must be the only property.
Set element to the value of @set; leave @list untouched.

If, after the algorithm outlined above is run, the resulting element is an JSON object with just a @graph
property, element is set to the value of @graph's value. Finally, if element is a JSON object,
it is wrapped into an array.

4.8 Compaction

Compaction is the process of taking a JSON-LD document and applying a
context such that the most compact form of the document is generated. JSON
is typically expressed in a very compact, key-value format. That is, full
IRIs are rarely used as keys. At times, a JSON-LD document may be received
that is not in its most compact form. JSON-LD, via the API, provides a way
to compact a JSON-LD document.

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 to
name, it could have also mapped it to any arbitrary string
provided by the developer.

If element is an array, process each entry in element recursively
using this algorithm, passing a copy of the active context and the active property.
If element has a single item, the compacted value is that item; otherwise the compacted value
is element.

Otherwise, if the active property has a @container mapping to @list
and element has a corresponding @list property, recursively compact that
property's value passing a copy of the active context and the active property ensuring
that the result is an array and removing null values. Return either the
result as an array, as an object with a key of @list (or appropriate alias from
active context).

Otherwise, construct output as a new JSON object used for returning the result
of compacting element. For each property and value in element:

Perhaps this should also call Value Compaction on
native types and strings, which could consolidate potential transformation in one place.

If, after the algorithm outlined above is run, the resulting element is an array, put element into the
@graph property of a new JSON object and then set element to that JSON object.
Finally, add a @context property to element and set it to the initially passed context.

4.9 RDF Conversion

A JSON-LD document may be converted between other RDF-compatible document
formats using the algorithms specified in this section.

The JSON-LD Processing Model describes processing rules for extracting RDF
from a JSON-LD document, and for transforming an array of Quad retrieved by processing
another serialization format into JSON-LD. Note that many uses of JSON-LD may not require
generation of RDF.

The processing algorithms described in this section are provided in
order to demonstrate how one might implement a JSON-LD to RDF processor.
Conformant implementations are only required to produce the same type and
number of quads during the output process and are not required to
implement the algorithm exactly as described.

4.9.1 Overview

This section is non-normative.

JSON-LD is intended to have an easy to parse grammar that closely models existing
practice in using JSON for describing object representations. This allows the use
of existing libraries for parsing JSON.

As with other grammars used for describing Linked Data, a key
concept is that of a node in a linked data graph.
Nodes may be of three basic types.
The first is the IRI, which is used to refer to
nodes in other linked data graphs.
The second is the
blank node, which are nodes for which an external name does not
exist, or is not known. The third is a Literal, which express
values such as strings, dates and other information having a lexical
form, possibly including an explicit language or datatype.

Data described with JSON-LD may be considered to be a graph made
up of subject and objectnodes related via a propertynode. Specific implementations may also choose to operate
on the document as a normal JSON description of objects having
attributes. Both approaches are valid ways to interact with JSON-LD
documents.

4.9.2 Parsing Examples

This section is non-normative.

The following examples show simple transformations of JSON-LD documents to Turtle [TURTLE-TR].

The first example uses a simple document containing a simple FOAF profile:

The process of translating this to RDF then operates over each
subject definition to find a subject,
each property to find an RDF predicate,
and each value of that property to find an object.
In this case, each property has just a single object:
foaf:name identifies a literal, and
foaf:knows identifies a second subject definition
similar to Turtle's blankNodePropertyList.

After expansion, JSON-LD numbers,
booleans, typed- and language-tagged-literals, and IRIs
become explicit, and can be directly transformed into their RDF representations.

If the value of @value is a number, set the
active object to a typed literal using a string representation
of the value as defined in the section Data Round Tripping.
Set datatype to the value of the @type property if it exists, otherwise
either xsd:integer or xsd:double, depending
on if the value contains a fractional and/or an exponential component.

Otherwise, if the value of @value is true or false,
set the active object to a typed literal created from the
string representation of the value. Set datatype to the value of the @type
property if it exists, otherwise xsd:boolean.

4.9.4 List Conversion

List Conversion is the process of taking an array of values and adding them to a newly
created RDF Collection (see
[RDF-SCHEMA]) by linking each element of the list using rdf:first and rdf:next,
terminating the list with rdf:nil using the following sequence:

Unless this is the last element in array, generate a new blank node identified as
rest blank node, otherwise use rdf:nil.

Generate a new Quad using first blank node,
rdf:rest and rest blank node.

Set first blank node to
rest blank node.

Return first blank node.

4.9.5 Convert from RDF Algorithm

In some cases, data exists natively in Triples or Quads form; for example, if the data was originally
represented in an RDF graph or triple/quad store. This algorithm is designed to simply translate
an array of Quads into a JSON-LD document.

When expanding typed literal values having a datatype of xsd:string,
the @typemust not be set to xsd:string and the resulting value
must have only a @value property.

The conversion algorithm takes a single parameter input in the form of an
array of Quad representations.

Construct graphs as a JSON object containing defaultGraph
identified by
an empty string.

For each quad in input:

Set graph to the entry in graphs identified
by name, initializing it to a new entry using the mechanism
described in Step 1.

If property is rdf:first,
use the entry in graph.listMap indexed by subject,
initializing it to a new JSON object if nesessary. Represent
object in expanded form, as described in
Value Expansion. Add the
resulting object representation to the entry indexed by
first, and skip to the next quad.

If property is rdf:rest:

If object is a blank node, use the entry in
graph.listMap indexed by subject, initializing it
to a new JSON object if necessary. Add the nominalValue of
object to the entry indexed by rest.

Skip to the next quad.

If name is not null, and defaultGraph.subjects
does not contain an entry for name,
create a new entry for name from a new
JSON object with key/value pair of @id and
a string representation of name.

Set value as the entry from graph.subjects for
subject, initializing it to a new
JSON object with key/value pair of @id and
a string representation of subject if necessary.

If property is rdf:type and the notType
option is present and not true:

Append the string representation of object to the array value for the
key @type, creating an entry in value if necessary.

Otherwise, if object is rdf:nil:

Let key be the string representation of property.

Append an empty @list representation to the array value for
key, creating an entry in value if necessary.

Otherwise,

Let key be the string representation of property and let
object representation
be object represented in expanded form as described in
Value Expansion.

If object is a blank node,
use the entry in graph.listMap indexed by object,
initializing it to a new JSON object if nesessary.
Add an entry for head with object representation.

Append object representation to the array value for
key, creating an entry in value if necessary.

For each name and graph in graphs:

For each subject and entry in graph
where entry has both head and first keys:

Set value to the value of head in entry.

Remove the entry for @id in value.

Add an entry to value for @list initialized to a new array
containing the value of first from entry.

For each subject and entry in defaultGraph.subjects
ordered by subject:

Add entry to array.

If graphs has an entry for subject, add a property
@graph in entry containing the ordered entries
from graphs[subject].subjects.

Return array as the result.

5. Data Round Tripping

When coercing numbers to xsd:integer or xsd:double
as it, e.g., happens during RDF Conversion, implementers must
ensure that the result is a canonical lexical form in the form of a
string. A canonical lexical form is a set of literals
from among the valid set of literals for a datatype such that there is a one-to-one mapping
between the canonical lexical form and a value in the value space as defined in
[XMLSCHEMA11-2]]. In other words, every value must be converted to a deterministic string
representation.

The canonical lexical form of an integer, i.e., a number without fractions
or a number coerced to xsd:integer, is a finite-length sequence of decimal
digits (0-9) with an optional leading minus sign; leading zeroes are prohibited.
To convert the number in JavaScript, implementers can use the following snippet of code:

Example 23

(value).toFixed(0).toString()

The canonical lexical form of a double, i.e., a number with fractions
or a number coerced to xsd:double, consists of a mantissa followed by the
character "E", followed by an exponent. The mantissa must be a decimal number. The exponent
must be an integer. Leading zeroes and a preceding plus sign (+) are prohibited
in the exponent. If the exponent is zero, it must be indicated by E0.
For the mantissa, the preceding optional plus sign is prohibited and the decimal point is
required. Leading and trailing zeroes are prohibited subject to the following: number
representations must be normalized such that there is a single digit which is non-zero to the
left of the decimal point and at least a single digit to the right of the decimal point unless
the value being represented is zero. The canonical representation for zero is 0.0E0.
To convert the number in JavaScript, implementers can use the following snippet of code:

When data such as decimals need to be normalized, JSON-LD authors should
not use values that are going to undergo automatic conversion. This is due to the lossy nature
of xsd:double values. Authors should instead use the expanded object form to
set the canonical lexical form directly.

Note

When JSON-native datatypes, like numbers, are type coerced, lossless
data round-tripping can not be guaranted. Consider the following code example:

At this point, myObj1 and myObj2 will have different
values for the "number" property. myObj1 will have the number
42, while myObj2 have an object consisting of
@value set to the string "42" and @type
set to the expanded value of xsd:nonNegativeInteger.

Note

Some JSON serializers, such as PHP's native implementation in some versions,
backslash-escape the forward slash character. For example, the value
http://example.com/ would be serialized as http:\/\/example.com\/.
This is problematic as other JSON parsers might not understand those escaping characters.
There is no need to backslash-escape forward slashes in JSON-LD. To aid interoperability
between JSON-LD processors, a JSON-LD serializer must not backslash-escape forward slashes.

A. Initial Context

Issue 8

It is still being
discussed whether JSON-LD has the notion of an initial context or not. If JSON-LD has an
initial context, it must be specified external to the JSON-LD Syntax specification at a
well-known location.

B. Acknowledgements

The editors would like to thank Mark Birbeck, who provided a great deal of
the initial push behind the JSON-LD work via his work on RDFj,
Dave Lehn and Mike Johnson who reviewed, provided feedback, and
performed several implementations of the specification, and Ian Davis, who
created RDF/JSON. Thanks also to Nathan Rixham, Bradley P. Allen,
Kingsley Idehen, Glenn McDonald, Alexandre Passant, Danny Ayers, Ted
Thibodeau Jr., Olivier Grisel, Josh Mandel, Eric Prud'hommeaux,
David Wood, Guus Schreiber, Pat Hayes, Sandro Hawke, and Richard
Cyganiak for their input on the specification.

The JSON-LD Syntax Manu Sporny, Gregg Kellogg, Markus Lanthaler Editors. World Wide Web Consortium (work in progress). 22 May 2012. Editor's Draft. This edition of the JSON-LD Syntax specification is http://json-ld.org/spec/ED/json-ld-syntax/20120522/. The latest edition of the JSON-LD Syntax is available at http://json-ld.org/spec/latest/json-ld-syntax/

Web IDL Cameron McCormack, Editor. World Wide Web Consortium. 19 April 2012. Candidate Recommendataion. This edition of Web IDL is http://www.w3.org/TR/2012/CR-WebIDL-20120419/. The latest edition of Web IDL is available at http://dev.w3.org/2006/webapi/WebIDL/