JSON-LD - Linked Data Expression in JSON 1.0

A Context-based JSON Serialization for Linked Linking Data

Unofficial Draft 15 June 03 August 2011

Editors:
Manu Sporny , Digital Bazaar, Inc.
Gregg Kellogg , Kellogg Associates
Authors:
Mark Birbeck , Backplane Ltd.
Manu Sporny , Digital Bazaar, Inc.
This document is also available in this non-normative format: diff to previous version .

Abstract

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.

Status of This 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.

Table of Contents

1. Introduction

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.

JSON, as specified in [ RFC4627 ], is a simple language for representing objects on the web. Linked Data is a way of describing content across different documents, or web resources. 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 linked data in JSON.

1.1 How to Read this Document

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 ].

1.2 Contributing

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

2. Design Goals and Rationale

The following section outlines the design goals and rationale behind the JSON-LD markup language.

2.1 Goals and Rationale

A number of design considerations were explored during the creation of this markup language:

Simplicity
Developers don't need to only know RDF in order JSON and three keywords to use the basic functionality provided by in JSON-LD. No extra processors or software libraries are necessary to use JSON-LD in its most basic form. The language attempts to ensure that developers have an easy learning curve.
Compatibility
The JSON-LD markup should must be 100% compatible with JSON. This ensures that all of the standard JSON libraries work seamlessly with JSON-LD documents.
Expressiveness
All major RDF concepts The syntax must be expressible via the JSON-LD syntax. able to express directed graphs, which have been proven to be able to simply express almost every real world data model.
Terseness
The JSON-LD syntax must be very terse and human readable. readable, requiring as little as possible from the developer.
Pragmatism
Mixing the expression of pure Linked Data with data that is not linked was an approach that was driven by pragmatism. JSON-LD attempts to be more practical than theoretical in its approach to Linked Data.
Zero Edits, most of the time
JSON-LD provides a mechanism that allows developers to specify context in a way that is out-of-band. This allows organizations that have already deployed large JSON-based infrastructure to add meaning to their JSON in a way that is not disruptive to their day-to-day operations and is transparent to their current customers. At times, mapping JSON to RDF a graph representation can become difficult - in difficult. In these instances, rather than having JSON-LD support esoteric markup, we chose not to support the use case and support a simplified syntax instead. So, while we strive for Zero Edits, Edits was a goal, it was not always possible without adding great complexity to the language.
Streaming
The format supports both document-based and stream-based processing.

2.2 Map Terms Linked Data

The following definition for Linked Data is the one that will be used for this specification.

  1. Linked Data is a set of documents, each containing a representation of a linked data graph.
  2. A linked data graph is a labeled directed graph, where nodes are subject s or object s, and edges are properties.
  3. A subject is any node in a linked data graph with at least one outgoing edge.
  4. A subject should be labeled with a IRI.
  5. A property is an edge of the linked data graph .
  6. A property must be labeled with an IRI.
  7. An object is a node in a linked data graph with at least one incoming edge.
  8. An object may be labeled with an IRI.
  9. An IRI that is a label in a linked data graph should be dereferencable to IRIs a Linked Data document describing the labeled subject , object or property .
  10. A literal is an object with a label that is not an IRI

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.

2.3 Linking Data

An Internationalized Resource Identifier ( IRI ) ), as described in [ RFC3987 ], is a mechanism for representing unique identifiers on the web. In Linked Data, IRIs (or URI references) are Data , an IRI is commonly used for describing entities and properties. expressing a subject , a property or an object .

Establishing JSON-LD defines a mechanism to map JSON values to IRIs will help in the mapping of JSON objects to RDF. IRIs. This does not mean that JSON-LD must requires every key or value to be restrictive in declaring a set of terms, rather, experimentation an IRI, but rather ensures that keys and innovation should values can be supported as part of mapped to IRIs if the core design of JSON-LD. developer so desires to transform their data into Linked Data. There are, however, are a number of very small design criteria few techniques that can ensure that developers will generate good RDF data that will create value Linked Data for the greater semantic web community and JSON/REST-based Web Services community. Web. JSON-LD formalizes those techniques.

We will be using the following JSON object markup as the example for the rest of this section:

{ "a": "Person", "name": "Manu Sporny", "homepage": "http://manu.sporny.org/" "avatar": "http://twitter.com/account/profile_image/manusporny"
{
  "name": "Manu Sporny",
  "homepage": "http://manu.sporny.org/"
  "avatar": "http://twitter.com/account/profile_image/manusporny"

}

2.3 2.4 The JSON-LD Context

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.

2.4 2.4.1 Unambiguous Identifiers for JSON If a set of terms, like Person , name , and homepage , are defined in Inside a context, and that context is used to resolve Context

In the names in JSON objects, machines could automatically expand previous section, the terms developer used the @context keyword to pull in an external context. That context document, if de-referenced, would look something meaningful and unambiguous, like this:

{ "", "": "Manu Sporny", "": "http://manu.sporny.org" "": "http://twitter.com/account/profile_image/manusporny"
{
    "name": "http://xmlns.com/foaf/0.1/name",
    "homepage": "http://xmlns.com/foaf/0.1/homepage"
    "avatar": "http://xmlns.com/foaf/0.1/avatar"

}

Doing this would mean that JSON would start to become unambiguously machine-readable, play well with the semantic web, and basic markup wouldn't be that much more complex than basic JSON markup. A win, all around. 2.5 Mashing Up Vocabularies Developers would also benefit by allowing other vocabularies to be used automatically with their JSON API. There are over 200 Vocabulary Documents that are available for use on the Web today. Some of these vocabularies are: RDF - for describing information about objects on the semantic web. RDFS - for expressing things like labels and comments. XSD - for specifying basic types like strings, integers, dates and times. Dublin Core - for describing creative works. FOAF - for describing social networks. Calendar - for specifying events. SIOC - for describing discussions on blogs and websites. CCrel - for describing Creative Commons and other types of licenses. GEO - for describing geographic location. VCard - for describing organizations and people. DOAP - for describing projects. Since these vocabularies are very popular, they are pre-defined in something called the default JSON-LD context , which document is a set of vocabulary prefixes that are pre-loaded in all JSON-LD processors. The contents of the default context simple mapping from term are provided later in this document. Using the default context s and prefix allows developers es to express data unambiguously, like so: { "", "": "Manu Sporny", "": "http://manu.sporny.org/", "": "http://twitter.com/account/profile_image/manusporny" } Developers can 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.

2.6 An Example of a Context

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.

3. 2.5 Markup Examples The JSON-LD markup examples below demonstrate how JSON-LD can be used From JSON 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. 3.1 RDFa

The following example describes three people with their respective names If a set of terms such as, name , homepage , and homepages. <div > <ul> <li > <a >Bob</a> </li> <li > <a >Eve</a> </li> <li > <a >Manu</a> </li> </ul> </div> An example JSON-LD implementation is described below, however, there avatar , are other ways to mark-up this information such defined in a context, and that the context is not repeated. [ { "@": "_:bnode1", "a": "foaf:Person", "foaf:homepage": "http://example.com/bob/", "foaf:name": "Bob" }, { "@": "_:bnode2", "a": "foaf:Person", "foaf:homepage": "http://example.com/eve/", "foaf:name": "Eve" }, { "@": "_:bnode3", "a": "foaf:Person", "foaf:homepage": "http://example.com/manu/", "foaf:name": "Manu" } ] 3.2 Microformats The following example uses a simple Microformats hCard example used to express how resolve the Microformat is represented names in JSON-LD. <div class="vcard"> <a class="url fn" href="http://tantek.com/">Tantek Çelik</a> </div> The representation of the hCard expresses JSON objects, machines are able to automatically expand the Microformat terms in the context and uses them directly for the url and fn properties. Also note that the Microformat to JSON-LD processor has generated the proper URL type for http://tantek.com . something meaningful and unambiguous, like this:

{ "@context": { "vcard": "http://microformats.org/profile/hcard#vcard", "url": "http://microformats.org/profile/hcard#url", "fn": "http://microformats.org/profile/hcard#fn", "@coerce": { "xsd:anyURI": "url" } }, "@": "_:bnode1", "a": "vcard", "url": "http://tantek.com/", "fn": "Tantek Çelik"
{
  "http://xmlns.com/foaf/0.1/name": "Manu Sporny",
  "http://xmlns.com/foaf/0.1/homepage": "http://manu.sporny.org"
  "http://rdfs.org/sioc/ns#avatar": "http://twitter.com/account/profile_image/manusporny"

}
3.3 Microdata

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.

[ { "@": "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" } ]

4. 3. Markup of RDF Basic Concepts

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.

4.1 3.1 IRIs

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.

  1. In general, an IRI is generated if it is term s in the key position in an associative array. array that have a mapping to an IRI in the context are expanded to an IRI by JSON-LD processors. There are special rules for processing keys in @context and when dealing with keys that start with the @ character.
  2. An IRI is generated for the value specified using @ @subject , if it is a string.
  3. An IRI is generated for the value specified using a @type .
  4. An IRI is generated for the value specified using the @iri keyword.
  5. An IRI is generated when there are @coerce rules in effect for xsd:anyURI for a particular vocabulary term. key named @iri .

An example of IRI generation for a IRIs can be expressed directly in the key outside of a @context : position like so:

{ ... "": "Manu Sporny", ...
{
...
  "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 :

{ ""}, ... "": "Manu Sporny", ...
{
  "@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:

{ ... "": "Manu Sporny", ...
{
  "@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": { "": "http://manu.sporny.org" } ...
{
...
  "foaf:homepage": { "@iri": "http://manu.sporny.org" }
...

}

If type coercion rules are specified in the @context for a particular vocabulary term, an IRI is generated:

{ "@context": { "@coerce": { "xsd:anyURI": "foaf:homepage" } } ... "foaf:homepage": "http://manu.sporny.org", ...
{
  "@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

4.2 3.2 Identifying the Subject

A subject is declared using the @ @subject 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": "http://example.org/people#joebob",
...

}

The example above would set the subject to the IRI http://example.org/people#joebob .

4.3 3.3 Specifying the Type

The type of a particular subject can be specified using the a @type key. Specifying the type in this way will generate a triple of the form (subject, type, type-url).

{ ... "@": "http://example.org/people#joebob", "", ...
{
...
  "@subject": "http://example.org/people#joebob",
  "@type": "http://xmlns.com/foaf/0.1/Person",
...

}

The example above would generate the following triple if the JSON-LD document is mapped to RDF (in N-Triples notation):

<http://example.org/people#joebob> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
<http://example.org/people#joebob> 
   <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>

<http://xmlns.com/foaf/0.1/Person>
.

4.4 3.4 Plain Literals Strings

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": "", ...
{
...
  "foaf:name": "Mark Birbeck",
...

}

4.5 3.5 Language Specification in Plain Literals String Internationalization

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" } ...
{
...
  "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.

4.6 3.6 Typed Literals Datatypes

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:

  1. By utilizing the @coerce keyword.
  2. By utilizing the expanded form for specifying objects.
  3. By using a native JSON datatype.

The first example uses the @coerce keyword to express a typed literal:

{ "@context": { "@coerce": { "xsd:dateTime": "dc:modified" } } ... "dc:modified": "2010-05-29T14:17:39+02:00", ...
{
  "@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" } ...
{
...
  "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>
.

4.7 3.7 Multiple Objects for a Single Property

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": , ...
{
...
  "@": "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>
<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"
.

4.8 3.8 Multiple Typed Literals for a Single Property

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" } ] ...
{
...
  "@": "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>
<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
.

4.9 3.9 Blank Nodes Compaction

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.

{ ... "@": "", ...

3.10 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 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/"
   }
}

3.11 Framing

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.

5. 4. Advanced Features Concepts

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.

5.1 4.1 Automatic Typing

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": , "measure:cups": , // The following value is automatically converted to a type of xsd:double as well "space:astronomicUnits": , // The following value should never be converted to a language-native type "measure:stones": , // 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": , ...
{
...
  // 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.

5.2 4.2 Type Coercion

JSON-LD supports the coercion of types values to ensure that the zero-edit goal of JSON-LD can be accomplished. particular data types. Type coercion allows someone deploying JSON-LD to coerce and the incoming or outgoing types to the proper RDF data type based on a mapping of data type IRIs to RDF property types. Using type conversion, coercion, one may convert simple JSON data to properly typed RDF data.

The example below demonstrates how a JSON-LD author can coerce values to plain literal s, typed literal s and IRIs.

{ "@context": { "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "xsd": "http://www.w3.org/2001/XMLSchema#", "name": "http://xmlns.com/foaf/0.1/name", "age": "http://xmlns.com/foaf/0.1/age", "homepage": "http://xmlns.com/foaf/0.1/homepage", "@coerce": { "xsd:integer": "age", "xsd:anyURI": "homepage", } }, "name": "John Smith", "age": , "homepage":
{
  "@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>
_: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/>
.

4.3 Chaining

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.

6. 4.4 Identifying Unlabeled Nodes

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.

4.5 Overriding Keywords

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.

4.6 Normalization

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.

5. Algorithms

5.1 Compaction

TBD: Explain compaction algorithm.

5.2 Expansion

TBD: Explain expansion algorithm.

5.3 Framing

TBD: Explain framing algorithm.

5.4 Normalization

TBD: Explain normalization algorithm.

5.5 RDF Conversion

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.

6.1 5.5.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 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.

6.2 5.5.2 Processing Algorithm Terms

default initial context
a context that is specified to the JSON-LD processing algorithm before processing begins.
default graph
the destination graph for all triples generated by JSON-LD markup.
active subject
the currently active subject that the processor should use when generating triples.
active property
the currently active property that the processor should use when generating triples.
active object
the currently active object that the processor should use when generating triples.
active context
a context that is used to resolve CURIEs while the processing algorithm is running. The active context is the context contained within the processor state .
local context
a context that is specified at the JSON associative-array level, specified via the @context keyword.
processor state
the processor state , which includes the active context , current subject , and current property . The processor state is managed as a stack with elements from the previous processor state copied into a new processor state when entering a new associative array.

6.3 5.5.3 Processing Tokens and Keywords

@context
Used to set the local context .
@base
Used to set the base IRI for all object IRIs affected by the active context .
@profile A reference to a remote context description used to set the local context . @vocab
Used to set the base IRI for all property IRIs affected by the active context .
@coerce
Used to specify type coercion rules.
@literal
Used to specify a literal value.
@iri
Used to specify an IRI value.
@language
Used to specify the language for a literal.
@datatype
Used to specify the datatype for a literal.
:
The separator for CURIEs when used in JSON keys or JSON values.
@ @subject
Sets the active subjects.
a @type
Used to set the rdf:type of the active subjects. This token may be conferred as syntactic sugar for rdf:type.
Use @source instead of @ ? Use @type instead of a ? Note that both are just semantic sugar for rdf:type .

6.4 5.5.4 Context

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:

  • The key @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 .
  • The key @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 .
  • The key @coerce must have a value of an associative array. Processing of the associative array is described below
  • Otherwise, the key must have the lexical form of NCName and must have the value of a simple string with the lexical form of IRI. Merge each key-value pair into the active context , overwriting any duplicate values.
A local context may also be loaded from an external document using the @profile key as described in Vocabulary Profiles . 6.4.1
Coerce

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.

6.5 Chaining 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 objects. The example shows an two objects related by a property from the first object: { ... "foaf:name": "Manu Sporny", "": { "", "", } ... } An object definition may be used anyplace a value is legal in JSON-LD.

6.6 5.5.5 IRI Processing

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:

  1. Split the value into a prefix and suffix from the first occurrence of ':'.
  2. If the prefix is a '_', generate a named BNode using the suffix as the name.
  3. If the active context contains a mapping for prefix , generate an IRI by prepending the mapped prefix to the (possibly empty) suffix. Note that an empty suffix and no suffix (meaning the value contains no ':' string at all) are treated equivalently.
  4. If the IRI being processed is for a property (i.e., a key value in an associative array, or a value in a @coerce mapping) and the active context has a @vocab mapping, join the mapped value to the suffix using the method described in [ RFC3987 ].
  5. If the IRI being processed is for a subject or object (i.e., not a property) and the active context has a @base mapping, join the mapped value to the suffix using the method described in [ RFC3987 ].
  6. Otherwise, use the value directly as an IRI.

7. 5.5.6 Sequence

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:

  1. Create a new processor state with with the active context set to the default initial context and active subject and active property initialized to NULL.
  2. If an associative array is detected, perform the following steps:
    1. If the associative array has a @context key, process the local context as described in Context .
    2. If the associative array has an @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.
    3. If the associative array has a @literal key, set the active object to a literal value as follows:
      • as a typed literal if the associative array contains a @datatype key after performing IRI Processing on the specified @datatype .
      • otherwise, as a plain literal . If the associative array contains a @language key, use it's value to set the language of the plain literal.
      Generate a triple representing the active subject , the active property and the active object . Return the active object to the calling location.
    4. If the associative array has a @ key:
      1. If the value is a string, set the active object to the result of performing IRI Processing . Generate a triple representing the active subject , the active property and the active object . Set the active subject to the active object .
      2. Create a new processor state using copies of the active context , active subject and active property and process the value starting at Step 2 , set the active subject to the result and proceed using the previous processor state .
    5. If the associative array does not have a @ 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 .
    6. For each key in the associative array that has not already been processed, perform the following steps:
      1. If the key is a , set the active property to rdf:type .
      2. Otherwise, set the active property to the result of performing IRI Processing on the key.
      3. Create a new processor state copies of the active context , active subject and active property and process the value starting at Step 2 and proceed using the previous processor state .
    7. Return the active object to the calling location.
  3. If a regular array is detected, process each value in the array by doing the following returning the result of processing the last value in the array:
    1. If the value is a regular array, generate an RDF List by linking each element of the list using rdf:first and rdf:next , terminating the list with rdf:nil using the following sequence:
      1. If the list has no element, generate a triple using the active subject , active property and rdf:nil .
      2. Otherwise, generate a triple using using the active subject , active property and a newly generated BNode identified as first bnode .
      3. For each element other than the last element in the list:
        1. Create a processor state using the active context, first bnode as the active subject , and rdf:first as the active property .
        2. Unless this is the last element in the list, generate a new BNode identified as rest bnode , otherwise use rdf:nil .
        3. Generate a new triple using first bnode , rdf:rest and rest bnode .
        4. Set first bnode to rest bnode .
    2. Otherwise, create a new processor state copies of the active context , active subject and active property and process the value starting at Step 2 and proceed using the previous processor state .
  4. If a string is detected, generate a triple using the active subject , active object and a plain literal value created from the string.
  5. If a number is detected, generate a typed literal using a string representation of the value with datatype set to either 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.
  6. Otherwise, if true or false is detected, generate a triple using the active subject , active object and a typed literal value created from the string representation of the value with datatype set to xsd:boolean .
8. Best Practices The nature of Web programming allows one to use basic technologies, such as JSON-LD, across a variety of systems and environments. This section attempts to describe some of those environments and the way in which JSON-LD can be integrated in order to help alleviate certain development headaches. 8.1 JavaScript It is expected that JSON-LD will be used quite a bit in JavaScript environments, however, features like the expanded form for object values mean that using JSON-LD directly in JavaScript may be annoying without a middleware layer such as a simple library that converts JSON-LD markup before JavaScript uses it. One could say that JSON-LD is a good fit for the RDF API, which enables a variety of RDF-based Web Applications, but some don't want to require that level of functionality just to use JSON-LD. The group is still discussing the best way to proceed, so input on how JSON-LD could more easily be utilized in JavaScript environments would be very much appreciated. 8.2 Schema-less Databases Databases such as CouchDB and MongoDB allow the creation of schema-less data stores. RDF is a type of schema-less data model and thus lends itself to databases such as CouchDB and MongoDB. Both of these databases can use JSON-LD as their storage format. The group needs feedback from CouchDB and MongoDB experts regarding the usefulness of JSON-LD in those environments. MongoDB does not allow the '.' character to be used in key names. This prevents developers from storing IRIs as keys, which also prevents storage of the data in normalized form. While this issue can be avoided by using CURIEs for key values, it is not known if this mechanism is enough to allow JSON-LD to be used in MongoDB in a way that is useful to developers.

9. 6. Advanced Experimental Concepts

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.

9.1 Vocabulary Profiles One of the more powerful features of RDFa 1.1 Core is the ability to specify a collection of prefixes and terms that can be re-used by a processor to simplfy markup. JSON-LD provides a similar mechanism called Vocabulary Profiles, which is the inclusion of a context external to the JSON-LD document. The example below demonstrates how one may specify an external Vocabulary Profile. Assume the following profile exists at this imaginary URL: http://example.org/profiles/contacts . { "@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", "#types": { "age": "xsd:integer", "homepage": "xsd:anyURI", } } } The profile listed above can be used in the following way: { "@profile": "http://example.org/profiles/contacts", "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/> .

9.2 6.1 Disjoint Graphs

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://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" } ]
{
  "@": 
  [
    {
      "@": "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" }
[
  {
    "@": "http://example.org/people#john",
    "a": "foaf:Person"
  },
  {
    "@": "http://example.org/people#jane",
    "a": "foaf:Person"
  }

]

9.3 6.2 The JSON-LD API

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.

] interface { };
[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);

};

9.3.1 6.2.1 Methods

toGraph
Parses JSON-LD and transforms the data into an Graph, which is compatible with the RDF Interfaces API specification [ RDF-INTERFACES ]. This method will return 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.
No exceptions.
Return type: Graph
toProjection
Parses JSON-LD text into an RDF API Projection object as specified by the RDF API specification [ RDF-API ]. If there are any errors, 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.
No exceptions.
Return type: object

The JSONLDParserCallback is called whenever a processing error occurs on input data.

] interface { };
[NoInterfaceObject Callback]
interface JSONLDProcessorCallback {
    void error (in DOMString error);

};

9.3.2 6.2.2 Methods

error
This callback is invoked whenever an error occurs during processing.
Parameter Type Nullable Optional Description
error DOMString ✘ ✘ A descriptive error string returned by the processor.
No exceptions.
Return type: void

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. " +
// 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);

};

9.3.3 6.2.3 Methods

normalize
Serializes a language-native object into a normalized JSON-LD string. Normalization is important when performing things like equality comparison and digital signature creation and verification.
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.
No exceptions.
Return type: DOMString

The Normalization Algorithm

This algorithm is very rough, untested, and probably contains many bugs. Use at your own risk. It will change in the coming months.

The JSON-LD normalization algorithm is as follows:

  1. Remove the @context key and preserve it as the transformation map while running this algorithm.
  2. For each key
    1. If the key is a CURIE, expand the CURIE to an IRI using the transformation map .
  3. For each value
    1. If the value should be type coerced per the transformation map , ensure that it is transformed to the new value.
    2. If the value is a CURIE, expand the CURIE to an IRI using the transformation map .
    3. If the value is a typed literal and the type is a CURIE, expand it to an IRI using the transformation map .
    4. When generating the final value, use expanded object value form to store all IRIs, typed literals and plain literal s with language information.
  4. Output each sorted key-value pair without any extraneous whitespace. If the value is an associative array, perform this algorithm, starting at step #1, recursively on the sub-tree. There should be no nesting in the outputted JSON data. That is, the top-most element should be an array. Each item in the array contains a single subject with a corresponding array of properties in UTF-8 sort order. Any related objects that are complex objects themselves should be given a top-level object in the top-level array.

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 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/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
// 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 myObj = { "@context" : { 
                "number" : "http://example.com/vocab#number",
                "@coerce": {
                   "xsd:nonNegativeInteger": "number"
                }
              },
              "number" : 42 };

// Map the language-native object to JSON-LD
var jsonldText = jsonld.normalize(myObj);

// Convert the normalized object back to a JavaScript object

var
myObj2
=
jsonld.parse(jsonldText);

At this point, myObj2 and myObj will have different values for the "number" value. myObj will be the number 42, while myObj2 will be the string "42". This type of data round-tripping error can bite developers. We are currently wondering if having a "coerce validation" phase in the parsing/normalization phases would be a good idea. It would prevent data round-tripping issues like the one mentioned above.

A. The Default Context Markup Examples

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.

A.1 RDFa

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"
 }
]

A.2 Microformats

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"
}

A.3 Microdata

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"
  }
]

A.4 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:

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": { "@vocab": "", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "owl": "http://www.w3.org/2002/07/owl#", "xsd": "http://www.w3.org/2001/XMLSchema#", "dcterms": "http://purl.org/dc/terms/", "foaf": "http://xmlns.com/foaf/0.1/", "cal": "http://www.w3.org/2002/12/cal/ical#", "vcard": "http://www.w3.org/2006/vcard/ns# ", "geo": "http://www.w3.org/2003/01/geo/wgs84_pos#", "cc": "http://creativecommons.org/ns#", "sioc": "http://rdfs.org/sioc/ns#", "doap": "http://usefulinc.com/ns/doap#", "com": "http://purl.org/commerce#", "ps": "http://purl.org/payswarm#", "gr": "http://purl.org/goodrelations/v1#", "sig": "http://purl.org/signature#", "ccard": "http://purl.org/commerce/creditcard#" "@coerce": { "xsd:anyURI": ["rdf:type", "rdf:rest", "foaf:homepage", "foaf:member"], "xsd:integer": "foaf:age" } }
{
  "@context": { "myvocab": "http://example.org/myvocab#" },
  "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.

B. A.5 Acknowledgements

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.

C. B. References

C.1 B.1 Normative references

[BCP47]
A. Phillips, M. Davis. Tags for Identifying Languages September 2009. IETF Best Current Practice. URL: http://tools.ietf.org/rfc/bcp/bcp47.txt
[RDF-API]
Manu Sporny, Benjamin Adrian, Nathan Rixham; et al. RDF API Latest. W3C Editor's Draft. URL: http://www.w3.org/2010/02/rdfa/sources/rdf-api/
[RDF-CONCEPTS]
Graham Klyne; Jeremy J. Carroll. Resource Description Framework (RDF): Concepts and Abstract Syntax. 10 February 2004. W3C Recommendation. URL: http://www.w3.org/TR/2004/REC-rdf-concepts-20040210
[RDF-INTERFACES]
Nathan Rixham, Manu Sporny, Benjamin Adrian; et al. RDF Interfaces Latest. W3C Editor's Draft. URL: http://www.w3.org/2010/02/rdfa/sources/rdf-interfaces/
[RFC3987]
M. Dürst; Dürst; M. Suignard. Internationalized Resource Identifiers (IRIs). January 2005. Internet RFC 3987. URL: http://www.ietf.org/rfc/rfc3987.txt
[RFC4627]
D. Crockford. The application/json Media Type for JavaScript Object Notation (JSON) July 2006. Internet RFC 4627. URL: http://www.ietf.org/rfc/rfc4627.txt
[WEBIDL]
Cameron McCormack. Web IDL. 19 December 2008. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2008/WD-WebIDL-20081219

C.2 B.2 Informative references

[ECMA-262]
ECMAScript Language Specification, Third Edition. December 1999. URL: http://www.ecma-international.org/publications/standards/Ecma-262.htm
[MICRODATA]
Ian Hickson; et al. Microdata 04 March 2010. W3C Working Draft. URL: http://www.w3.org/TR/microdata/
[MICROFORMATS]
Microformats . URL: http://microformats.org
[RDFA-CORE]
Shane McCarron; et al. RDFa Core 1.1: Syntax and processing rules for embedding RDF through attributes. 31 March 2011. W3C Working Draft. URL: http://www.w3.org/TR/2011/WD-rdfa-core-20110331