--- a/spec/latest/json-ld-api/index.html Tue Aug 14 18:07:27 2012 +0200
+++ b/spec/latest/json-ld-api/index.html Tue Aug 14 18:40:32 2012 +0200
@@ -1,2287 +1,2288 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>JSON-LD API 1.0</title>
-<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
-<!--
- === NOTA BENE ===
- For the three scripts below, if your spec resides on dev.w3 you can check them
- out in the same tree and use relative links so that they'll work offline,
- -->
-<script type="text/javascript" src="../respec-w3c-common.js" class="remove"></script>
-<script type="text/javascript" class="remove">
-//<![CDATA[
- var preProc = {
- apply: function(c) {
- // extend the bibliography entries
- berjon.biblio["MICRODATA"] = "<cite><a href=\"http://www.w3.org/TR/2012/WD-microdata-20120329/\">HTML Microdata</a></cite> Ian Hickson Editor. World Wide Web Consortium (work in progress). 29 March 2012. This edition of the HTML Microdata specification is http://www.w3.org/TR/2012/WD-microdata-20120329/. The <a href=\"http://www.w3.org/TR/microdata/\">latest edition of HTML Microdata</a> is available at http://www.w3.org/TR/microdata/";
- berjon.biblio["JSON-LD"] = "<cite><a href=\"http://json-ld.org/spec/ED/json-ld-syntax/20120522/\">The JSON-LD Syntax</a></cite> 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 <a href=\"http://json-ld.org/spec/latest/json-ld-syntax/\">latest edition of the JSON-LD Syntax</a> is available at http://json-ld.org/spec/latest/json-ld-syntax/";
- berjon.biblio["JSON-POINTER"] = "<cite><a href=\"http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-02\">JSON Pointer</a></cite> P. Bryan, Ed. IETF Draft. URL: <a href=\"http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-02\">http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-02</a>";
- berjon.biblio["RDF-NORMALIZATION"] = "<cite><a href=\"http://json-ld.org/spec/ED/rdf-graph-normalization/20111016/\">RDF Graph Normalization</a></cite> Manu Sporny, Dave Longley Editors. World Wide Web Consortium (work in progress). 16 October 2011. Editor's Draft. This edition of the RDF Graph Normalization specification is http://json-ld.org/spec/ED/rdf-graph-normalization/20111016/. The <a href=\"http://json-ld.org/spec/latest/rdf-graph-normalization/\">latest edition of RDF Graph Normalization</a> is available at http://json-ld.org/spec/latest/rdf-graph-normalization/";
- berjon.biblio["IEEE-754-1985"] = "IEEE. <cite>IEEE Standard for Binary Floating-Point Arithmetic.</cite> See <a href=\"http://standards.ieee.org/reading/ieee/std_public/description/busarch/754-1985_desc.html\">http://standards.ieee.org/reading/ieee/std_public/description/busarch/754-1985_desc.html</a>";
- berjon.biblio["RDF-CONCEPTS"] = "<cite><a href=\"http://www.w3.org/TR/2011/WD-rdf11-concepts-20110830/\">RDF 1.1 Concepts and Abstract Syntax</a></cite> Richard Cyganiak, David Wood, Editors. World Wide Web Consortium (work in progress). 30 May 2012. Editor's Draft. This edition of the JSON-LD Syntax specification is http://www.w3.org/TR/2011/WD-rdf11-concepts-20110830/. The <a href=\"http://www.w3.org/TR/rdf11-concepts/\">latest edition of the JSON-LD Syntax</a> is available at http://www.w3.org/TR/rdf11-concepts/";
- berjon.biblio["TURTLE-TR"] = "Eric Prud'hommeaux, Gavin Carothers. <cite><a href=\"http://www.w3.org/TR/2011/WD-turtle-20110809/\">Turtle: Terse RDF Triple Language.</a></cite> 09 August 2011. W3C Working Draft. URL: <a href=\"http://www.w3.org/TR/2011/WD-turtle-20110809/\">http://www.w3.org/TR/2011/WD-turtle-20110809/</a>";
- berjon.biblio["WEBIDL"] = "<cite><a href=\"http://www.w3.org/TR/2012/CR-WebIDL-20120419/\">Web IDL</a></cite> 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 <a href=\"http://dev.w3.org/2006/webapi/WebIDL/\">latest edition of Web IDL</a> is available at http://dev.w3.org/2006/webapi/WebIDL/";
-
- // process the document before anything else is done
- var refs = document.querySelectorAll('adef') ;
- for (var i = 0; i < refs.length; i++) {
- var item = refs[i];
- var p = item.parentNode ;
- var con = item.innerHTML ;
- var sp = document.createElement( 'dfn' ) ;
- var tit = item.getAttribute('title') ;
- if (!tit) {
- tit = con;
- }
- sp.className = 'adef' ;
- sp.title=tit ;
- sp.innerHTML = con ;
- p.replaceChild(sp, item) ;
- }
- refs = document.querySelectorAll('aref') ;
- for (var i = 0; i < refs.length; i++) {
- var item = refs[i];
- var p = item.parentNode ;
- var con = item.innerHTML ;
- var sp = document.createElement( 'a' ) ;
- sp.className = 'aref' ;
- sp.setAttribute('title', con);
- sp.innerHTML = '@'+con ;
- p.replaceChild(sp, item) ;
- }
- // local datatype references
- refs = document.querySelectorAll('ldtref') ;
- for (var i = 0; i < refs.length; i++) {
- var item = refs[i];
- if (!item) continue ;
- var p = item.parentNode ;
- var con = item.innerHTML ;
- var ref = item.getAttribute('title') ;
- if (!ref) {
- ref = item.textContent ;
- }
- if (ref) {
- ref = ref.replace(/\s+/g, '_') ;
- }
- var sp = document.createElement( 'a' ) ;
- sp.className = 'datatype idlType';
- sp.title = ref ;
- sp.setAttribute('href', '#idl-def-' + ref);
- sp.innerHTML = '<code>' + con + '</code>';
- p.replaceChild(sp, item) ;
- }
- // external datatype references
- refs = document.querySelectorAll('dtref') ;
- for (var i = 0; i < refs.length; i++) {
- var item = refs[i];
- if (!item) continue ;
- var p = item.parentNode ;
- var con = item.innerHTML ;
- var ref = item.getAttribute('title') ;
- if (!ref) {
- ref = item.textContent ;
- }
- if (ref) {
- ref = ref.replace(/\s+/g, '_') ;
- }
- var sp = document.createElement( 'a' ) ;
- sp.className = 'externalDFN';
- sp.title = ref ;
- sp.innerHTML = con ;
- p.replaceChild(sp, item) ;
- }
- // now do terms
- refs = document.querySelectorAll('tdef') ;
- var tdefs = [];
- for (var i = 0; i < refs.length; i++) {
- var item = refs[i];
- if (!item) continue ;
- var p = item.parentNode ;
- var con = item.innerHTML ;
- var ref = item.getAttribute('title') ;
- if (!ref) {
- ref = item.textContent ;
- }
- if (ref) {
- ref = ref.replace(/\s+/g, '_').toLowerCase() ;
- }
-
- if ( tdefs[ref]) {
- throw "Duplicate definition of term '" + ref + "'" ;
- }
-
- var sp = document.createElement( 'dfn' ) ;
- tdefs[ref] = sp ;
- sp.title = ref ;
- sp.innerHTML = con ;
- p.replaceChild(sp, item) ;
- }
- // now term references
- refs = document.querySelectorAll('tref') ;
- for (var i = 0; i < refs.length; i++) {
- var item = refs[i];
- if (!item) continue ;
- var p = item.parentNode ;
- var con = item.innerHTML ;
- var ref = item.getAttribute('title') ;
- if (!ref) {
- ref = item.textContent ;
- }
- if (ref) {
- ref = ref.replace(/\s+/g, '_').toLowerCase() ;
- }
-
- if ( !tdefs[ref]) {
- throw "Reference to undefined term '" + ref + "'" ;
- }
- var sp = document.createElement( 'a' ) ;
- var id = item.textContent ;
- sp.className = 'tref' ;
- sp.title = ref ;
- sp.innerHTML = con ;
- p.replaceChild(sp, item) ;
- }
- }
- } ;
-
-
- var respecConfig = {
- doRDFa: "1.1",
- // specification status (e.g. WD, LCWD, NOTE, etc.). If in doubt use ED.
- specStatus: "FPWD",
- publishDate: "2012-07-12",
- copyrightStart: "2010",
-
- // the specification's short name, as in http://www.w3.org/TR/short-name/
- shortName: "json-ld-api",
- subtitle: "An Application Programming Interface for the JSON-LD Syntax",
- // if you wish the publication date to be other than today, set this
- // publishDate: "2009-08-06",
-
- // if there is a previously published draft, uncomment this and set its YYYY-MM-DD date
- // and its maturity status
- previousPublishDate: "2012-06-26",
- previousMaturity: "CG-FINAL",
- previousDiffURI: "http://json-ld.org/spec/ED/json-ld-api/20120626/",
- diffTool: "http://www.aptest.com/standards/htmldiff/htmldiff.pl",
-
- // if there a publicly available Editor's Draft, this is the link
- edDraftURI: "http://dvcs.w3.org/hg/json-ld/raw-file/default/spec/latest/json-ld-api/index.html",
-
- // if this is a LCWD, uncomment and set the end of its review period
- // lcEnd: "2009-08-05",
-
- // if you want to have extra CSS, append them to this list
- // it is recommended that the respec.css stylesheet be kept
- // extraCSS: [],
-
- issueBase: "https://github.com/json-ld/json-ld.org/issues/",
-
- // editors, add as many as you like
- // only "name" is required
- editors: [
- { name: "Manu Sporny", url: "http://manu.sporny.org/",
- company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/" },
- { name: "Gregg Kellogg", url: "http://greggkellogg.net/",
- company: "Kellogg Associates", companyURL: "http://kellogg-assoc.com/" },
- { name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
- company: "Graz University of Technology", companyURL: "http://www.tugraz.at/" }
- ],
-
- // authors, add as many as you like.
- // This is optional, uncomment if you have authors as well as editors.
- // only "name" is required. Same format as editors.
-
- authors: [
- { name: "Dave Longley", url: "http://digitalbazaar.com/",
- company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/"},
- { name: "Manu Sporny", url: "http://digitalbazaar.com/",
- company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/" },
- { name: "Gregg Kellogg", url: "http://greggkellogg.net/",
- company: "Kellogg Associates", companyURL: "http://kellogg-assoc.com/" },
- { name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
- company: "Graz University of Technology", companyURL: "http://www.tugraz.at/" }
- ],
-
- // name of the WG
- wg: "RDF Working Group",
-
- // URI of the public WG page
- wgURI: "http://www.w3.org/2011/rdf-wg/",
-
- // name (with the @w3c.org) of the public mailing to which comments are due
- wgPublicList: "public-rdf-comments",
-
- // URI of the patent status for this WG, for Rec-track documents
- // !!!! IMPORTANT !!!!
- // This is important for Rec-track documents, do not copy a patent URI from a random
- // document unless you know what you're doing. If in doubt ask your friendly neighbourhood
- // Team Contact.
- wgPatentURI: "http://www.w3.org/2004/01/pp-impl/46168/status",
- maxTocLevel: 4,
- preProcess: [ preProc ],
- alternateFormats: [ {uri: "diff-20120626.html", label: "diff to previous version"} ],
- };
-
- function _esc(s) {
- s = s.replace(/&/g,'&');
- s = s.replace(/>/g,'>');
- s = s.replace(/"/g,'"');
- s = s.replace(/</g,'<');
- return s;
- }
-
- function updateExample(doc, content) {
- // perform transformations to make it render and prettier
- content = content.replace(/<!--/, '');
- content = content.replace(/-->/, '');
- content = _esc(content);
- content = content.replace(/\*\*\*\*([^*]*)\*\*\*\*/g, '<span class="diff">$1</span>') ;
- return content ;
- }
-//]]>
- </script>
-<style type="text/css">
-.diff { font-weight:bold; color:#0a3; }
-</style>
-</head>
-
-<body>
-<section id="abstract">
-<p>
-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.
-</p>
-</section>
-
-<section id='sotd'>
-<p>This document has been under development for over 18 months in the
-JSON for Linking Data Community Group. The document has recently been
-transferred to the RDF Working Group for review, improvement, and publication
-along the Recommendation track. While this is a First Public Working Draft
-publication, the specification has undergone significant development, review,
-and changes during the course of the last 18 months and is more mature than
-the First Public Working Draft status implies.
-</p>
-<p>
-There are currently
-<a href="http://json-ld.org/#impl">five interoperable implementations</a>
-of this specification. There is
-a <a href="https://github.com/json-ld/json-ld.org/tree/master/test-suite">fairly complete test suite</a>
-and a
-<a href="http://json-ld.org/playground/">live JSON-LD editor</a>
-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.
-</p>
-<p class="issue">
-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.
-</p>
-</section>
-
-<section>
-<h2>Preface</h2>
-
-<p>
-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:
-</p>
-
-<ul>
- <li>Web authors and developers that want a very detailed view of how
- a JSON-LD processor and the API operates.</li>
- <li>Software developers that want to implement processors and APIs for
- JSON-LD.</li>
-</ul>
-
-<p>
-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]].</p>
-
-<section>
- <h2>Contributing</h2>
-
- <p>There are a number of ways that one may participate in the development of
- this specification:</p>
-
- <ul>
- <li>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:
- <a href="http://lists.w3.org/Archives/Public/public-rdf-comments/">public-rdf-comments@w3.org</a></li>
-
- <li>Ad-hoc technical discussion primarily occurs on the public community mailing list:
- <a href="http://lists.w3.org/Archives/Public/public-linked-json/">public-linked-json@w3.org</a></li>
-
- <li><a href="http://json-ld.org/minutes/">Public JSON-LD Community Group teleconferences</a>
- are held on Tuesdays at 1500UTC every week.</li>
-
- <li>RDF Working Group teleconferences are held on Wednesdays at 1500UTC
- every week. Participation is limited to RDF Working Group members.</li>
-
- <li>Specification bugs and issues should be reported in the
- <a href="https://github.com/json-ld/json-ld.org/issues">issue tracker</a>
- if you do not want to send an e-mail to the public-rdf-comments mailing
- list.</li>
-
- <li><a href="https://github.com/json-ld/json-ld.org/tree/master/spec">Source code</a>
- for the specification can be found on Github.</li>
-
- <li>The <a href="http://webchat.freenode.net/?channels=json-ld">#json-ld</a>
- IRC channel is available for real-time discussion on irc.freenode.net.</li>
- </ul>
-
-</section>
-
-</section>
-
-<section>
-<h1>Introduction</h1>
-
-<p>
-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.
-</p>
-
-<p>
-There are three major types of transformation that are discussed in this
-document; compaction, expansion, and RDF conversion.
-</p>
-
-<section>
- <h2>Expansion</h2>
- <p>
-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 <tref>term</tref>s and is fairly
-compact:
- </p>
-
- <pre class="example" data-transform="updateExample">
-var input1 = {
- "@context": "http://json-ld.org/contexts/person.jsonld"
- "name": "Manu Sporny",
- "homepage": "http://manu.sporny.org/"
-}
- </pre>
-
- <p>
-The next input example uses one <tref>IRI</tref> to express a property, but
-leaves the rest of the information untouched.
- </p>
-
- <pre class="example" data-transform="updateExample">
-var input2 = {
- "@context": "http://json-ld.org/contexts/person.jsonld"
- "****http://xmlns.com/foaf/0.1/name****": "Manu Sporny",
- "homepage": "http://manu.sporny.org/"
-}
- </pre>
-
- <p>
-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.
-<tdef>Expansion</tdef> performs two important operations. The first is to
-expand all values that are <tref>IRI</tref>s to their fully expanded form.
-The second is to express all values in <tdef>expanded form</tdef>. To
-transform both inputs above to the same representation, the developer could
-do the following:
- </p>
-
- <pre class="example" data-transform="updateExample">
-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);
- </pre>
-
- <p>
-The output for both calls above will be:
- </p>
-
- <pre class="example" data-transform="updateExample">
-[{
- "http://xmlns.com/foaf/0.1/name": [{
- "@value": "Manu Sporny"
- }],
- "http://xmlns.com/foaf/0.1/homepage": [{
- "@id": "http://manu.sporny.org/"
- }]
-}]
- </pre>
-
- <p>
-Note that in the example above; all <tref>context</tref> definitions have
-been removed, all <tref>term</tref> and prefixes have been expanded to full
-IRIs, and all <tref>literal</tref>s are expressed in <tref>expanded form</tref>.
-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.
- </p>
-</section>
-
-<section>
- <h2>Compaction</h2>
- <p>
-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
-read by software developers. Compaction uses a developer-supplied
-<tref>context</tref> to compresses all <tref>IRI</tref>s to <tref>term</tref>s
-or <tref>prefix</tref>es, and compacts all <tref>literal</tref>s expressed
-in <tref>expanded form</tref> as much as possible.
- </p>
-
- <p>
-The following example expresses input that has already been fully expanded:
- </p>
-
- <pre class="example" data-transform="updateExample">
-var expandedInput = [{
- "http://xmlns.com/foaf/0.1/name": [{
- "@value": "Manu Sporny"
- }],
- "http://xmlns.com/foaf/0.1/homepage": [{
- "@id": "http://manu.sporny.org/"
- }]
-}]
- </pre>
-
- <p>
-A developer that wants to transform the data above into a more human-readable
-form, could do the following using the JSON-LD API:
- </p>
-
- <pre class="example" data-transform="updateExample">
-function compactionCallback(output) {
- console.log(output);
-}
-
-jsonld.compact(expandedInput, "http://json-ld.org/contexts/person.jsonld", compactionCallback);
- </pre>
-
- <p>
-The following would be the result of the call above:
- </p>
-
- <pre class="example" data-transform="updateExample">
-{
- "@context": "http://json-ld.org/contexts/person.jsonld"
- "name": "Manu Sporny",
- "homepage": "http://manu.sporny.org/"
-}
- </pre>
-
- <p>
-Note that all of the <tref>term</tref>s have been compressed and
-the <tref>context</tref> 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.
- </p>
-
-</section>
-
-<section>
- <h3>Conversion to and from RDF</h3>
- <p>
-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:
- </p>
-
- <pre class="example" data-transform="updateExample">
-<!--
-var data = "
-<http://manu.sporny.org/about/#manu> <http://xmlns.com/foaf/0.1/name> \"Manu Sporny\" .\n
-<http://manu.sporny.org/about/#manu> <http://xmlns.com/foaf/0.1/homepage> <http://manu.sporny.org/> .";
--->
- </pre>
-
- <p>
-A developer can use the JSON-LD API to transform the markup above into a
-JSON-LD document:
- </p>
-
- <pre class="example" data-transform="updateExample">
-function conversionCallback(result)
-{
- console.log("JSON-LD Document: ", result);
-};
-
-jsonld.fromRDF(data, conversionCallback, {"format": "ntriples"});
- </pre>
-
- <p>
-The following expanded output would be the result of the call above:
- </p>
-
- <pre class="example" data-transform="updateExample">
-[{
- "@id": "http://manu.sporny.org/about/#manu",
- "http://xmlns.com/foaf/0.1/name": [{
- "@value": "Manu Sporny"
- }],
- "http://xmlns.com/foaf/0.1/homepage": [{
- "@id": "http://manu.sporny.org/"
- }]
-}]
- </pre>
-
- <p>
-Note that the output above, could easily be compacted to produce the following
-using the technique outlined in the previous section:
- </p>
-
- <pre class="example" data-transform="updateExample">
-{
- "@context": "http://json-ld.org/contexts/person.jsonld",
- "@id": "http://manu.sporny.org/about/#manu",
- "name": "Manu Sporny",
- "homepage": "http://manu.sporny.org/"
-}
- </pre>
-
- <p>
-Transforming the object above back to RDF is as simple as calling the
-<code>toRDF()</code> method:
- </p>
-
- <pre class="example" data-transform="updateExample">
-var jsonldDocument = ...; // assign the JSON-LD document here
-
-function rdfCallback(quads)
-{
- console.log("RDF Data: ", quads);
-};
-
-jsonld.toRDF(jsonldDocument, rdfCallback);
- </pre>
-
-</section>
-
-<section>
- <h3>Framing and Normalization</h3>
- <p class="issue">
-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 <tref>linked data graph</tref>s.
-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.
- </p>
-</section>
-
-</section>
-
-<section>
- <h2>The Application Programming Interface</h2>
-
- <p>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.
- </p>
-
-<section>
- <h3>General Terminology</h3>
-
- <p class="issue">
-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.
- </p>
-
- <p>
-The following is an explanation of the general terminology used in this
-document:
- </p>
-
- <dl>
- <dt><tdef>JSON object</tdef></dt><dd>
- An object structure is represented as a pair of curly brackets surrounding zero or
- more name-value pairs. A name is a <tref>string</tref>. 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.
- </dd>
- <dt><tdef>array</tdef></dt>
- <dd>
- An array is represented as square brackets surrounding zero or more
- values that are separated by commas.
- </dd>
- <dt><tdef>string</tdef></dt><dd>
- 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.
- </dd>
- <dt><tdef>number</tdef></dt>
- <dd>
- 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.</dd>
- <dt><tdef>true</tdef> and <tdef>false</tdef></dt><dd>
- Values that are used to express one of two possible boolean states.
- </dd>
- <dt><tdef>null</tdef></dt><dd>
- 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 <em>null</em>. If <code>@value</code>,
- <code>@list</code>, or <code>@set</code> is set to <em>null</em> in
- expanded form, then the entire JSON object is ignored. If
- <code>@context</code> is set to <em>null</em>, the
- <tref>active context</tref> is reset and when used
- within a <tref>context</tref>, it removes any definition associated
- with the key, unless otherwise specified.
- </dd>
- <dt><tdef>subject definition</tdef></dt><dd>
- A <tref>JSON object</tref> used to represent a <tref>subject</tref> and
- one or more properties of that subject. A <tref>JSON object</tref> is a
- subject definition if it does not contain they keys <code>@value</code>,
- <code>@list</code> or <code>@set</code> and it has one or more keys
- other than <code>@id</code>.</dd>
- <dt><tdef>subject reference</tdef></dt><dd>
- A <tref>JSON object</tref> used to reference a subject having only the
- <code>@id</code> key.</dd>
- <dt><tdef>Linked Data</tdef></dt>
- <dd>A set of documents, each containing a representation of a
- <tref>linked data graph</tref>.</dd>
- <dt><tdef>linked data graph</tdef> or <tdef>dataset</tdef></dt>
- <dd>An unordered labeled directed graph, where <tref>node</tref>s are
- <tref>subject</tref>s or <tref>object</tref>s, and edges are
- properties.</dd>
- <dt><tdef>node</tdef></dt>
- <dd>A piece of information that is represented in a
- <tref>linked data graph</tref>.</dd>
- <dt><tdef>named graph</tdef></dt>
- <dd>A <tref>linked data graph</tref> that has one or more
- <tref>IRI</tref> that are used to refer to it.</dd>
- <dt><tdef>graph name</tdef></dt>
- <dd>An <tref>IRI</tref> that is a reference to a
- <tref>named graph</tref>.</dd>
- <dt><tdef>default graph</tdef></dt>
- <dd>When executing an algorithm, the graph where data should be placed
- if a <tref>named graph</tref> is not specified.</dd>
- <dt><tdef>subject</tdef></dt>
- <dd>Any node in a <tref>linked data graph</tref> with at least one
- outgoing edge.</dd>
- <dt><tdef><abbr title="Internationalized Resource Identifier">IRI</abbr></tdef></dt>
- <dd>An Internationalized Resource Identifier as described in [[!RFC3987]].</dd>
- <dt><tdef>object</tdef></dt>
- <dd>A node in a <tref>linked data graph</tref> with at least one
- incoming edge.</dd>
- <dt><tdef>property</tdef></dt>
- <dd>An edge of the <tref>linked data graph</tref>.</dd>
- <dt><tdef>literal</tdef></dt>
- <dd>An <tref>object</tref> with a label that is not an
- <tref>IRI</tref>.</dd>
- <dt><tdef>quad</tdef></dt>
- <dd>A piece of information that contains four items; a
- <tref>subject</tref>, a <tref>property</tref>, a <tref>object</tref>,
- and a <tref>graph name</tref>.</dd>
- <dt><tdef>context</tdef></dt>
- <dd>A <tref>JSON object</tref> that contains rules for interpreting a
- JSON-LD document.</dd>
- <dt><tdef>keyword</tdef></dt>
- <dd>A JSON key that is specific to JSON-LD, specified in the JSON-LD
- Syntax specification [[!JSON-LD]] in the section titled
- <a href="http://sites.local/json-ld.org/spec/latest/json-ld-syntax/#syntax-tokens-and-keywords">Syntax Tokens and Keywords</a>.</dd>
- </dl>
- </section>
-
- <section>
- <h3>JsonLdProcessor</h3>
-
- <p>The JSON-LD processor interface is the high-level programming structure that developers
- use to access the JSON-LD transformation methods.</p>
-
- <p class="note">The JSON-LD API signatures are the same across all programming languages. Due
- to the fact that asynchronous programming is uncommon in certain languages, developers MAY
- implement processor with a synchronous interface instead. In that case, the <code>callback</code>
- parameter MUST NOT be included and the result MUST be returned as return value instead.</p>
-
- <dl title="[NoInterfaceObject] interface JsonLdProcessor" class="idl">
-
- <dt>void expand()</dt>
- <dd>
- <a href="#expansion">Expands</a> the given <code>input</code> according to
- the steps in the <a href="#expansion-algorithm">Expansion Algorithm</a>. The
- <code>input</code> MUST be copied, expanded and returned if there are
- no errors. If the expansion fails, an appropriate exception MUST be thrown.
-
- <dl class="parameters">
- <dt>object or object[] or IRI input</dt>
- <dd>The JSON-LD object or array of JSON-LD objects to perform the expansion upon or an
- <tref>IRI</tref> referencing the JSON-LD document to expand.</dd>
- <dt>object or IRI? context</dt>
- <dd>An optional external context to use additionally to the context embedded in
- <code>input</code> when expanding the <code>input</code>.</dd>
- <dt>JsonLdCallback callback</dt>
- <dd>A callback that is called when processing is complete on
- the given <code>input</code>.</dd>
- <dt>optional JsonLdOptions options</dt>
- <dd>A set of options that MAY affect the expansion algorithm such as, e.g., the
- input document's base <tref>IRI</tref>.</dd>
- </dl>
-
- <dl class="exception" title="InvalidContext">
- <dt>INVALID_SYNTAX</dt>
- <dd>A general syntax error was detected in the <code>@context</code>.
- For example, if a <code>@type</code> key maps to anything other than
- <code>@id</code> or an <tref>absolute IRI</tref>, this exception would be raised.</dd>
- <dt>LOAD_ERROR</dt>
- <dd>There was a problem encountered loading a remote context.</dd>
- </dl>
-
- <dl class="exception" title="ProcessingError">
- <dt>LIST_OF_LISTS_DETECTED</dt>
- <dd>A list of lists was detected. This is not supported in this
- version of JSON-LD.</dd>
- </dl>
- </dd>
-
- <dt>void compact()</dt>
- <dd>
- <a href="#compaction">Compacts</a> the given <code>input</code> using the
- <code>context</code> according to the steps in the
- <a href="#compaction-algorithm">Compaction Algorithm</a>. The
- <code>input</code> MUST be copied, compacted and returned if there are
- no errors. If the compaction fails, an appropriate exception MUST be
- thrown.
-
- <dl class="parameters">
- <dt>object or object[] or IRI input</dt>
- <dd>The JSON-LD object or array of JSON-LD objects to perform the compaction upon or an
- <tref>IRI</tref> referencing the JSON-LD document to compact.</dd>
- <dt>object or IRI context</dt>
- <dd>The context to use when compacting the <code>input</code>; either in the
- form of an <tref>JSON object</tref> or as <tref>IRI</tref>.</dd>
- <dt>JsonLdCallback callback</dt>
- <dd>A callback that is called when processing is complete on
- the given <code>input</code>.</dd>
- <dt>optional JsonLdOptions options</dt>
- <dd>A set of options that MAY affect the expansion algorithm such as, e.g., the
- input document's base <tref>IRI</tref>. This also includes <code>optimize</code>,
- which if set will cause processor-specific optimization.</dd>
- </dl>
-
- <dl class="exception" title="InvalidContext">
- <dt>INVALID_SYNTAX</dt>
- <dd>A general syntax error was detected in the <code>@context</code>.
- For example, if a <code>@type</code> key maps to anything other than
- <code>@id</code> or an <tref>absolute IRI</tref>, this exception would be raised.</dd>
- <dt>LOAD_ERROR</dt>
- <dd>There was a problem encountered loading a remote context.</dd>
- </dl>
-
- <dl class="exception" title="ProcessingError">
- <dt>LOSSY_COMPACTION</dt>
- <dd>The compaction would lead to a loss of information, such as a
- <code>@language</code> value.</dd>
- <dt>CONFLICTING_DATATYPES</dt>
- <dd>The target datatype specified in the coercion rule and the
- datatype for the typed literal do not match.</dd>
- <dt>LIST_OF_LISTS_DETECTED</dt>
- <dd>A list of lists was detected. This is not supported in this
- version of JSON-LD.</dd>
- </dl>
- </dd>
-
- <dt>void fromRDF()</dt>
- <dd>Creates a JSON-LD document given an set of <ldtref title="quad">Quads</ldtref>.
- <dl class="parameters">
- <dt>Quad[] input</dt>
- <dd>A <tref>dataset</tref> represented as an array of <ldtref title="quad">Quads</ldtref>.</dd>
- <dt>JsonLdCallback callback</dt>
- <dd>A callback that is called when processing is complete on
- the given <code>input</code>.</dd>
- <dt>optional JsonLdOptions options</dt>
- <dd>A set of options that will affect the algorithm. This includes <code>notType</code>,
- which if set to <tref>true</tref> causes the resulting document to use <code>rdf:type</code>
- as a property, instead of <code>@type</code>.</dd>
- </dl>
- </dd>
-
- <dt>void toRDF()</dt>
- <dd>
- Processes the <code>input</code> according to the
- <a href="#convert-to-rdf-algorithm">Convert to RDF Algorithm</a>, calling
- the provided <code>callback</code> for each <ldtref>Quad</ldtref> generated.
- <dl class="parameters">
- <dt>object or object[] or IRI input</dt>
- <dd>The JSON-LD object or array of JSON-LD objects to convert to RDF or a <a>IRI</a>
- referencing the JSON-LD document to convert to RDF.</dd>
- <dt>QuadCallback callback</dt>
- <dd>A callback that is called when a <ldtref>Quad</ldtref> is created from processing
- the given <code>input</code>.
- </dd>
- <dt>optional JsonLdOptions options</dt>
- <dd>A set of options that MAY affect the conversion to RDF such as, e.g.,
- the input document's base <tref>IRI</tref>.</dd>
- </dl>
-
- <dl class="exception" title="InvalidContext">
- <dt>INVALID_SYNTAX</dt>
- <dd>A general syntax error was detected in the <code>@context</code>.
- For example, if a <code>@type</code> key maps to anything other than
- <code>@id</code> or an <tref>absolute IRI</tref>, this exception would be raised.</dd>
- <dt>LOAD_ERROR</dt>
- <dd>There was a problem encountered loading a remote context.</dd>
- </dl>
-
- <dl class="exception" title="ProcessingError">
- <dt>LIST_OF_LISTS_DETECTED</dt>
- <dd>A list of lists was detected. This is not supported in this
- version of JSON-LD.</dd>
- </dl>
-
- </dd>
-
- </dl>
-
- </section>
-
- <section>
- <h3>Callbacks</h3>
- <section>
- <h3>JsonLdCallback</h3>
- <p>The <a>JsonLdCallback</a> is used to return a processed JSON-LD representation
- as the result of processing an API method.</p>
-
- <dl title="[NoInterfaceObject Callback] interface JsonLdCallback"
- class="idl">
-
- <dt>void jsonLd()</dt>
- <dd>This callback is invoked when processing is complete.
- <dl class="parameters">
- <dt>object or object[] jsonld</dt>
- <dd>The processed JSON-LD document.</dd>
- </dl>
- </dd>
- </dl>
- </section>
- <section>
- <h3>QuadCallback</h3>
- <p>The <a>QuadCallback</a> is called whenever the processor generates a
- quad during the <code>quad()</code> call.</p>
-
- <dl title="[NoInterfaceObject Callback] interface QuadCallback"
- class="idl">
-
- <dt>void quad()</dt>
- <dd>This callback is invoked whenever a quad is generated by the processor.
- <dl class="parameters">
- <dt>Quad quad</dt>
- <dd>The quad.</dd>
- </dl>
- </dd>
- </dl>
- </section>
- </section>
-
- <section>
- <h3>Data Structures</h3>
- <p>This section describes datatype definitions used within the JSON-LD API.</p>
-
- <section>
- <h3>IRI</h3>
- <p>The <a>IRI</a> datatype is a string representation of an <tref>IRI</tref>.</p>
- <div title="typedef DOMString IRI" class="idl">
- This datatype indicates that the <em>string</em> is interpreted as an Internationalized
- Resource Identifier [[!RFC3987]] identifying a document, which when parsed as JSON yields
- either a <tref>JSON object</tref> or <tref>array</tref>.
- </div>
- </section>
-
- <section>
- <h3>JsonLdOptions</h3>
- <p>The <a>JsonLdOptions</a> type is used to pass various options to the <a>JsonLdProcessor</a> methods.</p>
- <dl title="dictionary JsonLdOptions" class="idl">
- <dt>IRI? base</dt>
- <dd>The Base IRI to use when expanding the document. This overrides the value of
- <em>input</em> if it is a <a>IRI</a>. If not specified and <em>input</em> is not
- an <a>IRI</a>, the base IRI defaults to the current document IRI if in a browser context,
- or the empty string if there is no document context.</dd>
- <dt>boolean optimize = false</dt>
- <dd>If set to <code>true</code>, the JSON-LD processor is allowed to
- optimize the output of the <a href="#compaction-algorithm">Compaction Algorithm</a>
- 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.<br>
- The default value is <code>false</code>.</dd>
- <dt>boolean noType = false</dt>
- <dd>If set to <code>true</code>, the JSON-LD processor will not use the
- <code>@type</code> property when generating the output, and will use the
- expanded <code>rdf:type</code> IRI as the property instead of <code>@type</code>.<br>
- The default value is <code>false</code>.</dd>
- </dl>
- </section>
-
- <p>The following data structures are used for representing data about
- RDF quads. They are used for normalization, <a>fromRDF</a>,
- and from <a>toRDF</a> interfaces.
- </p>
-
- <section>
- <h3>Quad</h3>
- <p>The <a>Quad</a> interface represents an RDF Quad.
- See [[!RDF-CONCEPTS]] definition for
- <cite><a href="http://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple">RDF triple</a></cite>,
- which most closely aligns to <a>Quad</a>.
- </p>
- <dl title="[NoInterfaceObject] interface Quad" class="idl">
- <dt>readonly attribute Node subject</dt>
- <dd>The <tref>subject</tref> associated with the <a>Quad</a>.</dd>
- <dt>readonly attribute Node predicate</dt>
- <dd>The predicate associated with the <a>Quad</a>.
- Within JSON-LD, an <tdef>RDF predicate</tdef> is refered to as a
- <tref>property</tref></dd>
- <dt>readonly attribute Node object</dt>
- <dd>The <tref>object</tref> associated with the <a>Quad</a>.</dd>
- <dt>readonly attribute Node? graphName</dt>
- <dd>If present, the name associated with the <a>Quad</a> identifying
- it as a member of a <tref>named graph</tref>. If it is missing, the quad
- is a member of the <tref>default graph</tref>.
- <div class="issue" data-number="125">This element is at risk, and may be removed.</div>
- </dd>
- </dl>
- </section>
-
- <section>
- <h3>Node</h3>
- <p><ldtref>Node</ldtref> is the base class of <ldtref>IRI</ldtref>,
- <ldtref>BlankNode</ldtref>, and <ldtref>Literal</ldtref>. It is the IDL
- representation of a <tref>linked data graph</tref> <tref>node</tref>.</p>
- <dl title="[NoInterfaceObject] interface Node" class="idl">
- </dl>
- </section>
-
- <section>
- <h3>IRI</h3>
- <p>A <tref>node</tref> that is an <tref>IRI</tref>.</p>
- <dl title="[NoInterfaceObject] interface IRI : Node"
- class="idl">
- <dt>readonly attribute DOMString value</dt>
- <dd>The IRI identifier of the <tref>node</tref> as a [[UNICODE]] string.</dd>
- </dl>
- </section>
-
- <section>
- <h3><tdef>Blank Node</tdef></h3>
-
- <p>A <tref>node</tref> in the <tref>linked data graph</tref> 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 <tref>linked data graph</tref>.
- A blank node is assigned an identifier starting
- with the prefix <code>_:</code> and an implementation dependent,
- auto-generated suffix that is unique to all information associated with the
- particular blank node.
- </p>
-
- <dl title="[NoInterfaceObject] interface BlankNode : Node" class="idl">
- <dt>readonly attribute DOMString identifier</dt>
- <dd>The temporary identifier of the <tref>blank node</tref>.
- The <code>identifier</code> MUST NOT be relied upon in any way between two
- separate processing runs of the same document or with a different document.</dd>
- </dl>
-
- <p class="note">Developers and authors must not assume that the
- value of a <tref>blank node</tref> will remain the same between two
- processing runs. <a>BlankNode</a> values are only valid for the
- most recent processing run on the document. <a>BlankNode</a>
- values will often be generated differently by different processors.</p>
-
- <p class="note">Implementers MUST ensure that <a>BlankNode</a> values are unique
- within the current environment, two <ldtref
- title="blanknode">BlankNodes</ldtref> are considered equal if, and only
- if, their values are strictly equal.</p>
- </section>
-
- <section>
- <h3>Literal</h3>
- <p>Literals represent values such as numbers, dates and strings in
- RDF data. A <ldtref>Literal</ldtref> is comprised of three attributes:
- </p>
-
- <ul>
- <li>a lexical form of the <code>value</code></li>
- <li>an optional <code>language</code> tag</li>
- <li>a <code>datatype</code> specified by an <ldtref>IRI</ldtref></li>
- </ul>
-
- <p>Literals representing plain text in a natural language may have a
- <code>language</code> tag specified by a string token, as specified in
- [[!BCP47]], normalized to lowercase
- (e.g., <code>'en'</code>, <code>'fr'</code>, <code>'en-gb'</code>).
- They also have a datatype attribute such as <code>xsd:string</code>.
- If unspecified, the <code>datatype</code> defaults to <code>xsd:string</code>.
- </p>
-
- <p>Literals representing values with a specific datatype, such as
- the integer 72, may have a <code>datatype</code> attribute specified in the form
- of a <a>IRI</a> (e.g.,
- <code>xsd:integer</code>).</p>
-
- <p> See[[!RDF-CONCEPTS]] definition for
- <cite><a href="http://www.w3.org/TR/rdf11-concepts/#dfn-literal">literal</a></cite>.</p>
-
- <dl title="[NoInterfaceObject] interface Literal : Node" class="idl">
- <dt>readonly attribute DOMString value</dt>
- <dd>The lexical form of the Literal's value.</dd>
- <dt>readonly attribute DOMString? language</dt>
- <dd>An optional language tag as defined in [[!BCP47]], normalized to lowercase.</dd>
- <dt>readonly attribute IRI? datatype</dt>
- <dd>An optional datatype identified by a IRI.</dd>
- </dl>
- </section>
- </section>
-
-</section>
-
-<section>
-<h1>Algorithms</h1>
-
-<p>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.</p>
-
-<section>
- <h2>Algorithm Terms</h2>
- <dl>
- <dt><tdef>active subject</tdef></dt>
- <dd>
- the currently active subject that the processor should use when
- processing.
- </dd>
- <dt><tdef>active property</tdef></dt>
- <dd>
- 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 <tref>active context</tref>.
- </dd>
- <dt><tdef>active object</tdef></dt>
- <dd>
- the currently active object that the processor should use when
- processing.
- </dd>
- <dt><tdef>active context</tdef></dt>
- <dd>
- a context that is used to resolve <tref>term</tref>s while the processing
- algorithm is running. The <tref>active context</tref> is the context
- contained within the <tref>processor state</tref>.
- </dd>
- <dt><tdef>compact IRI</tdef></dt>
- <dd>
- a compact IRI is has the form of <tref>prefix</tref> and <em>suffix</em> and is used as a way
- of expressing an IRI without needing to define separate <tref>term</tref> definitions for
- each IRI contained within a common vocabulary identified by <tref>prefix</tref>.
- </dd>
- <dt><tdef>local context</tdef></dt>
- <dd>
- a context that is specified within a <tref>JSON object</tref>,
- specified via the <code>@context</code> <tref>keyword</tref>.
- </dd>
- <dt><tdef>processor state</tdef></dt>
- <dd>
- the <tref>processor state</tref>, which includes the <tref>active
- context</tref>, <tref>active subject</tref>, and
- <tref>active property</tref>. The <tref>processor state</tref> is managed
- as a stack with elements from the previous <tref>processor state</tref>
- copied into a new <tref>processor state</tref> when entering a new
- <tref>JSON object</tref>.
- </dd>
- <dt><tdef>JSON-LD input</tdef></dt>
- <dd>
- The JSON-LD data structure that is provided as input to the algorithm.
- </dd>
- <dt><tdef>JSON-LD output</tdef></dt>
- <dd>
- The JSON-LD data structure that is produced as output by the algorithm.
- </dd>
- <dt><tdef>term</tdef></dt><dd>
- A <tref>term</tref> is a short word defined in a context that MAY be expanded to an <tref>IRI</tref>
- </dd>
- <dt><tdef>prefix</tdef></dt><dd>
- A <tref>prefix</tref> is a <tref>term</tref> that expands to a vocabulary base IRI. It
- is typically used along with a <em>suffix</em> to form a <tref>compact IRI</tref> to create an IRI
- within a vocabulary.
- </dd>
- <dt><tdef>language-tagged literal</tdef></dt><dd>
- A <tref>language-tagged literal</tref> is a <tref>literal</tref> without a datatype, including
- a language.
- See <cite><a href="http://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-literal">languaged-tagged literal</a></cite> in [[!RDF-CONCEPTS]].
- </dd>
- <dt><tdef>typed literal</tdef></dt><dd>
- A <tref>typed literal</tref> is a <tref>literal</tref> with an associated <tref>IRI</tref>
- which indicates the literal's datatype.
- See <cite><a href="http://www.w3.org/TR/rdf11-concepts/#dfn-typed-literal">languaged-tagged literal</a></cite> in [[!RDF-CONCEPTS]].
- </dd>
- </dl>
-</section>
-
-<section>
- <h2 id="context">Context Processing</h2>
- <p>Processing of JSON-LD data structure is managed recursively.
- During processing, each rule is applied using information provided by the <tref>active context</tref>.
- Processing begins by pushing a new <tref>processor state</tref> onto the <tref>processor state</tref> stack.
- If a <tref>local context</tref> is encountered, information from the <tref>local context</tref> is merged
- into the <tref>active context</tref>.</p>
- <p>The <tref>active context</tref> is used for expanding properties and values of a <tref>JSON object</tref> (or elements
- of an array) using a <tdef>term mapping</tdef>. It is also used to maintain
- <tdef>coercion mapping</tdef>s from terms to datatypes, <tdef>language mapping</tdef>s from terms to language codes,
- and <tdef>list mapping</tdef>s and <tdef>set mapping</tdef>s 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.</p>
- <p>A <tref>local context</tref> is identified within a <tref>JSON object</tref> having a <code>@context</code>
- property with a <tref>string</tref>, <tref>array</tref> or a <tref>JSON object</tref> value.
- When processing a <tref>local context</tref>, special processing rules apply:</p>
- <ol class="algorithm">
- <li>Create a new, empty <tref>local context</tref>.</li>
- <li>Let <em>context</em> be the value of <code>@context</code>
- <ol class="algorithm">
- <li id="process-context">If <em>context</em> equals <tref>null</tref>, clear the <tref>active context</tref>.</li>
- <li>If <em>context</em> is an <tref>array</tref>, process each element as <em>context</em> in order
- by starting at <a href="#process-context">Step 2.1</a>.</li>
- <li>If <em>context</em> is a <tref>string</tref>, it MUST have a lexical form of <tref>absolute IRI</tref>.
- <ol class="algorithm">
- <li>Dereference <em>context</em>.</li>
- <li>If the resulting document is a JSON document, extract the top-level <code>@context</code>
- element using the JSON Pointer "/@context" as described in [[!JSON-POINTER]]. Set <em>context</em>
- to the extracted content and process it by starting at <a href="#process-context">Step 2.1</a>.</li>
- </ol>
- </li>
- <li>If <em>context</em> is a <tref>JSON object</tref>, perform the following steps:
- <ol class="algorithm">
- <li>If <em>context</em> has a <code>@language</code> property, it MUST have a value of a
- simple <tref>string</tref> with the lexical form described in [[!BCP47]], or <tref>null</tref>. Add the language to the <tref>local context</tref>.</li>
- <li>If <em>value</em> has a <code>@vocab</code> key, it MUST have a value of a simple <tref>string</tref>
- with the lexical form of an <tref>absolute IRI</tref>, or <tref>null</tref>. Add the vocabulary mapping to the <tref>local context</tref>.</li>
- <li id="object-context">Otherwise, for each property in <em>context</em> perform the following steps:
- <ol class="algorithm">
- <li>If the property's value is a simple <tref>string</tref>, determine the IRI mapping value by
- performing <a href="#iri-expansion">IRI Expansion</a> on the associated value. If the result of the IRI
- mapping is an <tref>absolute IRI</tref>, merge the property into the <tref>local context</tref>
- <tref>term mapping</tref>, unless the property is a JSON-LD <tref>keyword</tref>, in which
- case throw an exception.</li>
- <li>Otherwise, if the property's value is <tref>null</tref> remove mapping, coercion,
- container and language information associated with property from the
- <tref>local context</tref>.</li>
- <li>Otherwise, the <em>property</em>'s <em>value</em> MUST be a <tref>JSON object</tref>.
- <ol class="algorithm">
- <li>If the <em>property</em> is a JSON-LD <tref>keyword</tref> and the value has
- <code>@id</code>, <code>@language</code> or <code>@type</code> properties, throw an exception.
- <div class="issue">Undecided if <code>@type</code> or <code>@graph</code> can take a
- <code>@container</code> with <code>@set</code>.
- </div>
- </li>
- <li>If the <em>property</em> has the form of <tref>term</tref>, its <em>value</em> MUST have an
- <code>@id</code> property with a string value which MUST have the form of a <tref>term</tref>,
- <tref>compact IRI</tref>, or <tref>absolute IRI</tref>. Determine the IRI mapping
- by performing <a href="#iri-expansion">IRI Expansion</a> on the associated value.
- If the result of the IRI mapping is an <tref>absolute IRI</tref>, merge the
- <em>property</em> into the <tref>local context</tref> <tref>term mapping</tref>.</li>
- <li>If the <em>property</em> has the form of of a <tref>compact IRI</tref> or <tref>absolute IRI</tref>,
- the <em>value</em> MAY have a <code>@id</code> property with a string value which MUST have the
- form of a <tref>term</tref>, <tref>compact IRI</tref>, or absolute <tref>IRI</tref>.
- Determine the IRI mapping by performing <a href="#iri-expansion">IRI Expansion</a> on the associated
- value. If the result of the IRI mapping is an <tref>absolute IRI</tref>, merge the
- <em>property</em> into the <tref>local context</tref> <tref>term mapping</tref>.</li>
- <li>If the <em>value</em> has a <code>@type</code> property, its value MUST have the form of a <tref>term</tref>,
- <tref>compact IRI</tref>, <tref>absolute IRI</tref>, or the <tref>keyword</tref> <code>@id</code>.
- Determine the IRI by performing <a href="#iri-expansion">IRI Expansion</a> on the associated value.
- If the result of the IRI mapping is an <tref>absolute IRI</tref> or <code>@id</code>, merge into the
- <tref>local context</tref> <tref>coercion mapping</tref> using the lexical value of the <em>property</em>.</li>
- <li>If the <em>value</em> has a <code>@container</code> property, its value MUST be <code>@list</code> or
- <code>@set</code>. Merge the <tref>list mapping</tref> or <tref>set mapping</tref> into the
- <tref>local context</tref> using the lexical value of the <em>property</em>.</li>
- <li>If the <em>value</em> has a <code>@language</code> property but no <code>@type</code> property, the value of the
- <code>@language</code> property MUST be a <tref>string</tref> or <tref>null</tref>.
- Merge the <tref>language mapping</tref> into the <tref>local context</tref> using the lexical value of the
- <em>property</em>.</li>
- </ol>
- </li>
- <li>Merge the <tref>local context</tref> into the <tref>active context</tref>.</li>
- <li>Repeat <a href="#object-context">Step 2.4.2</a> until no entries are added to the <tref>local
- context</tref>.</li>
- </ol>
- </li>
- </ol>
- </li>
- </ol>
- </li>
- </ol>
-
- <p class="note">It can be difficult to distinguish between a <tref>compact IRI</tref> and an <tref>absolute IRI</tref>,
- as a <tref>compact IRI</tref> may seem to be a valid IRI <em>scheme</em>. 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 <a href="#object-context">Step 2.3.2</a> until no changes are made, mappings to IRIs created
- using an undefined term prefix will eventually resolve to <tref>absolute IRI</tref>s.</p>
-
- <p class="issue" data-number="43"><a href="https://github.com/json-ld/json-ld.org/issues/43">Issue 43</a>
- concerns performing IRI expansion in the key position of a context definition.</p>
-</section>
-
-<section>
- <h2>IRI Expansion</h2>
- <p>Keys and some values are evaluated to produce an <tref>IRI</tref>. This section defines an algorithm for
- transforming a value representing an IRI into an actual IRI.</p>
- <p><tref title="IRI">IRIs</tref> may be represented as an <tref>absolute IRI</tref>, a <tref>term</tref>,
- a <tref>compact IRI</tref>, or as a value relative to <code>@vocab</code>.</p>
- <p>An <tdef>absolute IRI</tdef> is defined in [[!RFC3987]] containing a <em>scheme</em> along with
- <em>path</em> and optional <em>query</em> and fragment segments. A <tdef>relative IRI</tdef> is an IRI
- that is relative some other <tref>absolute IRI</tref>; in the case of JSON-LD this is the base location
- of the document.</p>
-
- <p>The algorithm for generating an IRI is:
- <ol class="algorithm">
- <li>If the <tref>active context</tref> contains a <tref>term</tref> mapping for the value using
- a case-sensitive comparison, use the mapped value as an IRI.</li>
- <li>Otherwise, split the value into a <em>prefix</em> and <em>suffix</em> from the first occurrence of ':'.</li>
- <li>If the prefix is a '_' (underscore), the value represents a named <tref>blank node</tref>.</li>
- <li>If the <tref>active context</tref> contains a <tref>term</tref> mapping for <em>prefix</em> using
- a case-sensitive comparison, and <em>suffix</em> does not does not begin with '//'
- (i.e., it does not match a <em>hier-part</em> including
- <em>authority</em> (as defined in [[!RFC3986]]), generate an <tref>IRI</tref>
- 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.</li>
- <li>Otherwise, if the IRI being processed does not contain a colon and is a property, i.e., a key in
- a <tref>JSON object</tref>, or the value of <code>@type</code> and the active context has a
- <code>@vocab</code> mapping, join the mapped value to the suffix using textual concatenation.</li>
- <li>Otherwise, if the IRI being processed does not contain a colon and is not a property, i.e., not a key in a
- <tref>JSON object</tref> treat it as a <tref>relative IRI</tref> and resolve it against the base IRI as
- per [[RFC3986]] using only the basic algorithm in section 5.2. Neither <em>Syntax-Based Normalization</em>
- nor <em>Scheme-Based Normalization</em> (described in sections 6.2.2 and 6.2.3 of [[RFC3986]]) are performed.
- Characters additionally allowed in IRI references are treated in the same way that unreserved characters are
- treated in URI references, per section 6.5 of [[RFC3987]].</li>
- <li>Otherwise, use the value directly as an IRI.</li>
- </ol>
- </p>
-</section>
-
-<section>
- <h2>IRI Compaction</h2>
- <p>Some keys and values are expressed using <tref>IRI</tref>s. This section defines an
- algorithm for transforming an IRI (<em>iri</em>) to a <tref>term</tref> or <tref>compact IRI</tref> using the
- <tref>term</tref>s specified in the <tref>active context</tref> using an optional <em>value</em>.</p>
-
-<section>
- <h3>IRI Compaction Algorithm</h3>
- <p>The algorithm for generating a <tref>compact IRI</tref> is:
- <ol class="algorithm">
- <li>Create an empty list of terms <em>terms</em> that will be populated with
- <tref>term</tref>s that are ranked according to how closely they match
- <em>value</em>. Initialize <em>highest rank</em> to <code>0</code>,
- and set a flag <em>list container</em> to <code>false</code>.</li>
- <li>For each <em>term</em> in the <tref>active context</tref>:
- <ol class="algorithm">
- <li>If the <em>term</em>'s <tref>IRI</tref> is not a complete match against
- <em>iri</em>, continue to the next <em>term</em>.</li>
- <li>If <em>value</em> is a <tref>JSON object</tref> containing only the property <code>@list</code>:
- <ol class="algorithm">
- <li>If <em>term</em> has a <code>@container</code> set to <code>@set</code>, continue
- to the next <em>term</em>.</li>
- <li>If <em>list container</em> is <code>true</code> and <em>term</em> does not have a
- <code>container</code> set to <code>@list</code> and <em>value</em> is <tref>null</tref>,
- continue to the next <em>term</em>.</li>
- </ol>
- </li>
- <li>Otherwise, if <em>term</em> has a <code>container</code> set to <code>@list</code>,
- continue to the next <em>term</em>.</li>
- <li>Set <em>rank</em> to the <tref>term rank</tref> of <em>value</em> by passing
- passing <em>term</em>, <em>value</em>, and <tref>active context</tref> to
- the <a href="#term-rank-algorithm">Term Rank Algorithm</a>.</li>
- <li>If <em>rank</em> is greater than <code>0</code>:
- <ol class="algorithm">
- <li>If <em>term</em> has a <code>container</code> set to <code>@set</code>, then add
- <code>1</code> to <em>rank</em>.</li>
- <li>If <em>value</em> is a <tref>JSON object</tref> containing only the property <code>@list</code>
- and <em>list container</em> is <code>false</code> and <em>term</em> has a <code>container</code>
- set to <code>@list</code>, then set <em>list container</em> to <code>true</code>, clear
- <em>terms</em>, set <em>highest rank</em> to <em>rank</em>, and add <em>term</em> to <em>terms</em>.</li>
- <li>Otherwise, if <em>rank</em> is greater than or equal to <em>highest rank</em>:
- <ol class="algorithm">
- <li>If <em>rank</em> is greater than <em>highest rank</em>, clear <em>terms</em> and set
- <em>highest rank</em> to <em>rank</em>.</li>
- <li>Add <em>term</em> to <em>terms</em>.</li>
- </ol>
- </li>
- </ol>
- </li>
- </ol>
- </li>
- <li>If <em>terms</em> is empty, and the <tref>active context</tref> has a <code>@vocab</code>
- which is a prefix of <em>iri</em> where
- the resulting <tref>relative IRI</tref> is not a <tref>term</tref> in the
- <tref>active context</tref>. The resulting <tref>relative IRI</tref> is the
- unmatched part of <em>iri</em>.</li>
- <li>If <em>terms</em> is empty, add a <tref>compact IRI</tref> representation of <em>iri</em>
- for each <tref>term</tref> in the <tref>active context</tref> which
- maps to an <tref>IRI</tref> which is a prefix for <em>iri</em> where
- the resulting <tref>compact IRI</tref> is not a <tref>term</tref> in the
- <tref>active context</tref>. The resulting <tref>compact IRI</tref> is the
- <tref>term</tref> associated with the partially
- matched IRI in the <tref>active context</tref> concatenated with a
- colon (:) character and the unmatched part of <em>iri</em>.</li>
- <li>If <em>terms</em> is empty, the <tref>IRI</tref> being processed is a property or the
- value of <code>@type</code> and <code>@vocab</code> is not null and matches the beginning
- of <em>iri</em>, return the unmatched portion of <em>iri</em>. Otherwise return
- <em>iri</em>.</li>
- <li>Otherwise, return the shortest and lexicographically least value in <em>terms</em>.</li>
- </ol>
- </p>
-</section>
-
-<section>
-<h3>Term Rank Algorithm</h3>
-<p>When selecting among multiple possible terms for a given property, it may be that multiple
- <tref title="term">terms</tref> are defined with the same <tref>IRI</tref>, but differ in <code>@type</code>, <code>@container</code>
- or <code>@language</code>. The purpose of this algorithm is to take a <tref>term</tref>
- and a value and give it a <tdef>term rank</tdef>. The selection can then be based, partly, on
- the term having the highest <tref>term rank</tref>.</p>
-<p>Given a <tref>term</tref> <em>term</em>, <em>value</em>, and <tref>active context</tref>
- determine the <tref>term rank</tref> using the following steps:</p>
-<ol class="algorithm">
- <li>If <em>value</em> is <tref>null</tref>, <tref>term rank</tref> is <code>3</code>.</li>
- <li>Otherwise, if <em>value</em> is a <tref>JSON object</tref> containing only the property <code>@list</code>:
- <ol class="algorithm">
- <li>If the <code>@list</code> property is an empty array, if <em>term</em> has <code>@container</code>
- set to <code>@list</code>, <tref>term rank</tref> is <code>1</code>, otherwise <code>0</code>.</li>
- <li>Otherwise, return the sum of the <tref>term rank</tref>s for every entry in the list.</li>
- </ol>
- </li>
- <li>Otherwise, <em>value</em> MUST be a <tref>subject definition</tref>, <tref>subject reference</tref>,
- or a <tref>JSON object</tref> having a <code>@value</code>.
- <ol class="algorithm">
- <li>If <em>value</em> has a <code>@value</code> property:
- <ol class="algorithm">
- <li>If <em>value</em> has a <code>@type</code> property matching a
- <code>@type</code> coercion for <em>term</em>, <tref>term rank</tref>
- is <code>3</code>, otherwise if <em>term</em> has no <code>@type</code>
- coercion and no <code>@language</code>, <tref>term rank</tref> is
- <code>1</code>, otherwise <code>0</code>.</li>
- <li>Otherwise, if <code>@value</code> is not a <tref>string</tref>, if <em>term</em> has
- no <code>@type</code> or <code>@language</code> it is <code>2</code>, otherwise <code>1</code>.</li>
- <li>Otherwise, if <em>value</em> has no <code>@language</code> property, if <em>term</em> has
- <code>@language</code> <tref>null</tref>, or <em>term</em> has no <code>@type</code> or
- <code>@language</code> and the <tref>active context</tref> has no <code>@language</code>,
- <tref>term rank</tref> is <code>3</code>, otherwise <code>0</code>.</li>
- <li>Otherwise, if <em>value</em> has a <code>@language</code> property matching a
- <code>@language</code> definition for <em>term</em> (or
- <em>term</em> has no <code>@type</code> or <code>@language</code> definition and
- <code>@language</code> in the <tref>active context</tref> matches the
- <em>value</em> <code>@language</code>), <tref>term rank</tref> is
- <code>3</code>, otherwise if <em>term</em> has no <code>@type</code>
- coercion and no <code>@language</code>, <tref>term rank</tref> is
- <code>1</code>, otherwise <code>0</code>.</li>
- </ol>
- </li>
- <li>Otherwise, if <em>term</em> has <code>@type</code> coerced to <code>@id</code>,
- <tref>term rank</tref> is <code>3</code>, otherwise
- if <em>term</em> has no <code>@type</code> coercion and no <code>@language</code>,
- <tref>term rank</tref> is <code>1</code>, otherwise <code>0</code>.</li>
- </ol>
- </li>
- <li>Return <tref>term rank</tref>.</li>
-</ol>
-</section>
-
-</section>
-
-<section>
- <h2>Value Expansion</h2>
- <p>Some values in JSON-LD can be expressed in a compact form. These values
- are required to be expanded at times when processing JSON-LD documents.</p>
-
- <p>The algorithm for expanding a <em>value</em> takes an <tref>active property</tref>
- and <tref>active context</tref>. It is implemented as follows:</p>
- <ol class="algorithm">
- <li>If <em>value</em> is <tref>null</tref>, the <em>value</em> is already expanded.</li>
- <li>If <tref>active property</tref> is <code>@graph</code> or the target of an <code>@id</code> coercion,
- expand the value into an object with a key-value pair where the key is <code>@id</code> and the value is
- the expanded IRI according to the <a href="#iri-expansion">IRI Expansion</a> rules.</li>
- <li>Otherwise, if <tref>active property</tref> is not a <tref>keyword</tref>, then expand <em>value</em> into an
- object:
- <ol class="algorithm">
- <li>Set the first key-value pair to <code>@value</code> and the unexpanded <em>value</em>.</li>
- <li>If the <tref>active property</tref> is the target of typed literal coercion, set the second key-value pair
- to <code>@type</code> and the associated coercion datatype expanded according to the
- <a href="#iri-expansion">IRI Expansion</a> rules.</li>
- <li>Otherwise, if the <tref>active property</tref> is the target of language tagging, set the second key-value
- pair to <code>@language</code> and value of the language tagging from the <tref>active context</tref>.</li>
- </ol>
- </li>
- <li>Otherwise, <em>value</em> is already expanded.</li>
- </ol>
-</section>
-
-<section>
- <h2>Value Compaction</h2>
- <p>Some values, such as <tref title="IRI">IRIs</tref> and <tref title="typed literal">typed literals</tref>, may be expressed in an
- expanded form in JSON-LD. These values are required to be compacted at
- times when processing JSON-LD documents.
- </p>
-
- <p>The algorithm for compacting an expanded value <em>value</em> takes an <tref>active property</tref>
- and <tref>active context</tref>. It is implemented as follows:</p>
- <ol class="algorithm">
- <li>If <em>value</em> only has one property and the <tref>active context</tref> has no default language,
- then the compacted value is the value of <code>@value</code>.</li>
- <li>Otherwise, if <tref>active property</tref> is <code>@graph</code>, the compacted value is the
- value associated with the <code>@id</code> key, processed according to
- the <a href="#iri-compaction">IRI Compaction</a> steps.</li>
- <li>Otherwise, if the <tref>active context</tref> contains a coercion target for the
- key that matches the expression of the value, compact the value using the
- following steps:
- <ol class="algorithm">
- <li>If the coercion target is an <code>@id</code>, the compacted
- value is the value associated with the <code>@id</code> key,
- processed according to the
- <a href="#iri-compaction">IRI Compaction</a> steps.</li>
- <li>If the coercion target is a <tref>typed literal</tref>, the compacted
- value is the value associated with the <code>@value</code> key.</li>
- </ol>
- </li>
- <li>Otherwise, if <em>value</em> contains an <code>@id</code> key, the compacted value is <em>value</em> with
- the value of <code>@id</code> processed according to the
- <a href="#iri-compaction">IRI Compaction</a> steps.</li>
- <li>Otherwise, if the <tref>active context</tref> contains a <code>@language</code>, which
- matches the <code>@language</code> of the value, or the value has only a <code>@value</code> key, the compacted
- value is the value associated with the <code>@value</code> key.</li>
- <li>Otherwise, if the value contains a <code>@type</code> key, the compacted value
- is <em>value</em> with the <code>@type</code> value processed according to the
- <a href="#iri-compaction">IRI Compaction</a> steps.</li>
- <li>Otherwise, the value is not modified.</li>
- </ol>
-</section>
-
-<section>
-<h2>Expansion</h2>
-
-<p>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.</p>
-
-<p>For example, assume the following JSON-LD input document:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-{
- "@context":
- {
- "name": "http://xmlns.com/foaf/0.1/name",
- "homepage": {
- "@id": "http://xmlns.com/foaf/0.1/homepage",
- "@type", "@id"
- }
- },
- "name": "Manu Sporny",
- "homepage": "http://manu.sporny.org/"
-}
--->
-</pre>
-
-<p>Running the JSON-LD Expansion algorithm against the JSON-LD input document
- provided above would result in the following output:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-{
- "http://xmlns.com/foaf/0.1/name": "Manu Sporny",
- "http://xmlns.com/foaf/0.1/homepage": {
- "@id": "http://manu.sporny.org/"
- }
-}
--->
-</pre>
-
-<section>
-<h3>Expansion Algorithm</h3>
-
-<p>The algorithm takes three input variables: an <tref>active context</tref>,
- an <tref>active property</tref>, and an <em>element</em> to be expanded. To
- begin, the <tref>active context</tref> is set to the result of performing, <a
- href="#context-processing">Context Processing</a> on the passed
- <em>context</em>, or empty if <em>context</em> is <tref>null</tref>,
- <tref>active property</tref> is set to <tref>null</tref>, and
- <em>element</em> is set to the <tref>JSON-LD input</tref>.</p>
-<ol class="algorithm">
- <li>If <em>element</em> is an <tref>array</tref>, process each entry in <em>element</em> recursively
- using this algorithm, passing copies of the <tref>active context</tref> and <tref>active property</tref>.
- If has a <code>@container</code> set to <code>@list</code> and any entry in <em>element</em> is an
- <tref>array</tref>, or is a <tref>JSON object</tref> containing a <code>@list</code> 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 <em>element</em>'s entries.</li>
- <li>Otherwise, if <em>element</em> is an object
- <ol class="algorithm">
- <li>If <em>element</em> has a <code>@context</code> property, update the <tref>active context</tref> according to
- the steps outlined in <a href="#context-processing">Context Processing</a> and remove the <code>@context</code>
- property.</li>
- <li>Then, proceed and process each <em>property</em> and <em>value</em> in <em>element</em> as follows:
- <ol class="algorithm">
- <li>Remove <em>property</em> from <em>element</em>, expand
- <em>property</em> according to the steps outlined in <a href="#iri-expansion">IRI Expansion</a>.
- Set the <tref>active property</tref> to the original un-expanded <em>property</em> if
- <em>property</em> is not a <tref>keyword</tref>.</li>
- <li>If <em>property</em> does not expand to a keyword or an <tref>absolute IRI</tref> (i.e., it doesn't contain a colon),
- continue with the next property from <em>element</em>.</li>
- <li>If <em>value</em> is <tref>null</tref> and <em>property</em> is not <code>@value</code>, continue with the next
- property from <em>element</em>.</li>
- <li>If the <em>property</em> is <code>@id</code> the <em>value</em> MUST be a <tref>string</tref>.
- Expand the <em>value</em> according to <a href="#iri-expansion">IRI Expansion</a>.</li>
- <li>Otherwise, if the <em>property</em> is <code>@type</code>:
- <ol class="algorithm">
- <li>If <em>value</em> is a <tref>string</tref>, expand according to <a href="#iri-expansion">IRI Expansion</a>.</li>
- <li>Otherwise, if <em>value</em> is a <tref>JSON Object</tref>, it must be empty (used for
- <cite><a href="../json-ld-framing/#framing">Framing</a></cite>).</li>
- <li>Otherwise, if <em>value</em> is an <tref>array</tref>, all elements must be <tref>string</tref>s.
- Expand <em>value</em> for each of its entries according to <a href="#iri-expansion">IRI Expansion</a>.</li>
- </ol>
- </li>
- <li>Otherwise, if the <em>property</em> is <code>@value</code> or <code>@language</code> the <em>value</em> MUST NOT be a
- <tref>JSON object</tref> or an <tref>array</tref>.</li>
- <li>Otherwise, if the <em>property</em> is <code>@list</code> or <code>@set</code> expand <em>value</em>
- recursively using this algorithm, passing copies of the <tref>active context</tref> and <em>active property</em>. If the expanded
- <em>value</em> is not an <tref>array</tref>, convert it to an <tref>array</tref>.
- If <em>property</em> is <code>@list</code> and any entry in <em>value</em> is a
- <tref>JSON object</tref> containing an <code>@list</code> property, throw an exception, as
- lists of lists are not supported.</li>
- <li>Otherwise, expand <em>value</em> recursively using this algorithm, passing copies of the <tref>active context</tref> and
- <tref>active property</tref>.</li>
- <li>If <em>property</em> is not a keyword
- and <tref>active property</tref> has a <code>@container</code> <code>@list</code>
- and the expanded <em>value</em> is not <tref>null</tref>,
- convert <em>value</em> to an <tref>object</tref> with an <code>@list</code> property whose value is
- set to <em>value</em> (unless <em>value</em> is already in that form).</li>
- <li>Convert <em>value</em> to <tref>array</tref> form unless <em>value</em> is <tref>null</tref> or <em>property</em> is
- <code>@id</code>, <code>@type</code>, <code>@value</code>, or <code>@language</code>.</li>
- <li>If <em>value</em> is not <tref>null</tref>, either merge <em>value</em> into an existing <em>property</em> property of
- <em>element</em> or create a new <em>property</em> property with <em>value</em> as value.</li>
- </ol>
- </li>
- <li>If the processed <em>element</em> has an <code>@value</code> property
- <ol class="algorithm">
- <li><em>element</em> MUST NOT have more than one other property, which can either be <code>@language</code> or <code>@type</code>
- with a <tref>string</tref> value.</li>
- <li>if the value of <code>@value</code> equals <tref>null</tref>,
- replace <em>element</em> with the value of <code>@value</code>.</li>
- </ol>
- </li>
- <li>Otherwise, if <em>element</em> has an <code>@type</code> property and its value is not in the form of an
- <tref>array</tref>, convert it to an <tref>array</tref>.</li>
- <li>If <em>element</em> has an <code>@set</code> or <code>@list</code> property, it MUST be the only property.
- Set <em>element</em> to the value of <code>@set</code>; leave <code>@list</code> untouched.</li>
- <li>If <em>element</em> has just a <code>@language</code> property, set <em>element</em> to <tref>null</tref>.</li>
- </ol>
- </li>
- <li>Otherwise, expand <em>element</em> according to the <a href="#value-expansion">Value Expansion</a> rules,
- passing copies of the <tref>active context</tref> and <tref>active property</tref>.</li>
-</ol>
-
-<p>If, after the algorithm outlined above is run, the resulting <em>element</em> is an <tref>JSON object</tref> with just a <code>@graph</code>
- property, <em>element</em> is set to the value of <code>@graph</code>'s value. Finally, if <em>element</em> is a <tref>JSON object</tref>,
- it is wrapped into an <tref>array</tref>.</p>
-
-</section>
-
-</section>
-
-<section>
-<h2>Compaction</h2>
-
-<p>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.</p>
-
-<p>For example, assume the following JSON-LD input document:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-{
- "http://xmlns.com/foaf/0.1/name": "Manu Sporny",
- "http://xmlns.com/foaf/0.1/homepage": {
- "@id": "http://manu.sporny.org/"
- }
-}
--->
-</pre>
-
-<p>Additionally, assume the following developer-supplied JSON-LD context:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-{
- "@context": {
- "name": "http://xmlns.com/foaf/0.1/name",
- "homepage": {
- "@id": "http://xmlns.com/foaf/0.1/homepage",
- "@type": "@id"
- }
- }
-}
--->
-</pre>
-
-<p>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:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-{
- "@context": {
- "name": "http://xmlns.com/foaf/0.1/name",
- "homepage": {
- "@id": "http://xmlns.com/foaf/0.1/homepage",
- "@type": "@id"
- }
- },
- "name": "Manu Sporny",
- "homepage": "http://manu.sporny.org/"
-}
--->
-</pre>
-
-<p>The compaction algorithm also enables the developer to map any expanded
- format into an application-specific compacted format. While the context
- provided above mapped <code>http://xmlns.com/foaf/0.1/name</code> to
- <strong>name</strong>, it could have also mapped it to any arbitrary string
- provided by the developer.</p>
-
-<section>
-<h3>Compaction Algorithm</h3>
-
-<p>The algorithm takes three input variables: an <tref>active context</tref>, an <tref>active property</tref>,
- and an <em>element</em> to be compacted. To begin, the <tref>active context</tref> is
- set to the result of performing <a href="#context-processing">Context Processing</a> on the passed <em>context</em>,
- <tref>active property</tref> is set to <tref>null</tref>, and <em>element</em> is set to the result of performing the
- <a href="#expansion-algorithm">Expansion Algorithm</a> on the <tref>JSON-LD input</tref>. This removes any existing
- context to allow the given <tref>active context</tref> to be cleanly applied.</p>
-
-<ol class="algorithm">
- <li>If <em>element</em> is an <tref>array</tref>, process each entry in <em>element</em> recursively
- using this algorithm, passing a copy of the <tref>active context</tref> and the <tref>active property</tref>.
- If <em>element</em> has a single item, the compacted value is that item; otherwise the compacted value
- is <em>element</em>.</li>
- <li>Otherwise, if <em>element</em> is an object:
- <ol class="algorithm">
- <li>If <em>element</em> has an <code>@value</code> property or element is a <tref>subject reference</tref>,
- return the result of performing
- <a href="#value-compaction">Value Compaction</a> on <em>element</em> using <tref>active property</tref>.</li>
- <li>Otherwise, if the <tref>active property</tref> has a <code>@container</code> mapping to <code>@list</code>
- and <em>element</em> has a corresponding <code>@list</code> property, recursively compact that
- property's value passing a copy of the <tref>active context</tref> and the <tref>active property</tref> ensuring
- that the result is an array with all <tref>null</tref> values removed. If there already exists a value for
- <tref>active property</tref> in <em>element</em> and the full IRI of <em>property</em> is also coerced to
- <code>@list</code>, throw an exception. Otherwise store the resulting array as value of <tref>active property</tref>
- if empty or <em>property</em> otherwise.</li>
- <li>Otherwise, construct <em>output</em> as a new <tref>JSON object</tref> used for returning the result
- of compacting <em>element</em>. For each <em>property</em> and <em>value</em> in <em>element:</em>
- <ol class="algorithm">
- <li>If <em>property</em> is <code>@id</code> or <code>@type</code>
- <ol class="algorithm">
- <li>Set <tref>active property</tref> to the result of performing
- <a href="#iri-compaction">IRI Compaction</a> on <em>property</em>.</li>
- <li>If <em>value</em> is a <tref>string</tref>, the compacted <em>value</em> is the result of performing
- <a href="#iri-compaction">IRI Compaction</a> on <em>value</em>.</li>
- <li>Otherwise, <em>value</em> MUST be an <tref>array</tref>. Perform <a href="#iri-compaction">IRI Compaction</a>
- on every entry of <em>value</em>. If <em>value</em> contains just one entry, <em>value</em> is set to that entry.</li>
- <li>Add <tref>active property</tref> and the expanded <em>value</em> to <em>output</em>.</li>
- </ol>
- </li>
- <li>Otherwise, <em>value</em> MUST be an <tref>array</tref>.</li>
- <li>If <em>value</em> is empty:
- <ol class="algorithm">
- <li>Set <tref>active property</tref> to the result of performing
- <a href="#iri-compaction">IRI Compaction</a> on <em>property</em>.</li>
- <li>Create an entry in <em>output</em> for <tref>active property</tref> and <em>value</em>.</li>
- </ol>
- </li>
- <li>For each <em>item</em> in <em>value</em>:
- <ol class="algorithm">
- <li>Set <tref>active property</tref> to the result of performing <a href="#iri-compaction">IRI Compaction</a>
- for <em>property</em> and <em>item</em> using the <tref>active context</tref>.</li>
- <li>Compact <em>item</em> by recursively performing this algorithm passing a copy of
- the <tref>active context</tref> and the <tref>active property</tref>.</li>
- <li>If an entry already exists in <em>output</em> for <tref>active property</tref>, convert it
- to an <tref>array</tref> if necessary, and append the compacted <em>value</em>.</li>
- <li>Otherwise, if the compacted <em>value</em> is not an <tref>array</tref> and <tref>active property</tref>
- has a <code>@container</code> mapping to <code>@set</code>,
- create an entry in <em>output</em> for <tref>active property</tref> and <em>value</em> as an
- <tref>array</tref>.</li>
- <li>Otherwise, create an entry in <em>output</em> for <tref>active property</tref> and <em>value</em>.</li>
- </ol>
- </li>
- </ol>
- </li>
- </ol>
- </li>
- <li>Otherwise, return <em>element</em> as the compacted <em>element</em>.
- <div class="issue">Perhaps this should also call <a href="#value-compaction">Value Compaction</a> on
- native types and strings, which could consolidate potential transformation in one place.</div>
- </li>
-</ol>
-
-<p>If, after the algorithm outlined above is run, the resulting <em>element</em> is an <tref>array</tref>, put <em>element</em> into the
- <code>@graph</code> property of a new <tref>JSON object</tref> and then set <em>element</em> to that <tref>JSON object</tref>.
- Finally, add a <code>@context</code> property to <em>element</em> and set it to the initially passed <em>context</em>.</p>
-
-</section>
-
-</section>
-
-<section>
-<h2>RDF Conversion</h2>
-
-<p>A JSON-LD document MAY be converted between other RDF-compatible document
- formats using the algorithms specified in this section.</p>
-
-<p>The JSON-LD Processing Model describes processing rules for extracting RDF
- from a JSON-LD document, and for transforming an array of <a>Quad</a> retrieved by processing
- another serialization format into JSON-LD. Note that many uses of JSON-LD may not require
- generation of RDF.</p>
-
-<p>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.</p>
-
-<section class="informative">
- <h4>Overview</h4>
- <p>
- 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.
- </p>
- <p>
- As with other grammars used for describing <tref>Linked Data</tref>, a key
- concept is that of a <tref>node</tref> in a <tref>linked data graph</tref>.
- Nodes may be of three basic types.
- The first is the <ldtref>IRI</ldtref>, which is used to refer to
- <tref>node</tref>s in other <tref>linked data graph</tref>s.
- The second is the
- <tref>blank node</tref>, which are nodes for which an external name does not
- exist, or is not known. The third is a <tref>Literal</tref>, which express
- values such as strings, dates and other information having a lexical
- form, possibly including an explicit language or datatype.
- </p>
- <p>Data described with JSON-LD may be considered to be a graph made
- up of <tref>subject</tref> and <tref>object</tref>
- <tref title="node">nodes</tref> related via a <tref>property</tref>
- <tref>node</tref>. 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.</p>
-</section>
-
-<section class="informative">
- <h4>Parsing Examples</h4>
-
- <p>The following examples show simple transformations of JSON-LD documents to Turtle [[TURTLE-TR]].</p>
-
- <p>The first example uses a simple document containing a simple FOAF profile:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-{
- "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
- "@id": "http://greggkellogg.net/foaf#me",
- "@type": "foaf:Person",
- "foaf:name": "Gregg Kellogg",
- "foaf:knows": {
- "@type": "foaf:Person",
- "foaf:name": "Manu Sporny"
- }
-}
--->
-</pre>
-
- <p>This translates fairly directly to a similar Turtle document:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-@prefix foaf: <http://xmlns.com/foaf/0.1/>.
-
-<http://greggkellogg.net/foaf#me> a foaf:Person;
- foaf:name "Gregg Kellogg";
- foaf:knows [ a foaf:Person; foaf:name "Manu Sporny"].
--->
-</pre>
-
- <p>The actual parsing steps first require that the JSON-LD document be expanded,
- to eliminate the <code>@context</code>:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-[{
- "@id": "http://greggkellogg.net/foaf#me",
- "@type": ["http://xmlns.com/foaf/0.1/Person"],
- "http://xmlns.com/foaf/0.1/name": [{"@value": "Gregg Kellogg"}],
- "http://xmlns.com/foaf/0.1/knows": [{
- "@type": ["http://xmlns.com/foaf/0.1/Person"],
- "http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}]
- }]
-}]
--->
-</pre>
-
- <p>The process of translating this to RDF then operates over each
- <tref>subject definition</tref> to find a subject,
- each <tref>property</tref> to find an RDF <em>predicate</em>,
- and each value of that property to find an <tref>object</tref>.
- In this case, each property has just a single object:
- <code>foaf:name</code> identifies a <tref>literal</tref>, and
- <code>foaf:knows</code> identifies a second <tref>subject definition</tref>
- similar to Turtle's <code>blankNodePropertyList</code>.</p>
-
- <p>After expansion, JSON-LD <tref title="number">numbers</tref>,
- <tref title="true">booleans</tref>, typed- and language-tagged-<tref
- title="literal">literals</tref>, and <tref title="iri">IRIs</tref>
- become explicit, and can be directly transformed into their RDF representations.</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-[{
- "@id": "http://greggkellogg.net/foaf#me",
- "@type": ["http://xmlns.com/foaf/0.1/Person"],
- "http://xmlns.com/foaf/0.1/name": [{"@value": "Gregg Kellogg"}],
- ****"http://xmlns.com/foaf/0.1/currentProject": [{"@id": "http://json-ld.org/"}],
- "http://xmlns.com/foaf/0.1/birthday": [{
- "@value": "1957-02-27",
- "@type": "http://www.w3.org/2001/XMLSchema#date"
- }],****
- "http://xmlns.com/foaf/0.1/knows": [{
- "@type": ["http://xmlns.com/foaf/0.1/Person"],
- "http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}]
- }]
-}]
--->
-</pre>
-
- <p>Translates to:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-@prefix foaf: <http://xmlns.com/foaf/0.1/>.
-@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
-
-<http://greggkellogg.net/foaf#me> a foaf:Person;
- foaf:name "Gregg Kellogg";
- ****foaf:currentProject <http://json-ld.org/>;
- foaf:birthday "1957-02-27"^^xsd:date;****
- foaf:knows [ a foaf:Person; foaf:name "Manu Sporny"].
--->
-</pre>
-
-</section>
-
-<section>
- <h3>Convert to RDF Algorithm</h3>
- <p>
- The algorithm below is designed for in-memory implementations with random access to <tref>JSON object</tref> elements.
- </p>
- <p>
- A conforming JSON-LD processor implementing RDF conversion MUST implement a
- processing algorithm that results in the same set of RDF <tref title="quad">Quads</tref> that the following
- algorithm generates:
- </p>
-
- <p>The algorithm takes five input variables: a <em>element</em> to be converted, an
- <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>.
- To begin, the <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>
- are set to <tref>null</tref>, and <em>element</em> is
- set to the result of performing the <a href="#expansion-algorithm">Expansion Algorithm</a> on
- the <tref>JSON-LD input</tref>. This removes any existing context to allow the given context to be cleanly
- applied.</p>
-
- <ol class="algorithm">
- <li id="processing-step-associative">
- If <em>element</em> is a <tref>JSON object</tref>, perform the following steps:
- <ol class="algorithm">
- <li>Set <tref>active object</tref> to <tref>null</tref>.</li>
- <li>
- If <em>element</em> has a <code>@value</code> property:
- <ol class="algorithm">
- <li>If the value of <code>@value</code> is a <tref>number</tref>, set the
- <tref>active object</tref> to a <tref>typed literal</tref> using a string representation
- of the value as defined in the section <a href="#data-round-tripping">Data Round Tripping</a>.
- Set datatype to the value of the <code>@type</code> property if it exists, otherwise
- either <code>xsd:integer</code> or <code>xsd:double</code>, depending
- on if the value contains a fractional and/or an exponential component.
- <p class="issue" data-number="150">It is being
- <a href="https://github.com/json-ld/json-ld.org/issues/150">discussed</a> if the automatic
- mapping of JSON-native types to the XSD type system should be configurable or not.</p></li>
- <li>Otherwise, if the value of <code>@value</code> is <strong>true</strong> or <strong>false</strong>,
- set the <tref>active object</tref> to a <tref>typed literal</tref> created from the
- string representation of the value. Set datatype to the value of the <code>@type</code>
- property if it exists, otherwise <code>xsd:boolean</code>.</li>
- <li>
- Otherwise, if <em>element</em> contains a <code>@type</code> property, set the
- <tref>active object</tref> to a <tref>typed literal</tref>.
- </li>
- <li>
- Otherwise, if <em>element</em> contains a <code>@language</code> property, set the
- <tref>active object</tref> to a <tref>language-tagged literal</tref>.
- </li>
- <li>
- Otherwise, set the <tref>active object</tref> to a <tref>typed literal</tref>
- using <code>xsd:string</code> as the datatype.
- </li>
- </ol>
- </li>
- <li>
- If <em>element</em> has a <code>@list</code> property the value MUST be an <tref>array</tref>.
- Process its value as a list as described in <a href="#list-conversion">List Conversion</a> using
- the return value as the <tref>active object</tref>
- </li>
- <li>If <tref>active object</tref> is not <tref>null</tref>:
- <ol class="algorithm">
- <li>If neither <tref>active subject</tref> nor <tref>active property</tref> are <tref>null</tref>,
- generate a <a>Quad</a>
- representing <tref>active subject</tref>, <tref>active property</tref>,
- <tref>active object</tref>, and <tref>graph name</tref>.</li>
- <li>Return <tref>active object</tref>.</li>
- </ol>
- </li>
- <li id="processing-step-subject">If <em>element</em> has a <code>@id</code> property,
- the value MUST be a <tref>string</tref>, set the <tref>active subject</tref> to the previously
- expanded value (either a <tref>blank node</tref> or an <ldtref>IRI</ldtref>).</li>
- <li>
- Otherwise, if <em>element</em> does not have a <code>@id</code> property, set the <tref>active
- subject</tref> to newly generated <tref>blank node</tref>.</li>
- <li>
- Process each <em>property</em> and <em>value</em> in <em>element</em>, ordered by
- <em>property</em>, as follows:
- <ol class="algorithm">
- <li>
- If <em>property</em> is <code>@type</code>, set the <tref>active property</tref>
- to <code>rdf:type</code>.
- </li>
- <li>Otherwise, if <em>property</em> is <code>@graph</code>,
- process <em>value</em> algorithm recursively, using <tref>active subject</tref> as <tref>graph name</tref>
- and null values for <tref>active subject</tref> and <tref>active property</tref> and then
- proceed to next property.</li>
- <li>Otherwise, if <em>property</em> is a <tref>keyword</tref>, skip this step.</li>
- <li>Otherwise, set <tref>active property</tref> to the IRI value of <em>property</em>.</li>
- <li>Process <em>value</em> recursively using this algorithm, passing copies of
- <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>.
- </li>
- </ol>
- </li>
- <li>
- Set <tref>active object</tref> to <tref>active subject</tref>.
- </li>
- </ol>
- </li>
-
- <li>Otherwise, if <em>element</em> is an <tref>array</tref>, process each value in the <tref>array</tref>
- as follows, process <em>element</em> recursively using this algorithm, using copies of
- <tref>active subject</tref>, <tref>active property</tref>, and <tref>graph name</tref>.</li>
-
- <li>Otherwise, if <em>element</em> is a <tref>string</tref>, then the <tref>active property</tref>
- must be <code>rdf:type</code> so set the <tref>active object</tref> to an <ldtref>IRI</ldtref>.</li>
-
- <li>If any of these steps created an <tref>active object</tref> and neither <tref>active subject</tref>
- nor <tref>active property</tref> are <tref>null</tref>, generate a <a>Quad</a> using
- <tref>active subject</tref>,<tref>active property</tref>, <tref>active object</tref> and
- <tref>graph name</tref>.
- </li>
- <li>Return <tref>active object</tref>.</li>
- </ol>
-</section>
-<section id="list-conversion">
- <h3>List Conversion</h3>
-
- <p>List Conversion is the process of taking an <tref>array</tref> of values and adding them to a newly
- created <cite><a href="http://www.w3.org/TR/rdf-schema/#ch_collectionvocab">RDF Collection</a></cite> (see
- [[!RDF-SCHEMA]]) by linking each element of the list using <code>rdf:first</code> and <code>rdf:next</code>,
- terminating the list with <code>rdf:nil</code> using the following sequence:</p>
- <p>The algorithm is invoked with an <tref>array</tref> <em>array</em>, the <tref>active property</tref>
- and returns a value to be used as an <tref>active object</tref> in the calling location.</p>
- <div class="note">This algorithm does not support lists containing lists.</div>
- <ol class="algorithm">
- <li>
- If <em>array</em> is empty return <code>rdf:nil</code>.
- </li>
- <li>
- Otherwise, generate a <a>Quad</a> using using the <tref>active subject</tref>, <tref>active property</tref>
- and a newly generated <tref>blank node</tref> identified as <em>first <tref>blank node</tref></em>.
- </li>
- <li>
- For each element in <em>array</em> other than the last element:
- <ol class="algorithm">
- <li>Create a processor state using
- <em>first blank node</em> as the <tref>active subject</tref>, and
- <code>rdf:first</code> as the <tref>active property</tref>.
- <ol class="algorithm">
- <li>Process the value starting at <a href="#processing-step-associative">Step 1</a>.</li>
- <li>Proceed using the previous <tref>processor state</tref>.</li>
- </ol>
- </li>
- <li>Unless this is the last element in <em>array</em>, generate a new <tref>blank node</tref> identified as
- <em>rest blank node</em>, otherwise use <code>rdf:nil</code>.</li>
- <li>Generate a new <a>Quad</a> using <em>first blank node</em>,
- <code>rdf:rest</code> and <em>rest blank node</em>.</li>
- <li>Set <em>first blank node</em> to
- <em>rest blank node</em>.</li>
- <li>Return <em>first blank node</em>.</li>
- </ol>
- </li>
- </ol>
-</section>
-
-<section>
- <h2>Convert from RDF Algorithm</h2>
- <p>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 <ldtref title="quad">Quads</ldtref> into a JSON-LD document.</p>
- <p>When expanding <tref>typed literal</tref> values having a datatype of <code>xsd:string</code>,
- the <code>@type</code> MUST NOT be set to <code>xsd:string</code> and the resulting value
- MUST have only a <code>@value</code> property.</p>
- <p>The conversion algorithm takes a single parameter <em>input</em> in the form of an
- array of <a>Quad</a> representations.</p>
- <ol class="algorithm">
- <li id="new_graph">Construct <em>defaultGraph</em> as a <tref>JSON object</tref>
- containing <em>subjects</em> and <em>listMap</em>, each an empty <tref>JSON object</tref>.</li>
- <li>Construct <em>graphs</em> as a <tref>JSON object</tref> containing <em>defaultGraph</em>
- identified by
- an empty <tref>string</tref>.</li>
- <li>For each quad in <em>input</em>:
- <ol class="algorithm">
- <li>Set <em>graph</em> to the entry in <em>graphs</em> identified
- by <em>name</em>, initializing it to a new entry using the mechanism
- described in <a href="#new_graph">Step 1</a>.</li>
- <li>If <em>property</em> is <code>rdf:first</code>,
- use the entry in <em>graph.listMap</em> indexed by <em>subject</em>,
- initializing it to a new <tref>JSON object</tref> if nesessary. Represent
- <em>object</em> in expanded form, as described in
- <a href="#value-expansion">Value Expansion</a>. Add the
- resulting <em>object representation</em> to the entry indexed by
- <em>first</em>, and skip to the next quad.</li>
- <li>If <em>property</em> is <code>rdf:rest</code>:
- <ol class="algorithm">
- <li>If <em>object</em> is a <tref>blank node</tref>, use the entry in
- <em>graph.listMap</em> indexed by <em>subject</em>, initializing it
- to a new <tref>JSON object</tref> if necessary. Add the <em>nominalValue</em> of
- <em>object</em> to the entry indexed by <em>rest</em>.
- </li>
- <li>Skip to the next quad.</li>
- </ol>
- </li>
- <li>If <em>name</em> is not <tref>null</tref>, and <em>defaultGraph.subjects</em>
- does not contain an entry for <em>name</em>,
- create a new entry for <em>name</em> from a new
- <tref>JSON object</tref> with key/value pair of <code>@id</code> and
- a string representation of <em>name</em>.</li>
- <li>Set <em>value</em> as the entry from <em>graph.subjects</em> for
- <em>subject</em>, initializing it to a new
- <tref>JSON object</tref> with key/value pair of <code>@id</code> and
- a string representation of <em>subject</em> if necessary.</li>
- <li>If <em>property</em> is <code>rdf:type</code> and the <em>notType</em>
- option is present and not <tref>true</tref>:
- <ol class="algorithm">
- <li>Append the string representation of <em>object</em> to the array value for the
- key <code>@type</code>, creating an entry in <em>value</em> if necessary.</li>
- </ol>
- </li>
- <li>Otherwise, if <em>object</em> is <code>rdf:nil</code>:
- <ol class="algorithm">
- <li>Let <em>key</em> be the string representation of <em>property</em>.</li>
- <li>Append an empty <code>@list</code> representation to the array value for
- <em>key</em>, creating an entry in <em>value</em> if necessary.</li>
- </ol>
- </li>
- <li>Otherwise,
- <ol class="algorithm">
- <li>Let <em>key</em> be the string representation of <em>property</em> and let
- <em>object representation</em>
- be <em>object</em> represented in expanded form as described in
- <a href="#value-expansion">Value Expansion</a>.</li>
- <li>If <em>object</em> is a <tref>blank node</tref>,
- use the entry in <em>graph.listMap</em> indexed by <em>object</em>,
- initializing it to a new <tref>JSON object</tref> if nesessary.
- Add an entry for <em>head</em> with <em>object representation</em>.</li>
- <li>Append <em>object representation</em> to the array value for
- <em>key</em>, creating an entry in <em>value</em> if necessary.</li>
- </ol>
- </li>
- </ol>
- </li>
- <li>For each <em>name</em> and <em>graph</em> in <em>graphs</em>:
- <ol class="algorithm">
- <li>For each <em>subject</em> and <em>entry</em> in <em>graph</em>
- where <em>entry</em> has both <em>head</em> and <em>first</em> keys:
- <ol class="algorithm">
- <li>Set <em>value</em> to the value of <em>head</em> in <em>entry</em>.</li>
- <li>Remove the entry for <code>@id</code> in <em>value</em>.</li>
- <li>Add an entry to <em>value</em> for <code>@list</code> initialized to a new array
- containing the value of <em>first</em> from <em>entry</em>.</li>
- <li>While <em>entry</em> has a key for <em>rest</em>:
- <ol class="algorithm">
- <li>Set <em>entry</em> to the value of <em>graph.listMap</em> for <em>entry.rest</em>.</li>
- <li>Add the value for <em>entry.first</em> to the list array.</li>
- </ol>
- </li>
- </ol>
- </li>
- </ol>
- </li>
- <li>Create <em>array</em> as an empty <tref>array</tref>.</li>
- <li>For each <em>subject</em> and <em>entry</em> in <em>defaultGraph.subjects</em>
- ordered by <em>subject</em>:
- <ol class="algorithm">
- <li>Add <em>entry</em> to <em>array</em>.</li>
- <li>If <em>graphs</em> has an entry for <em>subject</em>, add a property
- <code>@graph</code> in <em>entry</em> containing the ordered entries
- from <em>graphs[subject].subjects</em>.</li>
- </ol>
- </li>
- <li>Return <em>array</em> as the result.</li>
- </ol>
-</section>
-</section>
-
-</section>
-
-<section>
-<h3>Data Round Tripping</h3>
-
-<p>When <a href="#rdf-conversion">converting JSON-LD to RDF</a> JSON-native types such as
- <em>numbers</em> and <em>booleans</em> are automatically coerced to <strong>xsd:integer</strong>,
- <strong>xsd:double</strong>, or <strong>xsd:boolean</strong>. Implementers MUST ensure that the
- result is a canonical lexical form in the form of a <tref>string</tref>. A
- <tdef>canonical lexical form</tdef> 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.</p>
-
-<p>The canonical lexical form of an <em>integer</em>, i.e., a number without fractions
- or a number coerced to <strong>xsd:integer</strong>, is a finite-length sequence of decimal
- digits (<code>0-9</code>) with an optional leading minus sign; leading zeroes are prohibited.
- To convert the number in JavaScript, implementers can use the following snippet of code:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-(value).toFixed(0).toString()
--->
-</pre>
-
-<p>The canonical lexical form of a <em>double</em>, i.e., a number with fractions
- or a number coerced to <strong>xsd:double</strong>, 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 (<code>+</code>) are prohibited
- in the exponent. If the exponent is zero, it must be indicated by <code>E0</code>.
- 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 <code>0.0E0</code>.
- <strong>xsd:double</strong>'s value space is defined by the IEEE double-precision 64-bit
- floating point type [[!IEEE-754-1985]]; in JSON-LD the mantissa is rounded to 15 digits after the
- decimal point.</p>
-
-<p>To convert the number in JavaScript, implementers can use the following snippet of code:</p>
-
-<pre class="example" data-transform="updateExample">
-<!--
-(value).toExponential(15).replace(/(\d)0*e\+?/,'$1E')
--->
-</pre>
-
-<p class="note">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 <strong>xsd:double</strong> values. Authors should instead use the expanded object form to
- set the canonical lexical form directly.</p>
-
-<p>The canonical lexical form of the <em>boolean</em> values <code>true</code> and <code>false</code>
- are the strings <strong>true</strong> and <strong>false</strong>.</p>
-
-<p>When JSON-native <tref>number</tref>s, are type coerced, lossless data round-tripping can not
- be guaranted as rounding errors might occur. Additionally, only literals typed as
- <strong>xsd:integer</strong>, <strong>xsd:double</strong>, and <strong>xsd:boolean</strong> are
- automatically converted back to their JSON-native counterparts in when
- <a href="#rdf-conversion">converting from RDF</a>.</p>
-
-<p class="issue" data-number="150">It is being
- <a href="https://github.com/json-ld/json-ld.org/issues/150">discussed</a> if the automatic mapping
- of JSON-native types to the XSD type system should be configurable or not.</p>
-
-<p class="note">Some JSON serializers, such as PHP's native implementation in some versions,
- backslash-escape the forward slash character. For example, the value
- <code>http://example.com/</code> would be serialized as <code>http:\/\/example.com\/</code>.
- 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.</p>
-
-</section>
-
-<section class="appendix">
-<h1>Acknowledgements</h1>
-
-<p>A large amount of thanks goes out to the JSON-LD Community Group
-participants who worked through many of the technical issues on the mailing
-list and the weekly telecons - of special mention are Niklas Lindström,
-François Daoust, and Zdenko 'Denny' Vrandečić.
-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.
-The work of Dave Lehn and Mike Johnson are appreciated for reviewing,
-and performing several implementations of the specification. Ian Davis is
-thanked for this work on 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.
-</p></section>
-
-</body>
-</html>
+<!DOCTYPE html>
+<html>
+<head>
+<title>JSON-LD API 1.0</title>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+<!--
+ === NOTA BENE ===
+ For the three scripts below, if your spec resides on dev.w3 you can check them
+ out in the same tree and use relative links so that they'll work offline,
+ -->
+<script type="text/javascript" src="../respec-w3c-common.js" class="remove"></script>
+<script type="text/javascript" class="remove">
+//<![CDATA[
+ var preProc = {
+ apply: function(c) {
+ // extend the bibliography entries
+ berjon.biblio["MICRODATA"] = "<cite><a href=\"http://www.w3.org/TR/2012/WD-microdata-20120329/\">HTML Microdata</a></cite> Ian Hickson Editor. World Wide Web Consortium (work in progress). 29 March 2012. This edition of the HTML Microdata specification is http://www.w3.org/TR/2012/WD-microdata-20120329/. The <a href=\"http://www.w3.org/TR/microdata/\">latest edition of HTML Microdata</a> is available at http://www.w3.org/TR/microdata/";
+ berjon.biblio["JSON-LD"] = "<cite><a href=\"http://json-ld.org/spec/ED/json-ld-syntax/20120522/\">The JSON-LD Syntax</a></cite> 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 <a href=\"http://json-ld.org/spec/latest/json-ld-syntax/\">latest edition of the JSON-LD Syntax</a> is available at http://json-ld.org/spec/latest/json-ld-syntax/";
+ berjon.biblio["JSON-POINTER"] = "<cite><a href=\"http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-02\">JSON Pointer</a></cite> P. Bryan, Ed. IETF Draft. URL: <a href=\"http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-02\">http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-02</a>";
+ berjon.biblio["RDF-NORMALIZATION"] = "<cite><a href=\"http://json-ld.org/spec/ED/rdf-graph-normalization/20111016/\">RDF Graph Normalization</a></cite> Manu Sporny, Dave Longley Editors. World Wide Web Consortium (work in progress). 16 October 2011. Editor's Draft. This edition of the RDF Graph Normalization specification is http://json-ld.org/spec/ED/rdf-graph-normalization/20111016/. The <a href=\"http://json-ld.org/spec/latest/rdf-graph-normalization/\">latest edition of RDF Graph Normalization</a> is available at http://json-ld.org/spec/latest/rdf-graph-normalization/";
+ berjon.biblio["IEEE-754-1985"] = "IEEE. <cite>IEEE Standard for Binary Floating-Point Arithmetic.</cite> See <a href=\"http://standards.ieee.org/reading/ieee/std_public/description/busarch/754-1985_desc.html\">http://standards.ieee.org/reading/ieee/std_public/description/busarch/754-1985_desc.html</a>";
+ berjon.biblio["RDF-CONCEPTS"] = "<cite><a href=\"http://www.w3.org/TR/2011/WD-rdf11-concepts-20110830/\">RDF 1.1 Concepts and Abstract Syntax</a></cite> Richard Cyganiak, David Wood, Editors. World Wide Web Consortium (work in progress). 30 May 2012. Editor's Draft. This edition of the JSON-LD Syntax specification is http://www.w3.org/TR/2011/WD-rdf11-concepts-20110830/. The <a href=\"http://www.w3.org/TR/rdf11-concepts/\">latest edition of the JSON-LD Syntax</a> is available at http://www.w3.org/TR/rdf11-concepts/";
+ berjon.biblio["TURTLE-TR"] = "Eric Prud'hommeaux, Gavin Carothers. <cite><a href=\"http://www.w3.org/TR/2011/WD-turtle-20110809/\">Turtle: Terse RDF Triple Language.</a></cite> 09 August 2011. W3C Working Draft. URL: <a href=\"http://www.w3.org/TR/2011/WD-turtle-20110809/\">http://www.w3.org/TR/2011/WD-turtle-20110809/</a>";
+ berjon.biblio["WEBIDL"] = "<cite><a href=\"http://www.w3.org/TR/2012/CR-WebIDL-20120419/\">Web IDL</a></cite> 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 <a href=\"http://dev.w3.org/2006/webapi/WebIDL/\">latest edition of Web IDL</a> is available at http://dev.w3.org/2006/webapi/WebIDL/";
+
+ // process the document before anything else is done
+ var refs = document.querySelectorAll('adef') ;
+ for (var i = 0; i < refs.length; i++) {
+ var item = refs[i];
+ var p = item.parentNode ;
+ var con = item.innerHTML ;
+ var sp = document.createElement( 'dfn' ) ;
+ var tit = item.getAttribute('title') ;
+ if (!tit) {
+ tit = con;
+ }
+ sp.className = 'adef' ;
+ sp.title=tit ;
+ sp.innerHTML = con ;
+ p.replaceChild(sp, item) ;
+ }
+ refs = document.querySelectorAll('aref') ;
+ for (var i = 0; i < refs.length; i++) {
+ var item = refs[i];
+ var p = item.parentNode ;
+ var con = item.innerHTML ;
+ var sp = document.createElement( 'a' ) ;
+ sp.className = 'aref' ;
+ sp.setAttribute('title', con);
+ sp.innerHTML = '@'+con ;
+ p.replaceChild(sp, item) ;
+ }
+ // local datatype references
+ refs = document.querySelectorAll('ldtref') ;
+ for (var i = 0; i < refs.length; i++) {
+ var item = refs[i];
+ if (!item) continue ;
+ var p = item.parentNode ;
+ var con = item.innerHTML ;
+ var ref = item.getAttribute('title') ;
+ if (!ref) {
+ ref = item.textContent ;
+ }
+ if (ref) {
+ ref = ref.replace(/\s+/g, '_') ;
+ }
+ var sp = document.createElement( 'a' ) ;
+ sp.className = 'datatype idlType';
+ sp.title = ref ;
+ sp.setAttribute('href', '#idl-def-' + ref);
+ sp.innerHTML = '<code>' + con + '</code>';
+ p.replaceChild(sp, item) ;
+ }
+ // external datatype references
+ refs = document.querySelectorAll('dtref') ;
+ for (var i = 0; i < refs.length; i++) {
+ var item = refs[i];
+ if (!item) continue ;
+ var p = item.parentNode ;
+ var con = item.innerHTML ;
+ var ref = item.getAttribute('title') ;
+ if (!ref) {
+ ref = item.textContent ;
+ }
+ if (ref) {
+ ref = ref.replace(/\s+/g, '_') ;
+ }
+ var sp = document.createElement( 'a' ) ;
+ sp.className = 'externalDFN';
+ sp.title = ref ;
+ sp.innerHTML = con ;
+ p.replaceChild(sp, item) ;
+ }
+ // now do terms
+ refs = document.querySelectorAll('tdef') ;
+ var tdefs = [];
+ for (var i = 0; i < refs.length; i++) {
+ var item = refs[i];
+ if (!item) continue ;
+ var p = item.parentNode ;
+ var con = item.innerHTML ;
+ var ref = item.getAttribute('title') ;
+ if (!ref) {
+ ref = item.textContent ;
+ }
+ if (ref) {
+ ref = ref.replace(/\s+/g, '_').toLowerCase() ;
+ }
+
+ if ( tdefs[ref]) {
+ throw "Duplicate definition of term '" + ref + "'" ;
+ }
+
+ var sp = document.createElement( 'dfn' ) ;
+ tdefs[ref] = sp ;
+ sp.title = ref ;
+ sp.innerHTML = con ;
+ p.replaceChild(sp, item) ;
+ }
+ // now term references
+ refs = document.querySelectorAll('tref') ;
+ for (var i = 0; i < refs.length; i++) {
+ var item = refs[i];
+ if (!item) continue ;
+ var p = item.parentNode ;
+ var con = item.innerHTML ;
+ var ref = item.getAttribute('title') ;
+ if (!ref) {
+ ref = item.textContent ;
+ }
+ if (ref) {
+ ref = ref.replace(/\s+/g, '_').toLowerCase() ;
+ }
+
+ if ( !tdefs[ref]) {
+ throw "Reference to undefined term '" + ref + "'" ;
+ }
+ var sp = document.createElement( 'a' ) ;
+ var id = item.textContent ;
+ sp.className = 'tref' ;
+ sp.title = ref ;
+ sp.innerHTML = con ;
+ p.replaceChild(sp, item) ;
+ }
+ }
+ } ;
+
+
+ var respecConfig = {
+ doRDFa: "1.1",
+ // specification status (e.g. WD, LCWD, NOTE, etc.). If in doubt use ED.
+ specStatus: "FPWD",
+ publishDate: "2012-07-12",
+ copyrightStart: "2010",
+
+ // the specification's short name, as in http://www.w3.org/TR/short-name/
+ shortName: "json-ld-api",
+ subtitle: "An Application Programming Interface for the JSON-LD Syntax",
+ // if you wish the publication date to be other than today, set this
+ // publishDate: "2009-08-06",
+
+ // if there is a previously published draft, uncomment this and set its YYYY-MM-DD date
+ // and its maturity status
+ previousPublishDate: "2012-06-26",
+ previousMaturity: "CG-FINAL",
+ previousDiffURI: "http://json-ld.org/spec/ED/json-ld-api/20120626/",
+ diffTool: "http://www.aptest.com/standards/htmldiff/htmldiff.pl",
+
+ // if there a publicly available Editor's Draft, this is the link
+ edDraftURI: "http://dvcs.w3.org/hg/json-ld/raw-file/default/spec/latest/json-ld-api/index.html",
+
+ // if this is a LCWD, uncomment and set the end of its review period
+ // lcEnd: "2009-08-05",
+
+ // if you want to have extra CSS, append them to this list
+ // it is recommended that the respec.css stylesheet be kept
+ // extraCSS: [],
+
+ issueBase: "https://github.com/json-ld/json-ld.org/issues/",
+
+ // editors, add as many as you like
+ // only "name" is required
+ editors: [
+ { name: "Manu Sporny", url: "http://manu.sporny.org/",
+ company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/" },
+ { name: "Gregg Kellogg", url: "http://greggkellogg.net/",
+ company: "Kellogg Associates", companyURL: "http://kellogg-assoc.com/" },
+ { name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
+ company: "Graz University of Technology", companyURL: "http://www.tugraz.at/" }
+ ],
+
+ // authors, add as many as you like.
+ // This is optional, uncomment if you have authors as well as editors.
+ // only "name" is required. Same format as editors.
+
+ authors: [
+ { name: "Dave Longley", url: "http://digitalbazaar.com/",
+ company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/"},
+ { name: "Manu Sporny", url: "http://digitalbazaar.com/",
+ company: "Digital Bazaar", companyURL: "http://digitalbazaar.com/" },
+ { name: "Gregg Kellogg", url: "http://greggkellogg.net/",
+ company: "Kellogg Associates", companyURL: "http://kellogg-assoc.com/" },
+ { name: "Markus Lanthaler", url: "http://www.markus-lanthaler.com/",
+ company: "Graz University of Technology", companyURL: "http://www.tugraz.at/" }
+ ],
+
+ // name of the WG
+ wg: "RDF Working Group",
+
+ // URI of the public WG page
+ wgURI: "http://www.w3.org/2011/rdf-wg/",
+
+ // name (with the @w3c.org) of the public mailing to which comments are due
+ wgPublicList: "public-rdf-comments",
+
+ // URI of the patent status for this WG, for Rec-track documents
+ // !!!! IMPORTANT !!!!
+ // This is important for Rec-track documents, do not copy a patent URI from a random
+ // document unless you know what you're doing. If in doubt ask your friendly neighbourhood
+ // Team Contact.
+ wgPatentURI: "http://www.w3.org/2004/01/pp-impl/46168/status",
+ maxTocLevel: 4,
+ preProcess: [ preProc ],
+ alternateFormats: [ {uri: "diff-20120626.html", label: "diff to previous version"} ],
+ };
+
+ function _esc(s) {
+ s = s.replace(/&/g,'&');
+ s = s.replace(/>/g,'>');
+ s = s.replace(/"/g,'"');
+ s = s.replace(/</g,'<');
+ return s;
+ }
+
+ function updateExample(doc, content) {
+ // perform transformations to make it render and prettier
+ content = content.replace(/<!--/, '');
+ content = content.replace(/-->/, '');
+ content = _esc(content);
+ content = content.replace(/\*\*\*\*([^*]*)\*\*\*\*/g, '<span class="diff">$1</span>') ;
+ return content ;
+ }
+//]]>
+ </script>
+<style type="text/css">
+.diff { font-weight:bold; color:#0a3; }
+</style>
+</head>
+
+<body>
+<section id="abstract">
+<p>
+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.
+</p>
+</section>
+
+<section id='sotd'>
+<p>This document has been under development for over 18 months in the
+JSON for Linking Data Community Group. The document has recently been
+transferred to the RDF Working Group for review, improvement, and publication
+along the Recommendation track. While this is a First Public Working Draft
+publication, the specification has undergone significant development, review,
+and changes during the course of the last 18 months and is more mature than
+the First Public Working Draft status implies.
+</p>
+<p>
+There are currently
+<a href="http://json-ld.org/#impl">five interoperable implementations</a>
+of this specification. There is
+a <a href="https://github.com/json-ld/json-ld.org/tree/master/test-suite">fairly complete test suite</a>
+and a
+<a href="http://json-ld.org/playground/">live JSON-LD editor</a>
+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.
+</p>
+<p class="issue">
+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.
+</p>
+</section>
+
+<section>
+<h2>Preface</h2>
+
+<p>
+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:
+</p>
+
+<ul>
+ <li>Web authors and developers that want a very detailed view of how
+ a JSON-LD processor and the API operates.</li>
+ <li>Software developers that want to implement processors and APIs for
+ JSON-LD.</li>
+</ul>
+
+<p>
+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]].</p>
+
+<section>
+ <h2>Contributing</h2>
+
+ <p>There are a number of ways that one may participate in the development of
+ this specification:</p>
+
+ <ul>
+ <li>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:
+ <a href="http://lists.w3.org/Archives/Public/public-rdf-comments/">public-rdf-comments@w3.org</a></li>
+
+ <li>Ad-hoc technical discussion primarily occurs on the public community mailing list:
+ <a href="http://lists.w3.org/Archives/Public/public-linked-json/">public-linked-json@w3.org</a></li>
+
+ <li><a href="http://json-ld.org/minutes/">Public JSON-LD Community Group teleconferences</a>
+ are held on Tuesdays at 1500UTC every week.</li>
+
+ <li>RDF Working Group teleconferences are held on Wednesdays at 1500UTC
+ every week. Participation is limited to RDF Working Group members.</li>
+
+ <li>Specification bugs and issues should be reported in the
+ <a href="https://github.com/json-ld/json-ld.org/issues">issue tracker</a>
+ if you do not want to send an e-mail to the public-rdf-comments mailing
+ list.</li>
+
+ <li><a href="https://github.com/json-ld/json-ld.org/tree/master/spec">Source code</a>
+ for the specification can be found on Github.</li>
+
+ <li>The <a href="http://webchat.freenode.net/?channels=json-ld">#json-ld</a>
+ IRC channel is available for real-time discussion on irc.freenode.net.</li>
+ </ul>
+
+</section>
+
+</section>
+
+<section>
+<h1>Introduction</h1>
+
+<p>
+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.
+</p>
+
+<p>
+There are three major types of transformation that are discussed in this
+document; compaction, expansion, and RDF conversion.
+</p>
+
+<section>
+ <h2>Expansion</h2>
+ <p>
+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 <tref>term</tref>s and is fairly
+compact:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+var input1 = {
+ "@context": "http://json-ld.org/contexts/person.jsonld"
+ "name": "Manu Sporny",
+ "homepage": "http://manu.sporny.org/"
+}
+ </pre>
+
+ <p>
+The next input example uses one <tref>IRI</tref> to express a property, but
+leaves the rest of the information untouched.
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+var input2 = {
+ "@context": "http://json-ld.org/contexts/person.jsonld"
+ "****http://xmlns.com/foaf/0.1/name****": "Manu Sporny",
+ "homepage": "http://manu.sporny.org/"
+}
+ </pre>
+
+ <p>
+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.
+<tdef>Expansion</tdef> performs two important operations. The first is to
+expand all values that are <tref>IRI</tref>s to their fully expanded form.
+The second is to express all values in <tdef>expanded form</tdef>. To
+transform both inputs above to the same representation, the developer could
+do the following:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+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);
+ </pre>
+
+ <p>
+The output for both calls above will be:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+[{
+ "http://xmlns.com/foaf/0.1/name": [{
+ "@value": "Manu Sporny"
+ }],
+ "http://xmlns.com/foaf/0.1/homepage": [{
+ "@id": "http://manu.sporny.org/"
+ }]
+}]
+ </pre>
+
+ <p>
+Note that in the example above; all <tref>context</tref> definitions have
+been removed, all <tref>term</tref> and prefixes have been expanded to full
+IRIs, and all <tref>literal</tref>s are expressed in <tref>expanded form</tref>.
+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.
+ </p>
+</section>
+
+<section>
+ <h2>Compaction</h2>
+ <p>
+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
+read by software developers. Compaction uses a developer-supplied
+<tref>context</tref> to compresses all <tref>IRI</tref>s to <tref>term</tref>s
+or <tref>prefix</tref>es, and compacts all <tref>literal</tref>s expressed
+in <tref>expanded form</tref> as much as possible.
+ </p>
+
+ <p>
+The following example expresses input that has already been fully expanded:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+var expandedInput = [{
+ "http://xmlns.com/foaf/0.1/name": [{
+ "@value": "Manu Sporny"
+ }],
+ "http://xmlns.com/foaf/0.1/homepage": [{
+ "@id": "http://manu.sporny.org/"
+ }]
+}]
+ </pre>
+
+ <p>
+A developer that wants to transform the data above into a more human-readable
+form, could do the following using the JSON-LD API:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+function compactionCallback(output) {
+ console.log(output);
+}
+
+jsonld.compact(expandedInput, "http://json-ld.org/contexts/person.jsonld", compactionCallback);
+ </pre>
+
+ <p>
+The following would be the result of the call above:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+{
+ "@context": "http://json-ld.org/contexts/person.jsonld"
+ "name": "Manu Sporny",
+ "homepage": "http://manu.sporny.org/"
+}
+ </pre>
+
+ <p>
+Note that all of the <tref>term</tref>s have been compressed and
+the <tref>context</tref> 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.
+ </p>
+
+</section>
+
+<section>
+ <h3>Conversion to and from RDF</h3>
+ <p>
+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:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+<!--
+var data = "
+<http://manu.sporny.org/about/#manu> <http://xmlns.com/foaf/0.1/name> \"Manu Sporny\" .\n
+<http://manu.sporny.org/about/#manu> <http://xmlns.com/foaf/0.1/homepage> <http://manu.sporny.org/> .";
+-->
+ </pre>
+
+ <p>
+A developer can use the JSON-LD API to transform the markup above into a
+JSON-LD document:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+function conversionCallback(result)
+{
+ console.log("JSON-LD Document: ", result);
+};
+
+jsonld.fromRDF(data, conversionCallback, {"format": "ntriples"});
+ </pre>
+
+ <p>
+The following expanded output would be the result of the call above:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+[{
+ "@id": "http://manu.sporny.org/about/#manu",
+ "http://xmlns.com/foaf/0.1/name": [{
+ "@value": "Manu Sporny"
+ }],
+ "http://xmlns.com/foaf/0.1/homepage": [{
+ "@id": "http://manu.sporny.org/"
+ }]
+}]
+ </pre>
+
+ <p>
+Note that the output above, could easily be compacted to produce the following
+using the technique outlined in the previous section:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+{
+ "@context": "http://json-ld.org/contexts/person.jsonld",
+ "@id": "http://manu.sporny.org/about/#manu",
+ "name": "Manu Sporny",
+ "homepage": "http://manu.sporny.org/"
+}
+ </pre>
+
+ <p>
+Transforming the object above back to RDF is as simple as calling the
+<code>toRDF()</code> method:
+ </p>
+
+ <pre class="example" data-transform="updateExample">
+var jsonldDocument = ...; // assign the JSON-LD document here
+
+function rdfCallback(quads)
+{
+ console.log("RDF Data: ", quads);
+};
+
+jsonld.toRDF(jsonldDocument, rdfCallback);
+ </pre>
+
+</section>
+
+<section>
+ <h3>Framing and Normalization</h3>
+ <p class="issue">
+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 <tref>linked data graph</tref>s.
+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.
+ </p>
+</section>
+
+</section>
+
+<section>
+ <h2>The Application Programming Interface</h2>
+
+ <p>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.
+ </p>
+
+<section>
+ <h3>General Terminology</h3>
+
+ <p class="issue">
+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.
+ </p>
+
+ <p>
+The following is an explanation of the general terminology used in this
+document:
+ </p>
+
+ <dl>
+ <dt><tdef>JSON object</tdef></dt><dd>
+ An object structure is represented as a pair of curly brackets surrounding zero or
+ more name-value pairs. A name is a <tref>string</tref>. 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.
+ </dd>
+ <dt><tdef>array</tdef></dt>
+ <dd>
+ An array is represented as square brackets surrounding zero or more
+ values that are separated by commas.
+ </dd>
+ <dt><tdef>string</tdef></dt><dd>
+ 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.
+ </dd>
+ <dt><tdef>number</tdef></dt>
+ <dd>
+ 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.</dd>
+ <dt><tdef>true</tdef> and <tdef>false</tdef></dt><dd>
+ Values that are used to express one of two possible boolean states.
+ </dd>
+ <dt><tdef>null</tdef></dt><dd>
+ 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 <em>null</em>. If <code>@value</code>,
+ <code>@list</code>, or <code>@set</code> is set to <em>null</em> in
+ expanded form, then the entire JSON object is ignored. If
+ <code>@context</code> is set to <em>null</em>, the
+ <tref>active context</tref> is reset and when used
+ within a <tref>context</tref>, it removes any definition associated
+ with the key, unless otherwise specified.
+ </dd>
+ <dt><tdef>subject definition</tdef></dt><dd>
+ A <tref>JSON object</tref> used to represent a <tref>subject</tref> and
+ one or more properties of that subject. A <tref>JSON object</tref> is a
+ subject definition if it does not contain they keys <code>@value</code>,
+ <code>@list</code> or <code>@set</code> and it has one or more keys
+ other than <code>@id</code>.</dd>
+ <dt><tdef>subject reference</tdef></dt><dd>
+ A <tref>JSON object</tref> used to reference a subject having only the
+ <code>@id</code> key.</dd>
+ <dt><tdef>Linked Data</tdef></dt>
+ <dd>A set of documents, each containing a representation of a
+ <tref>linked data graph</tref>.</dd>
+ <dt><tdef>linked data graph</tdef> or <tdef>dataset</tdef></dt>
+ <dd>An unordered labeled directed graph, where <tref>node</tref>s are
+ <tref>subject</tref>s or <tref>object</tref>s, and edges are
+ properties.</dd>
+ <dt><tdef>node</tdef></dt>
+ <dd>A piece of information that is represented in a
+ <tref>linked data graph</tref>.</dd>
+ <dt><tdef>named graph</tdef></dt>
+ <dd>A <tref>linked data graph</tref> that has one or more
+ <tref>IRI</tref> that are used to refer to it.</dd>
+ <dt><tdef>graph name</tdef></dt>
+ <dd>An <tref>IRI</tref> that is a reference to a
+ <tref>named graph</tref>.</dd>
+ <dt><tdef>default graph</tdef></dt>
+ <dd>When executing an algorithm, the graph where data should be placed
+ if a <tref>named graph</tref> is not specified.</dd>
+ <dt><tdef>subject</tdef></dt>
+ <dd>Any node in a <tref>linked data graph</tref> with at least one
+ outgoing edge.</dd>
+ <dt><tdef><abbr title="Internationalized Resource Identifier">IRI</abbr></tdef></dt>
+ <dd>An Internationalized Resource Identifier as described in [[!RFC3987]].</dd>
+ <dt><tdef>object</tdef></dt>
+ <dd>A node in a <tref>linked data graph</tref> with at least one
+ incoming edge.</dd>
+ <dt><tdef>property</tdef></dt>
+ <dd>An edge of the <tref>linked data graph</tref>.</dd>
+ <dt><tdef>literal</tdef></dt>
+ <dd>An <tref>object</tref> with a label that is not an
+ <tref>IRI</tref>.</dd>
+ <dt><tdef>quad</tdef></dt>
+ <dd>A piece of information that contains four items; a
+ <tref>subject</tref>, a <tref>property</tref>, a <tref>object</tref>,
+ and a <tref>graph name</tref>.</dd>
+ <dt><tdef>context</tdef></dt>
+ <dd>A <tref>JSON object</tref> that contains rules for interpreting a
+ JSON-LD document.</dd>
+ <dt><tdef>keyword</tdef></dt>
+ <dd>A JSON key that is specific to JSON-LD, specified in the JSON-LD
+ Syntax specification [[!JSON-LD]] in the section titled
+ <a href="http://sites.local/json-ld.org/spec/latest/json-ld-syntax/#syntax-tokens-and-keywords">Syntax Tokens and Keywords</a>.</dd>
+ </dl>
+ </section>
+
+ <section>
+ <h3>JsonLdProcessor</h3>
+
+ <p>The JSON-LD processor interface is the high-level programming structure that developers
+ use to access the JSON-LD transformation methods.</p>
+
+ <p class="note">The JSON-LD API signatures are the same across all programming languages. Due
+ to the fact that asynchronous programming is uncommon in certain languages, developers MAY
+ implement processor with a synchronous interface instead. In that case, the <code>callback</code>
+ parameter MUST NOT be included and the result MUST be returned as return value instead.</p>
+
+ <dl title="[NoInterfaceObject] interface JsonLdProcessor" class="idl">
+
+ <dt>void expand()</dt>
+ <dd>
+ <a href="#expansion">Expands</a> the given <code>input</code> according to
+ the steps in the <a href="#expansion-algorithm">Expansion Algorithm</a>. The
+ <code>input</code> MUST be copied, expanded and returned if there are
+ no errors. If the expansion fails, an appropriate exception MUST be thrown.
+
+ <dl class="parameters">
+ <dt>object or object[] or IRI input</dt>
+ <dd>The JSON-LD object or array of JSON-LD objects to perform the expansion upon or an
+ <tref>IRI</tref> referencing the JSON-LD document to expand.</dd>
+ <dt>object or IRI? context</dt>
+ <dd>An optional external context to use additionally to the context embedded in
+ <code>input</code> when expanding the <code>input</code>.</dd>
+ <dt>JsonLdCallback callback</dt>
+ <dd>A callback that is called when processing is complete on
+ the given <code>input</code>.</dd>
+ <dt>optional JsonLdOptions options</dt>
+ <dd>A set of options that MAY affect the expansion algorithm such as, e.g., the
+ input document's base <tref>IRI</tref>.</dd>
+ </dl>
+
+ <dl class="exception" title="InvalidContext">
+ <dt>INVALID_SYNTAX</dt>
+ <dd>A general syntax error was detected in the <code>@context</code>.
+ For example, if a <code>@type</code> key maps to anything other than
+ <code>@id</code> or an <tref>absolute IRI</tref>, this exception would be raised.</dd>
+ <dt>LOAD_ERROR</dt>
+ <dd>There was a problem encountered loading a remote context.</dd>
+ </dl>
+
+ <dl class="exception" title="ProcessingError">
+ <dt>LIST_OF_LISTS_DETECTED</dt>
+ <dd>A list of lists was detected. This is not supported in this
+ version of JSON-LD.</dd>
+ </dl>
+ </dd>
+
+ <dt>void compact()</dt>
+ <dd>
+ <a href="#compaction">Compacts</a> the given <code>input</code> using the
+ <code>context</code> according to the steps in the
+ <a href="#compaction-algorithm">Compaction Algorithm</a>. The
+ <code>input</code> MUST be copied, compacted and returned if there are
+ no errors. If the compaction fails, an appropriate exception MUST be
+ thrown.
+
+ <dl class="parameters">
+ <dt>object or object[] or IRI input</dt>
+ <dd>The JSON-LD object or array of JSON-LD objects to perform the compaction upon or an
+ <tref>IRI</tref> referencing the JSON-LD document to compact.</dd>
+ <dt>object or IRI context</dt>
+ <dd>The context to use when compacting the <code>input</code>; either in the
+ form of an <tref>JSON object</tref> or as <tref>IRI</tref>.</dd>
+ <dt>JsonLdCallback callback</dt>
+ <dd>A callback that is called when processing is complete on
+ the given <code>input</code>.</dd>
+ <dt>optional JsonLdOptions options</dt>
+ <dd>A set of options that MAY affect the expansion algorithm such as, e.g., the
+ input document's base <tref>IRI</tref>. This also includes <code>optimize</code>,
+ which if set will cause processor-specific optimization.</dd>
+ </dl>
+
+ <dl class="exception" title="InvalidContext">
+ <dt>INVALID_SYNTAX</dt>
+ <dd>A general syntax error was detected in the <code>@context</code>.
+ For example, if a <code>@type</code> key maps to anything other than
+ <code>@id</code> or an <tref>absolute IRI</tref>, this exception would be raised.</dd>
+ <dt>LOAD_ERROR</dt>
+ <dd>There was a problem encountered loading a remote context.</dd>
+ </dl>
+
+ <dl class="exception" title="ProcessingError">
+ <dt>LOSSY_COMPACTION</dt>
+ <dd>The compaction would lead to a loss of information, such as a
+ <code>@language</code> value.</dd>
+ <dt>CONFLICTING_DATATYPES</dt>
+ <dd>The target datatype specified in the coercion rule and the
+ datatype for the typed literal do not match.</dd>
+ <dt>LIST_OF_LISTS_DETECTED</dt>
+ <dd>A list of lists was detected. This is not supported in this
+ version of JSON-LD.</dd>
+ </dl>
+ </dd>
+
+ <dt>void fromRDF()</dt>
+ <dd>Creates a JSON-LD document given an set of <ldtref title="quad">Quads</ldtref>.
+ <dl class="parameters">
+ <dt>Quad[] input</dt>
+ <dd>A <tref>dataset</tref> represented as an array of <ldtref title="quad">Quads</ldtref>.</dd>
+ <dt>JsonLdCallback callback</dt>
+ <dd>A callback that is called when processing is complete on
+ the given <code>input</code>.</dd>
+ <dt>optional JsonLdOptions options</dt>
+ <dd>A set of options that will affect the algorithm. This includes <code>notType</code>,
+ which if set to <tref>true</tref> causes the resulting document to use <code>rdf:type</code>
+ as a property, instead of <code>@type</code>.</dd>
+ </dl>
+ </dd>
+
+ <dt>void toRDF()</dt>
+ <dd>
+ Processes the <code>input</code> according to the
+ <a href="#convert-to-rdf-algorithm">Convert to RDF Algorithm</a>, calling
+ the provided <code>callback</code> for each <ldtref>Quad</ldtref> generated.
+ <dl class="parameters">
+ <dt>object or object[] or IRI input</dt>
+ <dd>The JSON-LD object or array of JSON-LD objects to convert to RDF or a <a>IRI</a>
+ referencing the JSON-LD document to convert to RDF.</dd>
+ <dt>QuadCallback callback</dt>
+ <dd>A callback that is called when a <ldtref>Quad</ldtref> is created from processing
+ the given <code>input</code>.
+ </dd>
+ <dt>optional JsonLdOptions options</dt>
+ <dd>A set of options that MAY affect the conversion to RDF such as, e.g.,
+ the input document's base <tref>IRI</tref>.</dd>
+ </dl>
+
+ <dl class="exception" title="InvalidContext">
+ <dt>INVALID_SYNTAX</dt>
+ <dd>A general syntax error was detected in the <code>@context</code>.
+ For example, if a <code>@type</code> key maps to anything other than
+ <code>@id</code> or an <tref>absolute IRI</tref>, this exception would be raised.</dd>
+ <dt>LOAD_ERROR</dt>
+ <dd>There was a problem encountered loading a remote context.</dd>
+ </dl>
+
+ <dl class="exception" title="ProcessingError">
+ <dt>LIST_OF_LISTS_DETECTED</dt>
+ <dd>A list of lists was detected. This is not supported in this
+ version of JSON-LD.</dd>
+ </dl>
+
+ </dd>
+
+ </dl>
+
+ </section>
+
+ <section>
+ <h3>Callbacks</h3>
+ <section>
+ <h3>JsonLdCallback</h3>
+ <p>The <a>JsonLdCallback</a> is used to return a processed JSON-LD representation
+ as the result of processing an API method.</p>
+
+ <dl title="[NoInterfaceObject Callback] interface JsonLdCallback"
+ class="idl">
+
+ <dt>void jsonLd()</dt>
+ <dd>This callback is invoked when processing is complete.
+ <dl class="parameters">
+ <dt>object or object[] jsonld</dt>
+ <dd>The processed JSON-LD document.</dd>
+ </dl>
+ </dd>
+ </dl>
+ </section>
+ <section>
+ <h3>QuadCallback</h3>
+ <p>The <a>QuadCallback</a> is called whenever the processor generates a
+ quad during the <code>quad()</code> call.</p>
+
+ <dl title="[NoInterfaceObject Callback] interface QuadCallback"
+ class="idl">
+
+ <dt>void quad()</dt>
+ <dd>This callback is invoked whenever a quad is generated by the processor.
+ <dl class="parameters">
+ <dt>Quad quad</dt>
+ <dd>The quad.</dd>
+ </dl>
+ </dd>
+ </dl>
+ </section>
+ </section>
+
+ <section>
+ <h3>Data Structures</h3>
+ <p>This section describes datatype definitions used within the JSON-LD API.</p>
+
+ <section>
+ <h3>IRI</h3>
+ <p>The <a>IRI</a> datatype is a string representation of an <tref>IRI</tref>.</p>
+ <div title="typedef DOMString IRI" class="idl">
+ This datatype indicates that the <em>string</em> is interpreted as an Internationalized
+ Resource Identifier [[!RFC3987]] identifying a document, which when parsed as JSON yields
+ either a <tref>JSON object</tref> or <tref>array</tref>.
+ </div>
+ </section>
+
+ <section>
+ <h3>JsonLdOptions</h3>
+ <p>The <a>JsonLdOptions</a> type is used to pass various options to the <a>JsonLdProcessor</a> methods.</p>
+ <dl title="dictionary JsonLdOptions" class="idl">
+ <dt>IRI? base</dt>
+ <dd>The Base IRI to use when expanding the document. This overrides the value of
+ <em>input</em> if it is a <a>IRI</a>. If not specified and <em>input</em> is not
+ an <a>IRI</a>, the base IRI defaults to the current document IRI if in a browser context,
+ or the empty string if there is no document context.</dd>
+ <dt>boolean optimize = false</dt>
+ <dd>If set to <code>true</code>, the JSON-LD processor is allowed to
+ optimize the output of the <a href="#compaction-algorithm">Compaction Algorithm</a>
+ 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.<br>
+ The default value is <code>false</code>.</dd>
+ <dt>boolean useRdfType = false</dt>
+ <dd>If set to <code>true</code>, the JSON-LD processor will will use the
+ expanded <code>rdf:type</code> IRI as the property instead of
+ <code>@type</code> when converting <a>fromRDF</a>.<br>
+ The default value is <code>false</code>.</dd>
+ </dl>
+ </section>
+
+ <p>The following data structures are used for representing data about
+ RDF quads. They are used for normalization, <a>fromRDF</a>,
+ and from <a>toRDF</a> interfaces.
+ </p>
+
+ <section>
+ <h3>Quad</h3>
+ <p>The <a>Quad</a> interface represents an RDF Quad.
+ See [[!RDF-CONCEPTS]] definition for
+ <cite><a href="http://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple">RDF triple</a></cite>,
+ which most closely aligns to <a>Quad</a>.
+ </p>
+ <dl title="[NoInterfaceObject] interface Quad" class="idl">
+ <dt>readonly attribute Node subject</dt>
+ <dd>The <tref>subject</tref> associated with the <a>Quad</a>.</dd>
+ <dt>readonly attribute Node predicate</dt>
+ <dd>The predicate associated with the <a>Quad</a>.
+ Within JSON-LD, an <tdef>RDF predicate</tdef> is refered to as a
+ <tref>property</tref></dd>
+ <dt>readonly attribute Node object</dt>
+ <dd>The <tref>object</tref> associated with the <a>Quad</a>.</dd>
+ <dt>readonly attribute Node? graphName</dt>
+ <dd>If present, the name associated with the <a>Quad</a> identifying
+ it as a member of a <tref>named graph</tref>. If it is missing, the quad
+ is a member of the <tref>default graph</tref>.
+ <div class="issue" data-number="125">This element is at risk, and may be removed.</div>
+ </dd>
+ </dl>
+ </section>
+
+ <section>
+ <h3>Node</h3>
+ <p><ldtref>Node</ldtref> is the base class of <ldtref>IRI</ldtref>,
+ <ldtref>BlankNode</ldtref>, and <ldtref>Literal</ldtref>. It is the IDL
+ representation of a <tref>linked data graph</tref> <tref>node</tref>.</p>
+ <dl title="[NoInterfaceObject] interface Node" class="idl">
+ </dl>
+ </section>
+
+ <section>
+ <h3>IRI</h3>
+ <p>A <tref>node</tref> that is an <tref>IRI</tref>.</p>
+ <dl title="[NoInterfaceObject] interface IRI : Node"
+ class="idl">
+ <dt>readonly attribute DOMString value</dt>
+ <dd>The IRI identifier of the <tref>node</tref> as a [[UNICODE]] string.</dd>
+ </dl>
+ </section>
+
+ <section>
+ <h3><tdef>Blank Node</tdef></h3>
+
+ <p>A <tref>node</tref> in the <tref>linked data graph</tref> 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 <tref>linked data graph</tref>.
+ A blank node is assigned an identifier starting
+ with the prefix <code>_:</code> and an implementation dependent,
+ auto-generated suffix that is unique to all information associated with the
+ particular blank node.
+ </p>
+
+ <dl title="[NoInterfaceObject] interface BlankNode : Node" class="idl">
+ <dt>readonly attribute DOMString identifier</dt>
+ <dd>The temporary identifier of the <tref>blank node</tref>.
+ The <code>identifier</code> MUST NOT be relied upon in any way between two
+ separate processing runs of the same document or with a different document.</dd>
+ </dl>
+
+ <p class="note">Developers and authors must not assume that the
+ value of a <tref>blank node</tref> will remain the same between two
+ processing runs. <a>BlankNode</a> values are only valid for the
+ most recent processing run on the document. <a>BlankNode</a>
+ values will often be generated differently by different processors.</p>
+
+ <p class="note">Implementers MUST ensure that <a>BlankNode</a> values are unique
+ within the current environment, two <ldtref
+ title="blanknode">BlankNodes</ldtref> are considered equal if, and only
+ if, their values are strictly equal.</p>
+ </section>
+
+ <section>
+ <h3>Literal</h3>
+ <p>Literals represent values such as numbers, dates and strings in
+ RDF data. A <ldtref>Literal</ldtref> is comprised of three attributes:
+ </p>
+
+ <ul>
+ <li>a lexical form of the <code>value</code></li>
+ <li>an optional <code>language</code> tag</li>
+ <li>a <code>datatype</code> specified by an <ldtref>IRI</ldtref></li>
+ </ul>
+
+ <p>Literals representing plain text in a natural language may have a
+ <code>language</code> tag specified by a string token, as specified in
+ [[!BCP47]], normalized to lowercase
+ (e.g., <code>'en'</code>, <code>'fr'</code>, <code>'en-gb'</code>).
+ They also have a datatype attribute such as <code>xsd:string</code>.
+ If unspecified, the <code>datatype</code> defaults to <code>xsd:string</code>.
+ </p>
+
+ <p>Literals representing values with a specific datatype, such as
+ the integer 72, may have a <code>datatype</code> attribute specified in the form
+ of a <a>IRI</a> (e.g.,
+ <code>xsd:integer</code>).</p>
+
+ <p> See[[!RDF-CONCEPTS]] definition for
+ <cite><a href="http://www.w3.org/TR/rdf11-concepts/#dfn-literal">literal</a></cite>.</p>
+
+ <dl title="[NoInterfaceObject] interface Literal : Node" class="idl">
+ <dt>readonly attribute DOMString value</dt>
+ <dd>The lexical form of the Literal's value.</dd>
+ <dt>readonly attribute DOMString? language</dt>
+ <dd>An optional language tag as defined in [[!BCP47]], normalized to lowercase.</dd>
+ <dt>readonly attribute IRI? datatype</dt>
+ <dd>An optional datatype identified by a IRI.</dd>
+ </dl>
+ </section>
+ </section>
+
+</section>
+
+<section>
+<h1>Algorithms</h1>
+
+<p>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.</p>
+
+<section>
+ <h2>Algorithm Terms</h2>
+ <dl>
+ <dt><tdef>active subject</tdef></dt>
+ <dd>
+ the currently active subject that the processor should use when
+ processing.
+ </dd>
+ <dt><tdef>active property</tdef></dt>
+ <dd>
+ 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 <tref>active context</tref>.
+ </dd>
+ <dt><tdef>active object</tdef></dt>
+ <dd>
+ the currently active object that the processor should use when
+ processing.
+ </dd>
+ <dt><tdef>active context</tdef></dt>
+ <dd>
+ a context that is used to resolve <tref>term</tref>s while the processing
+ algorithm is running. The <tref>active context</tref> is the context
+ contained within the <tref>processor state</tref>.
+ </dd>
+ <dt><tdef>compact IRI</tdef></dt>
+ <dd>
+ a compact IRI is has the form of <tref>prefix</tref> and <em>suffix</em> and is used as a way
+ of expressing an IRI without needing to define separate <tref>term</tref> definitions for
+ each IRI contained within a common vocabulary identified by <tref>prefix</tref>.
+ </dd>
+ <dt><tdef>local context</tdef></dt>
+ <dd>
+ a context that is specified within a <tref>JSON object</tref>,
+ specified via the <code>@context</code> <tref>keyword</tref>.
+ </dd>
+ <dt><tdef>processor state</tdef></dt>
+ <dd>
+ the <tref>processor state</tref>, which includes the <tref>active
+ context</tref>, <tref>active subject</tref>, and
+ <tref>active property</tref>. The <tref>processor state</tref> is managed
+ as a stack with elements from the previous <tref>processor state</tref>
+ copied into a new <tref>processor state</tref> when entering a new
+ <tref>JSON object</tref>.
+ </dd>
+ <dt><tdef>JSON-LD input</tdef></dt>
+ <dd>
+ The JSON-LD data structure that is provided as input to the algorithm.
+ </dd>
+ <dt><tdef>JSON-LD output</tdef></dt>
+ <dd>
+ The JSON-LD data structure that is produced as output by the algorithm.
+ </dd>
+ <dt><tdef>term</tdef></dt><dd>
+ A <tref>term</tref> is a short word defined in a context that MAY be expanded to an <tref>IRI</tref>
+ </dd>
+ <dt><tdef>prefix</tdef></dt><dd>
+ A <tref>prefix</tref> is a <tref>term</tref> that expands to a vocabulary base IRI. It
+ is typically used along with a <em>suffix</em> to form a <tref>compact IRI</tref> to create an IRI
+ within a vocabulary.
+ </dd>
+ <dt><tdef>language-tagged literal</tdef></dt><dd>
+ A <tref>language-tagged literal</tref> is a <tref>literal</tref> without a datatype, including
+ a language.
+ See <cite><a href="http://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-literal">languaged-tagged literal</a></cite> in [[!RDF-CONCEPTS]].
+ </dd>
+ <dt><tdef>typed literal</tdef></dt><dd>
+ A <tref>typed literal</tref> is a <tref>literal</tref> with an associated <tref>IRI</tref>
+ which indicates the literal's datatype.
+ See <cite><a href="http://www.w3.org/TR/rdf11-concepts/#dfn-typed-literal">languaged-tagged literal</a></cite> in [[!RDF-CONCEPTS]].
+ </dd>
+ </dl>
+</section>
+
+<section>
+ <h2 id="context">Context Processing</h2>
+ <p>Processing of JSON-LD data structure is managed recursively.
+ During processing, each rule is applied using information provided by the <tref>active context</tref>.
+ Processing begins by pushing a new <tref>processor state</tref> onto the <tref>processor state</tref> stack.
+ If a <tref>local context</tref> is encountered, information from the <tref>local context</tref> is merged
+ into the <tref>active context</tref>.</p>
+ <p>The <tref>active context</tref> is used for expanding properties and values of a <tref>JSON object</tref> (or elements
+ of an array) using a <tdef>term mapping</tdef>. It is also used to maintain
+ <tdef>coercion mapping</tdef>s from terms to datatypes, <tdef>language mapping</tdef>s from terms to language codes,
+ and <tdef>list mapping</tdef>s and <tdef>set mapping</tdef>s 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.</p>
+ <p>A <tref>local context</tref> is identified within a <tref>JSON object</tref> having a <code>@context</code>
+ property with a <tref>string</tref>, <tref>array</tref> or a <tref>JSON object</tref> value.
+ When processing a <tref>local context</tref>, special processing rules apply:</p>
+ <ol class="algorithm">
+ <li>Create a new, empty <tref>local context</tref>.</li>
+ <li>Let <em>context</em> be the value of <code>@context</code>
+ <ol class="algorithm">
+ <li id="process-context">If <em>context</em> equals <tref>null</tref>, clear the <tref>active context</tref>.</li>
+ <li>If <em>context</em> is an <tref>array</tref>, process each element as <em>context</em> in order
+ by starting at <a href="#process-context">Step 2.1</a>.</li>
+ <li>If <em>context</em> is a <tref>string</tref>, it MUST have a lexical form of <tref>absolute IRI</tref>.
+ <ol class="algorithm">
+ <li>Dereference <em>context</em>.</li>
+ <li>If the resulting document is a JSON document, extract the top-level <code>@context</code>
+ element using the JSON Pointer "/@context" as described in [[!JSON-POINTER]]. Set <em>context</em>
+ to the extracted content and process it by starting at <a href="#process-context">Step 2.1</a>.</li>
+ </ol>
+ </li>
+ <li>If <em>context</em> is a <tref>JSON object</tref>, perform the following steps:
+ <ol class="algorithm">
+ <li>If <em>context</em> has a <code>@language</code> property, it MUST have a value of a
+ simple <tref>string</tref> with the lexical form described in [[!BCP47]], or <tref>null</tref>. Add the language to the <tref>local context</tref>.</li>
+ <li>If <em>value</em> has a <code>@vocab</code> key, it MUST have a value of a simple <tref>string</tref>
+ with the lexical form of an <tref>absolute IRI</tref>, or <tref>null</tref>. Add the vocabulary mapping to the <tref>local context</tref>.</li>
+ <li id="object-context">Otherwise, for each property in <em>context</em> perform the following steps:
+ <ol class="algorithm">
+ <li>If the property's value is a simple <tref>string</tref>, determine the IRI mapping value by
+ performing <a href="#iri-expansion">IRI Expansion</a> on the associated value. If the result of the IRI
+ mapping is an <tref>absolute IRI</tref>, merge the property into the <tref>local context</tref>
+ <tref>term mapping</tref>, unless the property is a JSON-LD <tref>keyword</tref>, in which
+ case throw an exception.</li>
+ <li>Otherwise, if the property's value is <tref>null</tref> remove mapping, coercion,
+ container and language information associated with property from the
+ <tref>local context</tref>.</li>
+ <li>Otherwise, the <em>property</em>'s <em>value</em> MUST be a <tref>JSON object</tref>.
+ <ol class="algorithm">
+ <li>If the <em>property</em> is a JSON-LD <tref>keyword</tref> and the value has
+ <code>@id</code>, <code>@language</code> or <code>@type</code> properties, throw an exception.
+ <div class="issue">Undecided if <code>@type</code> or <code>@graph</code> can take a
+ <code>@container</code> with <code>@set</code>.
+ </div>
+ </li>
+ <li>If the <em>property</em> has the form of <tref>term</tref>, its <em>value</em> MUST have an
+ <code>@id</code> property with a string value which MUST have the form of a <tref>term</tref>,
+ <tref>compact IRI</tref>, or <tref>absolute IRI</tref>. Determine the IRI mapping
+ by performing <a href="#iri-expansion">IRI Expansion</a> on the associated value.
+ If the result of the IRI mapping is an <tref>absolute IRI</tref>, merge the
+ <em>property</em> into the <tref>local context</tref> <tref>term mapping</tref>.</li>
+ <li>If the <em>property</em> has the form of of a <tref>compact IRI</tref> or <tref>absolute IRI</tref>,
+ the <em>value</em> MAY have a <code>@id</code> property with a string value which MUST have the
+ form of a <tref>term</tref>, <tref>compact IRI</tref>, or absolute <tref>IRI</tref>.
+ Determine the IRI mapping by performing <a href="#iri-expansion">IRI Expansion</a> on the associated
+ value. If the result of the IRI mapping is an <tref>absolute IRI</tref>, merge the
+ <em>property</em> into the <tref>local context</tref> <tref>term mapping</tref>.</li>
+ <li>If the <em>value</em> has a <code>@type</code> property, its value MUST have the form of a <tref>term</tref>,
+ <tref>compact IRI</tref>, <tref>absolute IRI</tref>, or the <tref>keyword</tref> <code>@id</code>.
+ Determine the IRI by performing <a href="#iri-expansion">IRI Expansion</a> on the associated value.
+ If the result of the IRI mapping is an <tref>absolute IRI</tref> or <code>@id</code>, merge into the
+ <tref>local context</tref> <tref>coercion mapping</tref> using the lexical value of the <em>property</em>.</li>
+ <li>If the <em>value</em> has a <code>@container</code> property, its value MUST be <code>@list</code> or
+ <code>@set</code>. Merge the <tref>list mapping</tref> or <tref>set mapping</tref> into the
+ <tref>local context</tref> using the lexical value of the <em>property</em>.</li>
+ <li>If the <em>value</em> has a <code>@language</code> property but no <code>@type</code> property, the value of the
+ <code>@language</code> property MUST be a <tref>string</tref> or <tref>null</tref>.
+ Merge the <tref>language mapping</tref> into the <tref>local context</tref> using the lexical value of the
+ <em>property</em>.</li>
+ </ol>
+ </li>
+ <li>Merge the <tref>local context</tref> into the <tref>active context</tref>.</li>
+ <li>Repeat <a href="#object-context">Step 2.4.2</a> until no entries are added to the <tref>local
+ context</tref>.</li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ </ol>
+
+ <p class="note">It can be difficult to distinguish between a <tref>compact IRI</tref> and an <tref>absolute IRI</tref>,
+ as a <tref>compact IRI</tref> may seem to be a valid IRI <em>scheme</em>. 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 <a href="#object-context">Step 2.3.2</a> until no changes are made, mappings to IRIs created
+ using an undefined term prefix will eventually resolve to <tref>absolute IRI</tref>s.</p>
+
+ <p class="issue" data-number="43"><a href="https://github.com/json-ld/json-ld.org/issues/43">Issue 43</a>
+ concerns performing IRI expansion in the key position of a context definition.</p>
+</section>
+
+<section>
+ <h2>IRI Expansion</h2>
+ <p>Keys and some values are evaluated to produce an <tref>IRI</tref>. This section defines an algorithm for
+ transforming a value representing an IRI into an actual IRI.</p>
+ <p><tref title="IRI">IRIs</tref> may be represented as an <tref>absolute IRI</tref>, a <tref>term</tref>,
+ a <tref>compact IRI</tref>, or as a value relative to <code>@vocab</code>.</p>
+ <p>An <tdef>absolute IRI</tdef> is defined in [[!RFC3987]] containing a <em>scheme</em> along with
+ <em>path</em> and optional <em>query</em> and fragment segments. A <tdef>relative IRI</tdef> is an IRI
+ that is relative some other <tref>absolute IRI</tref>; in the case of JSON-LD this is the base location
+ of the document.</p>
+
+ <p>The algorithm for generating an IRI is:
+ <ol class="algorithm">
+ <li>If the <tref>active context</tref> contains a <tref>term</tref> mapping for the value using
+ a case-sensitive comparison, use the mapped value as an IRI.</li>
+ <li>Otherwise, split the value into a <em>prefix</em> and <em>suffix</em> from the first occurrence of ':'.</li>
+ <li>If the prefix is a '_' (underscore), the value represents a named <tref>blank node</tref>.</li>
+ <li>If the <tref>active context</tref> contains a <tref>term</tref> mapping for <em>prefix</em> using
+ a case-sensitive comparison, and <em>suffix</em> does not does not begin with '//'
+ (i.e., it does not match a <em>hier-part</em> including
+ <em>authority</em> (as defined in [[!RFC3986]]), generate an <tref>IRI</tref>
+ 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.</li>
+ <li>Otherwise, if the IRI being processed does not contain a colon and is a property, i.e., a key in
+ a <tref>JSON object</tref>, or the value of <code>@type</code> and the active context has a
+ <code>@vocab</code> mapping, join the mapped value to the suffix using textual concatenation.</li>
+ <li>Otherwise, if the IRI being processed does not contain a colon and is not a property, i.e., not a key in a
+ <tref>JSON object</tref> treat it as a <tref>relative IRI</tref> and resolve it against the base IRI as
+ per [[RFC3986]] using only the basic algorithm in section 5.2. Neither <em>Syntax-Based Normalization</em>
+ nor <em>Scheme-Based Normalization</em> (described in sections 6.2.2 and 6.2.3 of [[RFC3986]]) are performed.
+ Characters additionally allowed in IRI references are treated in the same way that unreserved characters are
+ treated in URI references, per section 6.5 of [[RFC3987]].</li>
+ <li>Otherwise, use the value directly as an IRI.</li>
+ </ol>
+ </p>
+</section>
+
+<section>
+ <h2>IRI Compaction</h2>
+ <p>Some keys and values are expressed using <tref>IRI</tref>s. This section defines an
+ algorithm for transforming an IRI (<em>iri</em>) to a <tref>term</tref> or <tref>compact IRI</tref> using the
+ <tref>term</tref>s specified in the <tref>active context</tref> using an optional <em>value</em>.</p>
+
+<section>
+ <h3>IRI Compaction Algorithm</h3>
+ <p>The algorithm for generating a <tref>compact IRI</tref> is:
+ <ol class="algorithm">
+ <li>Create an empty list of terms <em>terms</em> that will be populated with
+ <tref>term</tref>s that are ranked according to how closely they match
+ <em>value</em>. Initialize <em>highest rank</em> to <code>0</code>,
+ and set a flag <em>list container</em> to <code>false</code>.</li>
+ <li>For each <em>term</em> in the <tref>active context</tref>:
+ <ol class="algorithm">
+ <li>If the <em>term</em>'s <tref>IRI</tref> is not a complete match against
+ <em>iri</em>, continue to the next <em>term</em>.</li>
+ <li>If <em>value</em> is a <tref>JSON object</tref> containing only the property <code>@list</code>:
+ <ol class="algorithm">
+ <li>If <em>term</em> has a <code>@container</code> set to <code>@set</code>, continue
+ to the next <em>term</em>.</li>
+ <li>If <em>list container</em> is <code>true</code> and <em>term</em> does not have a
+ <code>container</code> set to <code>@list</code> and <em>value</em> is <tref>null</tref>,
+ continue to the next <em>term</em>.</li>
+ </ol>
+ </li>
+ <li>Otherwise, if <em>term</em> has a <code>container</code> set to <code>@list</code>,
+ continue to the next <em>term</em>.</li>
+ <li>Set <em>rank</em> to the <tref>term rank</tref> of <em>value</em> by passing
+ passing <em>term</em>, <em>value</em>, and <tref>active context</tref> to
+ the <a href="#term-rank-algorithm">Term Rank Algorithm</a>.</li>
+ <li>If <em>rank</em> is greater than <code>0</code>:
+ <ol class="algorithm">
+ <li>If <em>term</em> has a <code>container</code> set to <code>@set</code>, then add
+ <code>1</code> to <em>rank</em>.</li>
+ <li>If <em>value</em> is a <tref>JSON object</tref> containing only the property <code>@list</code>
+ and <em>list container</em> is <code>false</code> and <em>term</em> has a <code>container</code>
+ set to <code>@list</code>, then set <em>list container</em> to <code>true</code>, clear
+ <em>terms</em>, set <em>highest rank</em> to <em>rank</em>, and add <em>term</em> to <em>terms</em>.</li>
+ <li>Otherwise, if <em>rank</em> is greater than or equal to <em>highest rank</em>:
+ <ol class="algorithm">
+ <li>If <em>rank</em> is greater than <em>highest rank</em>, clear <em>terms</em> and set
+ <em>highest rank</em> to <em>rank</em>.</li>
+ <li>Add <em>term</em> to <em>terms</em>.</li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ <li>If <em>terms</em> is empty, and the <tref>active context</tref> has a <code>@vocab</code>
+ which is a prefix of <em>iri</em> where
+ the resulting <tref>relative IRI</tref> is not a <tref>term</tref> in the
+ <tref>active context</tref>. The resulting <tref>relative IRI</tref> is the
+ unmatched part of <em>iri</em>.</li>
+ <li>If <em>terms</em> is empty, add a <tref>compact IRI</tref> representation of <em>iri</em>
+ for each <tref>term</tref> in the <tref>active context</tref> which
+ maps to an <tref>IRI</tref> which is a prefix for <em>iri</em> where
+ the resulting <tref>compact IRI</tref> is not a <tref>term</tref> in the
+ <tref>active context</tref>. The resulting <tref>compact IRI</tref> is the
+ <tref>term</tref> associated with the partially
+ matched IRI in the <tref>active context</tref> concatenated with a
+ colon (:) character and the unmatched part of <em>iri</em>.</li>
+ <li>If <em>terms</em> is empty, the <tref>IRI</tref> being processed is a property or the
+ value of <code>@type</code> and <code>@vocab</code> is not null and matches the beginning
+ of <em>iri</em>, return the unmatched portion of <em>iri</em>. Otherwise return
+ <em>iri</em>.</li>
+ <li>Otherwise, return the shortest and lexicographically least value in <em>terms</em>.</li>
+ </ol>
+ </p>
+</section>
+
+<section>
+<h3>Term Rank Algorithm</h3>
+<p>When selecting among multiple possible terms for a given property, it may be that multiple
+ <tref title="term">terms</tref> are defined with the same <tref>IRI</tref>, but differ in <code>@type</code>, <code>@container</code>
+ or <code>@language</code>. The purpose of this algorithm is to take a <tref>term</tref>
+ and a value and give it a <tdef>term rank</tdef>. The selection can then be based, partly, on
+ the term having the highest <tref>term rank</tref>.</p>
+<p>Given a <tref>term</tref> <em>term</em>, <em>value</em>, and <tref>active context</tref>
+ determine the <tref>term rank</tref> using the following steps:</p>
+<ol class="algorithm">
+ <li>If <em>value</em> is <tref>null</tref>, <tref>term rank</tref> is <code>3</code>.</li>
+ <li>Otherwise, if <em>value</em> is a <tref>JSON object</tref> containing only the property <code>@list</code>:
+ <ol class="algorithm">
+ <li>If the <code>@list</code> property is an empty array, if <em>term</em> has <code>@container</code>
+ set to <code>@list</code>, <tref>term rank</tref> is <code>1</code>, otherwise <code>0</code>.</li>
+ <li>Otherwise, return the sum of the <tref>term rank</tref>s for every entry in the list.</li>
+ </ol>
+ </li>
+ <li>Otherwise, <em>value</em> MUST be a <tref>subject definition</tref>, <tref>subject reference</tref>,
+ or a <tref>JSON object</tref> having a <code>@value</code>.
+ <ol class="algorithm">
+ <li>If <em>value</em> has a <code>@value</code> property:
+ <ol class="algorithm">
+ <li>If <em>value</em> has a <code>@type</code> property matching a
+ <code>@type</code> coercion for <em>term</em>, <tref>term rank</tref>
+ is <code>3</code>, otherwise if <em>term</em> has no <code>@type</code>
+ coercion and no <code>@language</code>, <tref>term rank</tref> is
+ <code>1</code>, otherwise <code>0</code>.</li>
+ <li>Otherwise, if <code>@value</code> is not a <tref>string</tref>, if <em>term</em> has
+ no <code>@type</code> or <code>@language</code> it is <code>2</code>, otherwise <code>1</code>.</li>
+ <li>Otherwise, if <em>value</em> has no <code>@language</code> property, if <em>term</em> has
+ <code>@language</code> <tref>null</tref>, or <em>term</em> has no <code>@type</code> or
+ <code>@language</code> and the <tref>active context</tref> has no <code>@language</code>,
+ <tref>term rank</tref> is <code>3</code>, otherwise <code>0</code>.</li>
+ <li>Otherwise, if <em>value</em> has a <code>@language</code> property matching a
+ <code>@language</code> definition for <em>term</em> (or
+ <em>term</em> has no <code>@type</code> or <code>@language</code> definition and
+ <code>@language</code> in the <tref>active context</tref> matches the
+ <em>value</em> <code>@language</code>), <tref>term rank</tref> is
+ <code>3</code>, otherwise if <em>term</em> has no <code>@type</code>
+ coercion and no <code>@language</code>, <tref>term rank</tref> is
+ <code>1</code>, otherwise <code>0</code>.</li>
+ </ol>
+ </li>
+ <li>Otherwise, if <em>term</em> has <code>@type</code> coerced to <code>@id</code>,
+ <tref>term rank</tref> is <code>3</code>, otherwise
+ if <em>term</em> has no <code>@type</code> coercion and no <code>@language</code>,
+ <tref>term rank</tref> is <code>1</code>, otherwise <code>0</code>.</li>
+ </ol>
+ </li>
+ <li>Return <tref>term rank</tref>.</li>
+</ol>
+</section>
+
+</section>
+
+<section>
+ <h2>Value Expansion</h2>
+ <p>Some values in JSON-LD can be expressed in a compact form. These values
+ are required to be expanded at times when processing JSON-LD documents.</p>
+
+ <p>The algorithm for expanding a <em>value</em> takes an <tref>active property</tref>
+ and <tref>active context</tref>. It is implemented as follows:</p>
+ <ol class="algorithm">
+ <li>If <em>value</em> is <tref>null</tref>, the <em>value</em> is already expanded.</li>
+ <li>If <tref>active property</tref> is <code>@graph</code> or the target of an <code>@id</code> coercion,
+ expand the value into an object with a key-value pair where the key is <code>@id</code> and the value is
+ the expanded IRI according to the <a href="#iri-expansion">IRI Expansion</a> rules.</li>
+ <li>Otherwise, if <tref>active property</tref> is not a <tref>keyword</tref>, then expand <em>value</em> into an
+ object:
+ <ol class="algorithm">
+ <li>Set the first key-value pair to <code>@value</code> and the unexpanded <em>value</em>.</li>
+ <li>If the <tref>active property</tref> is the target of typed literal coercion, set the second key-value pair
+ to <code>@type</code> and the associated coercion datatype expanded according to the
+ <a href="#iri-expansion">IRI Expansion</a> rules.</li>
+ <li>Otherwise, if the <tref>active property</tref> is the target of language tagging, set the second key-value
+ pair to <code>@language</code> and value of the language tagging from the <tref>active context</tref>.</li>
+ </ol>
+ </li>
+ <li>Otherwise, <em>value</em> is already expanded.</li>
+ </ol>
+</section>
+
+<section>
+ <h2>Value Compaction</h2>
+ <p>Some values, such as <tref title="IRI">IRIs</tref> and <tref title="typed literal">typed literals</tref>, may be expressed in an
+ expanded form in JSON-LD. These values are required to be compacted at
+ times when processing JSON-LD documents.
+ </p>
+
+ <p>The algorithm for compacting an expanded value <em>value</em> takes an <tref>active property</tref>
+ and <tref>active context</tref>. It is implemented as follows:</p>
+ <ol class="algorithm">
+ <li>If <em>value</em> only has one property and the <tref>active context</tref> has no default language,
+ then the compacted value is the value of <code>@value</code>.</li>
+ <li>Otherwise, if <tref>active property</tref> is <code>@graph</code>, the compacted value is the
+ value associated with the <code>@id</code> key, processed according to
+ the <a href="#iri-compaction">IRI Compaction</a> steps.</li>
+ <li>Otherwise, if the <tref>active context</tref> contains a coercion target for the
+ key that matches the expression of the value, compact the value using the
+ following steps:
+ <ol class="algorithm">
+ <li>If the coercion target is an <code>@id</code>, the compacted
+ value is the value associated with the <code>@id</code> key,
+ processed according to the
+ <a href="#iri-compaction">IRI Compaction</a> steps.</li>
+ <li>If the coercion target is a <tref>typed literal</tref>, the compacted
+ value is the value associated with the <code>@value</code> key.</li>
+ </ol>
+ </li>
+ <li>Otherwise, if <em>value</em> contains an <code>@id</code> key, the compacted value is <em>value</em> with
+ the value of <code>@id</code> processed according to the
+ <a href="#iri-compaction">IRI Compaction</a> steps.</li>
+ <li>Otherwise, if the <tref>active context</tref> contains a <code>@language</code>, which
+ matches the <code>@language</code> of the value, or the value has only a <code>@value</code> key, the compacted
+ value is the value associated with the <code>@value</code> key.</li>
+ <li>Otherwise, if the value contains a <code>@type</code> key, the compacted value
+ is <em>value</em> with the <code>@type</code> value processed according to the
+ <a href="#iri-compaction">IRI Compaction</a> steps.</li>
+ <li>Otherwise, the value is not modified.</li>
+ </ol>
+</section>
+
+<section>
+<h2>Expansion</h2>
+
+<p>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.</p>
+
+<p>For example, assume the following JSON-LD input document:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+{
+ "@context":
+ {
+ "name": "http://xmlns.com/foaf/0.1/name",
+ "homepage": {
+ "@id": "http://xmlns.com/foaf/0.1/homepage",
+ "@type", "@id"
+ }
+ },
+ "name": "Manu Sporny",
+ "homepage": "http://manu.sporny.org/"
+}
+-->
+</pre>
+
+<p>Running the JSON-LD Expansion algorithm against the JSON-LD input document
+ provided above would result in the following output:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+{
+ "http://xmlns.com/foaf/0.1/name": "Manu Sporny",
+ "http://xmlns.com/foaf/0.1/homepage": {
+ "@id": "http://manu.sporny.org/"
+ }
+}
+-->
+</pre>
+
+<section>
+<h3>Expansion Algorithm</h3>
+
+<p>The algorithm takes three input variables: an <tref>active context</tref>,
+ an <tref>active property</tref>, and an <em>element</em> to be expanded. To
+ begin, the <tref>active context</tref> is set to the result of performing, <a
+ href="#context-processing">Context Processing</a> on the passed
+ <em>context</em>, or empty if <em>context</em> is <tref>null</tref>,
+ <tref>active property</tref> is set to <tref>null</tref>, and
+ <em>element</em> is set to the <tref>JSON-LD input</tref>.</p>
+<ol class="algorithm">
+ <li>If <em>element</em> is an <tref>array</tref>, process each entry in <em>element</em> recursively
+ using this algorithm, passing copies of the <tref>active context</tref> and <tref>active property</tref>.
+ If has a <code>@container</code> set to <code>@list</code> and any entry in <em>element</em> is an
+ <tref>array</tref>, or is a <tref>JSON object</tref> containing a <code>@list</code> 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 <em>element</em>'s entries.</li>
+ <li>Otherwise, if <em>element</em> is an object
+ <ol class="algorithm">
+ <li>If <em>element</em> has a <code>@context</code> property, update the <tref>active context</tref> according to
+ the steps outlined in <a href="#context-processing">Context Processing</a> and remove the <code>@context</code>
+ property.</li>
+ <li>Then, proceed and process each <em>property</em> and <em>value</em> in <em>element</em> as follows:
+ <ol class="algorithm">
+ <li>Remove <em>property</em> from <em>element</em>, expand
+ <em>property</em> according to the steps outlined in <a href="#iri-expansion">IRI Expansion</a>.
+ Set the <tref>active property</tref> to the original un-expanded <em>property</em> if
+ <em>property</em> is not a <tref>keyword</tref>.</li>
+ <li>If <em>property</em> does not expand to a keyword or an <tref>absolute IRI</tref> (i.e., it doesn't contain a colon),
+ continue with the next property from <em>element</em>.</li>
+ <li>If <em>value</em> is <tref>null</tref> and <em>property</em> is not <code>@value</code>, continue with the next
+ property from <em>element</em>.</li>
+ <li>If the <em>property</em> is <code>@id</code> the <em>value</em> MUST be a <tref>string</tref>.
+ Expand the <em>value</em> according to <a href="#iri-expansion">IRI Expansion</a>.</li>
+ <li>Otherwise, if the <em>property</em> is <code>@type</code>:
+ <ol class="algorithm">
+ <li>If <em>value</em> is a <tref>string</tref>, expand according to <a href="#iri-expansion">IRI Expansion</a>.</li>
+ <li>Otherwise, if <em>value</em> is a <tref>JSON Object</tref>, it must be empty (used for
+ <cite><a href="../json-ld-framing/#framing">Framing</a></cite>).</li>
+ <li>Otherwise, if <em>value</em> is an <tref>array</tref>, all elements must be <tref>string</tref>s.
+ Expand <em>value</em> for each of its entries according to <a href="#iri-expansion">IRI Expansion</a>.</li>
+ </ol>
+ </li>
+ <li>Otherwise, if the <em>property</em> is <code>@value</code> or <code>@language</code> the <em>value</em> MUST NOT be a
+ <tref>JSON object</tref> or an <tref>array</tref>.</li>
+ <li>Otherwise, if the <em>property</em> is <code>@list</code> or <code>@set</code> expand <em>value</em>
+ recursively using this algorithm, passing copies of the <tref>active context</tref> and <em>active property</em>. If the expanded
+ <em>value</em> is not an <tref>array</tref>, convert it to an <tref>array</tref>.
+ If <em>property</em> is <code>@list</code> and any entry in <em>value</em> is a
+ <tref>JSON object</tref> containing an <code>@list</code> property, throw an exception, as
+ lists of lists are not supported.</li>
+ <li>Otherwise, expand <em>value</em> recursively using this algorithm, passing copies of the <tref>active context</tref> and
+ <tref>active property</tref>.</li>
+ <li>If <em>property</em> is not a keyword
+ and <tref>active property</tref> has a <code>@container</code> <code>@list</code>
+ and the expanded <em>value</em> is not <tref>null</tref>,
+ convert <em>value</em> to an <tref>object</tref> with an <code>@list</code> property whose value is
+ set to <em>value</em> (unless <em>value</em> is already in that form).</li>
+ <li>Convert <em>value</em> to <tref>array</tref> form unless <em>value</em> is <tref>null</tref> or <em>property</em> is
+ <code>@id</code>, <code>@type</code>, <code>@value</code>, or <code>@language</code>.</li>
+ <li>If <em>value</em> is not <tref>null</tref>, either merge <em>value</em> into an existing <em>property</em> property of
+ <em>element</em> or create a new <em>property</em> property with <em>value</em> as value.</li>
+ </ol>
+ </li>
+ <li>If the processed <em>element</em> has an <code>@value</code> property
+ <ol class="algorithm">
+ <li><em>element</em> MUST NOT have more than one other property, which can either be <code>@language</code> or <code>@type</code>
+ with a <tref>string</tref> value.</li>
+ <li>if the value of <code>@value</code> equals <tref>null</tref>,
+ replace <em>element</em> with the value of <code>@value</code>.</li>
+ </ol>
+ </li>
+ <li>Otherwise, if <em>element</em> has an <code>@type</code> property and its value is not in the form of an
+ <tref>array</tref>, convert it to an <tref>array</tref>.</li>
+ <li>If <em>element</em> has an <code>@set</code> or <code>@list</code> property, it MUST be the only property.
+ Set <em>element</em> to the value of <code>@set</code>; leave <code>@list</code> untouched.</li>
+ <li>If <em>element</em> has just a <code>@language</code> property, set <em>element</em> to <tref>null</tref>.</li>
+ </ol>
+ </li>
+ <li>Otherwise, expand <em>element</em> according to the <a href="#value-expansion">Value Expansion</a> rules,
+ passing copies of the <tref>active context</tref> and <tref>active property</tref>.</li>
+</ol>
+
+<p>If, after the algorithm outlined above is run, the resulting <em>element</em> is an <tref>JSON object</tref> with just a <code>@graph</code>
+ property, <em>element</em> is set to the value of <code>@graph</code>'s value. Finally, if <em>element</em> is a <tref>JSON object</tref>,
+ it is wrapped into an <tref>array</tref>.</p>
+
+</section>
+
+</section>
+
+<section>
+<h2>Compaction</h2>
+
+<p>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.</p>
+
+<p>For example, assume the following JSON-LD input document:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+{
+ "http://xmlns.com/foaf/0.1/name": "Manu Sporny",
+ "http://xmlns.com/foaf/0.1/homepage": {
+ "@id": "http://manu.sporny.org/"
+ }
+}
+-->
+</pre>
+
+<p>Additionally, assume the following developer-supplied JSON-LD context:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+{
+ "@context": {
+ "name": "http://xmlns.com/foaf/0.1/name",
+ "homepage": {
+ "@id": "http://xmlns.com/foaf/0.1/homepage",
+ "@type": "@id"
+ }
+ }
+}
+-->
+</pre>
+
+<p>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:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+{
+ "@context": {
+ "name": "http://xmlns.com/foaf/0.1/name",
+ "homepage": {
+ "@id": "http://xmlns.com/foaf/0.1/homepage",
+ "@type": "@id"
+ }
+ },
+ "name": "Manu Sporny",
+ "homepage": "http://manu.sporny.org/"
+}
+-->
+</pre>
+
+<p>The compaction algorithm also enables the developer to map any expanded
+ format into an application-specific compacted format. While the context
+ provided above mapped <code>http://xmlns.com/foaf/0.1/name</code> to
+ <strong>name</strong>, it could have also mapped it to any arbitrary string
+ provided by the developer.</p>
+
+<section>
+<h3>Compaction Algorithm</h3>
+
+<p>The algorithm takes three input variables: an <tref>active context</tref>, an <tref>active property</tref>,
+ and an <em>element</em> to be compacted. To begin, the <tref>active context</tref> is
+ set to the result of performing <a href="#context-processing">Context Processing</a> on the passed <em>context</em>,
+ <tref>active property</tref> is set to <tref>null</tref>, and <em>element</em> is set to the result of performing the
+ <a href="#expansion-algorithm">Expansion Algorithm</a> on the <tref>JSON-LD input</tref>. This removes any existing
+ context to allow the given <tref>active context</tref> to be cleanly applied.</p>
+
+<ol class="algorithm">
+ <li>If <em>element</em> is an <tref>array</tref>, process each entry in <em>element</em> recursively
+ using this algorithm, passing a copy of the <tref>active context</tref> and the <tref>active property</tref>.
+ If <em>element</em> has a single item, the compacted value is that item; otherwise the compacted value
+ is <em>element</em>.</li>
+ <li>Otherwise, if <em>element</em> is an object:
+ <ol class="algorithm">
+ <li>If <em>element</em> has an <code>@value</code> property or element is a <tref>subject reference</tref>,
+ return the result of performing
+ <a href="#value-compaction">Value Compaction</a> on <em>element</em> using <tref>active property</tref>.</li>
+ <li>Otherwise, if the <tref>active property</tref> has a <code>@container</code> mapping to <code>@list</code>
+ and <em>element</em> has a corresponding <code>@list</code> property, recursively compact that
+ property's value passing a copy of the <tref>active context</tref> and the <tref>active property</tref> ensuring
+ that the result is an array with all <tref>null</tref> values removed. If there already exists a value for
+ <tref>active property</tref> in <em>element</em> and the full IRI of <em>property</em> is also coerced to
+ <code>@list</code>, throw an exception. Otherwise store the resulting array as value of <tref>active property</tref>
+ if empty or <em>property</em> otherwise.</li>
+ <li>Otherwise, construct <em>output</em> as a new <tref>JSON object</tref> used for returning the result
+ of compacting <em>element</em>. For each <em>property</em> and <em>value</em> in <em>element:</em>
+ <ol class="algorithm">
+ <li>If <em>property</em> is <code>@id</code> or <code>@type</code>
+ <ol class="algorithm">
+ <li>Set <tref>active property</tref> to the result of performing
+ <a href="#iri-compaction">IRI Compaction</a> on <em>property</em>.</li>
+ <li>If <em>value</em> is a <tref>string</tref>, the compacted <em>value</em> is the result of performing
+ <a href="#iri-compaction">IRI Compaction</a> on <em>value</em>.</li>
+ <li>Otherwise, <em>value</em> MUST be an <tref>array</tref>. Perform <a href="#iri-compaction">IRI Compaction</a>
+ on every entry of <em>value</em>. If <em>value</em> contains just one entry, <em>value</em> is set to that entry.</li>
+ <li>Add <tref>active property</tref> and the expanded <em>value</em> to <em>output</em>.</li>
+ </ol>
+ </li>
+ <li>Otherwise, <em>value</em> MUST be an <tref>array</tref>.</li>
+ <li>If <em>value</em> is empty:
+ <ol class="algorithm">
+ <li>Set <tref>active property</tref> to the result of performing
+ <a href="#iri-compaction">IRI Compaction</a> on <em>property</em>.</li>
+ <li>Create an entry in <em>output</em> for <tref>active property</tref> and <em>value</em>.</li>
+ </ol>
+ </li>
+ <li>For each <em>item</em> in <em>value</em>:
+ <ol class="algorithm">
+ <li>Set <tref>active property</tref> to the result of performing <a href="#iri-compaction">IRI Compaction</a>
+ for <em>property</em> and <em>item</em> using the <tref>active context</tref>.</li>
+ <li>Compact <em>item</em> by recursively performing this algorithm passing a copy of
+ the <tref>active context</tref> and the <tref>active property</tref>.</li>
+ <li>If an entry already exists in <em>output</em> for <tref>active property</tref>, convert it
+ to an <tref>array</tref> if necessary, and append the compacted <em>value</em>.</li>
+ <li>Otherwise, if the compacted <em>value</em> is not an <tref>array</tref> and <tref>active property</tref>
+ has a <code>@container</code> mapping to <code>@set</code>,
+ create an entry in <em>output</em> for <tref>active property</tref> and <em>value</em> as an
+ <tref>array</tref>.</li>
+ <li>Otherwise, create an entry in <em>output</em> for <tref>active property</tref> and <em>value</em>.</li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ <li>Otherwise, return <em>element</em> as the compacted <em>element</em>.
+ <div class="issue">Perhaps this should also call <a href="#value-compaction">Value Compaction</a> on
+ native types and strings, which could consolidate potential transformation in one place.</div>
+ </li>
+</ol>
+
+<p>If, after the algorithm outlined above is run, the resulting <em>element</em> is an <tref>array</tref>, put <em>element</em> into the
+ <code>@graph</code> property of a new <tref>JSON object</tref> and then set <em>element</em> to that <tref>JSON object</tref>.
+ Finally, add a <code>@context</code> property to <em>element</em> and set it to the initially passed <em>context</em>.</p>
+
+</section>
+
+</section>
+
+<section>
+<h2>RDF Conversion</h2>
+
+<p>A JSON-LD document MAY be converted between other RDF-compatible document
+ formats using the algorithms specified in this section.</p>
+
+<p>The JSON-LD Processing Model describes processing rules for extracting RDF
+ from a JSON-LD document, and for transforming an array of <a>Quad</a> retrieved by processing
+ another serialization format into JSON-LD. Note that many uses of JSON-LD may not require
+ generation of RDF.</p>
+
+<p>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.</p>
+
+<section class="informative">
+ <h4>Overview</h4>
+ <p>
+ 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.
+ </p>
+ <p>
+ As with other grammars used for describing <tref>Linked Data</tref>, a key
+ concept is that of a <tref>node</tref> in a <tref>linked data graph</tref>.
+ Nodes may be of three basic types.
+ The first is the <ldtref>IRI</ldtref>, which is used to refer to
+ <tref>node</tref>s in other <tref>linked data graph</tref>s.
+ The second is the
+ <tref>blank node</tref>, which are nodes for which an external name does not
+ exist, or is not known. The third is a <tref>Literal</tref>, which express
+ values such as strings, dates and other information having a lexical
+ form, possibly including an explicit language or datatype.
+ </p>
+ <p>Data described with JSON-LD may be considered to be a graph made
+ up of <tref>subject</tref> and <tref>object</tref>
+ <tref title="node">nodes</tref> related via a <tref>property</tref>
+ <tref>node</tref>. 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.</p>
+</section>
+
+<section class="informative">
+ <h4>Parsing Examples</h4>
+
+ <p>The following examples show simple transformations of JSON-LD documents to Turtle [[TURTLE-TR]].</p>
+
+ <p>The first example uses a simple document containing a simple FOAF profile:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+{
+ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
+ "@id": "http://greggkellogg.net/foaf#me",
+ "@type": "foaf:Person",
+ "foaf:name": "Gregg Kellogg",
+ "foaf:knows": {
+ "@type": "foaf:Person",
+ "foaf:name": "Manu Sporny"
+ }
+}
+-->
+</pre>
+
+ <p>This translates fairly directly to a similar Turtle document:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+@prefix foaf: <http://xmlns.com/foaf/0.1/>.
+
+<http://greggkellogg.net/foaf#me> a foaf:Person;
+ foaf:name "Gregg Kellogg";
+ foaf:knows [ a foaf:Person; foaf:name "Manu Sporny"].
+-->
+</pre>
+
+ <p>The actual parsing steps first require that the JSON-LD document be expanded,
+ to eliminate the <code>@context</code>:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+[{
+ "@id": "http://greggkellogg.net/foaf#me",
+ "@type": ["http://xmlns.com/foaf/0.1/Person"],
+ "http://xmlns.com/foaf/0.1/name": [{"@value": "Gregg Kellogg"}],
+ "http://xmlns.com/foaf/0.1/knows": [{
+ "@type": ["http://xmlns.com/foaf/0.1/Person"],
+ "http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}]
+ }]
+}]
+-->
+</pre>
+
+ <p>The process of translating this to RDF then operates over each
+ <tref>subject definition</tref> to find a subject,
+ each <tref>property</tref> to find an RDF <em>predicate</em>,
+ and each value of that property to find an <tref>object</tref>.
+ In this case, each property has just a single object:
+ <code>foaf:name</code> identifies a <tref>literal</tref>, and
+ <code>foaf:knows</code> identifies a second <tref>subject definition</tref>
+ similar to Turtle's <code>blankNodePropertyList</code>.</p>
+
+ <p>After expansion, JSON-LD <tref title="number">numbers</tref>,
+ <tref title="true">booleans</tref>, typed- and language-tagged-<tref
+ title="literal">literals</tref>, and <tref title="iri">IRIs</tref>
+ become explicit, and can be directly transformed into their RDF representations.</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+[{
+ "@id": "http://greggkellogg.net/foaf#me",
+ "@type": ["http://xmlns.com/foaf/0.1/Person"],
+ "http://xmlns.com/foaf/0.1/name": [{"@value": "Gregg Kellogg"}],
+ ****"http://xmlns.com/foaf/0.1/currentProject": [{"@id": "http://json-ld.org/"}],
+ "http://xmlns.com/foaf/0.1/birthday": [{
+ "@value": "1957-02-27",
+ "@type": "http://www.w3.org/2001/XMLSchema#date"
+ }],****
+ "http://xmlns.com/foaf/0.1/knows": [{
+ "@type": ["http://xmlns.com/foaf/0.1/Person"],
+ "http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}]
+ }]
+}]
+-->
+</pre>
+
+ <p>Translates to:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+@prefix foaf: <http://xmlns.com/foaf/0.1/>.
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
+
+<http://greggkellogg.net/foaf#me> a foaf:Person;
+ foaf:name "Gregg Kellogg";
+ ****foaf:currentProject <http://json-ld.org/>;
+ foaf:birthday "1957-02-27"^^xsd:date;****
+ foaf:knows [ a foaf:Person; foaf:name "Manu Sporny"].
+-->
+</pre>
+
+</section>
+
+<section>
+ <h3>Convert to RDF Algorithm</h3>
+ <p>
+ The algorithm below is designed for in-memory implementations with random access to <tref>JSON object</tref> elements.
+ </p>
+ <p>
+ A conforming JSON-LD processor implementing RDF conversion MUST implement a
+ processing algorithm that results in the same set of RDF <tref title="quad">Quads</tref> that the following
+ algorithm generates:
+ </p>
+
+ <p>The algorithm takes five input variables: a <em>element</em> to be converted, an
+ <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>.
+ To begin, the <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>
+ are set to <tref>null</tref>, and <em>element</em> is
+ set to the result of performing the <a href="#expansion-algorithm">Expansion Algorithm</a> on
+ the <tref>JSON-LD input</tref>. This removes any existing context to allow the given context to be cleanly
+ applied.</p>
+
+ <ol class="algorithm">
+ <li id="processing-step-associative">
+ If <em>element</em> is a <tref>JSON object</tref>, perform the following steps:
+ <ol class="algorithm">
+ <li>Set <tref>active object</tref> to <tref>null</tref>.</li>
+ <li>
+ If <em>element</em> has a <code>@value</code> property:
+ <ol class="algorithm">
+ <li>If the value of <code>@value</code> is a <tref>number</tref>, set the
+ <tref>active object</tref> to a <tref>typed literal</tref> using a string representation
+ of the value as defined in the section <a href="#data-round-tripping">Data Round Tripping</a>.
+ Set datatype to the value of the <code>@type</code> property if it exists, otherwise
+ either <code>xsd:integer</code> or <code>xsd:double</code>, depending
+ on if the value contains a fractional and/or an exponential component.
+ <p class="issue" data-number="150">It is being
+ <a href="https://github.com/json-ld/json-ld.org/issues/150">discussed</a> if the automatic
+ mapping of JSON-native types to the XSD type system should be configurable or not.</p></li>
+ <li>Otherwise, if the value of <code>@value</code> is <strong>true</strong> or <strong>false</strong>,
+ set the <tref>active object</tref> to a <tref>typed literal</tref> created from the
+ string representation of the value. Set datatype to the value of the <code>@type</code>
+ property if it exists, otherwise <code>xsd:boolean</code>.</li>
+ <li>
+ Otherwise, if <em>element</em> contains a <code>@type</code> property, set the
+ <tref>active object</tref> to a <tref>typed literal</tref>.
+ </li>
+ <li>
+ Otherwise, if <em>element</em> contains a <code>@language</code> property, set the
+ <tref>active object</tref> to a <tref>language-tagged literal</tref>.
+ </li>
+ <li>
+ Otherwise, set the <tref>active object</tref> to a <tref>typed literal</tref>
+ using <code>xsd:string</code> as the datatype.
+ </li>
+ </ol>
+ </li>
+ <li>
+ If <em>element</em> has a <code>@list</code> property the value MUST be an <tref>array</tref>.
+ Process its value as a list as described in <a href="#list-conversion">List Conversion</a> using
+ the return value as the <tref>active object</tref>
+ </li>
+ <li>If <tref>active object</tref> is not <tref>null</tref>:
+ <ol class="algorithm">
+ <li>If neither <tref>active subject</tref> nor <tref>active property</tref> are <tref>null</tref>,
+ generate a <a>Quad</a>
+ representing <tref>active subject</tref>, <tref>active property</tref>,
+ <tref>active object</tref>, and <tref>graph name</tref>.</li>
+ <li>Return <tref>active object</tref>.</li>
+ </ol>
+ </li>
+ <li id="processing-step-subject">If <em>element</em> has a <code>@id</code> property,
+ the value MUST be a <tref>string</tref>, set the <tref>active subject</tref> to the previously
+ expanded value (either a <tref>blank node</tref> or an <ldtref>IRI</ldtref>).</li>
+ <li>
+ Otherwise, if <em>element</em> does not have a <code>@id</code> property, set the <tref>active
+ subject</tref> to newly generated <tref>blank node</tref>.</li>
+ <li>
+ Process each <em>property</em> and <em>value</em> in <em>element</em>, ordered by
+ <em>property</em>, as follows:
+ <ol class="algorithm">
+ <li>
+ If <em>property</em> is <code>@type</code>, set the <tref>active property</tref>
+ to <code>rdf:type</code>.
+ </li>
+ <li>Otherwise, if <em>property</em> is <code>@graph</code>,
+ process <em>value</em> algorithm recursively, using <tref>active subject</tref> as <tref>graph name</tref>
+ and null values for <tref>active subject</tref> and <tref>active property</tref> and then
+ proceed to next property.</li>
+ <li>Otherwise, if <em>property</em> is a <tref>keyword</tref>, skip this step.</li>
+ <li>Otherwise, set <tref>active property</tref> to the IRI value of <em>property</em>.</li>
+ <li>Process <em>value</em> recursively using this algorithm, passing copies of
+ <tref>active subject</tref>, <tref>active property</tref> and <tref>graph name</tref>.
+ </li>
+ </ol>
+ </li>
+ <li>
+ Set <tref>active object</tref> to <tref>active subject</tref>.
+ </li>
+ </ol>
+ </li>
+
+ <li>Otherwise, if <em>element</em> is an <tref>array</tref>, process each value in the <tref>array</tref>
+ as follows, process <em>element</em> recursively using this algorithm, using copies of
+ <tref>active subject</tref>, <tref>active property</tref>, and <tref>graph name</tref>.</li>
+
+ <li>Otherwise, if <em>element</em> is a <tref>string</tref>, then the <tref>active property</tref>
+ must be <code>rdf:type</code> so set the <tref>active object</tref> to an <ldtref>IRI</ldtref>.</li>
+
+ <li>If any of these steps created an <tref>active object</tref> and neither <tref>active subject</tref>
+ nor <tref>active property</tref> are <tref>null</tref>, generate a <a>Quad</a> using
+ <tref>active subject</tref>,<tref>active property</tref>, <tref>active object</tref> and
+ <tref>graph name</tref>.
+ </li>
+ <li>Return <tref>active object</tref>.</li>
+ </ol>
+</section>
+<section id="list-conversion">
+ <h3>List Conversion</h3>
+
+ <p>List Conversion is the process of taking an <tref>array</tref> of values and adding them to a newly
+ created <cite><a href="http://www.w3.org/TR/rdf-schema/#ch_collectionvocab">RDF Collection</a></cite> (see
+ [[!RDF-SCHEMA]]) by linking each element of the list using <code>rdf:first</code> and <code>rdf:next</code>,
+ terminating the list with <code>rdf:nil</code> using the following sequence:</p>
+ <p>The algorithm is invoked with an <tref>array</tref> <em>array</em>, the <tref>active property</tref>
+ and returns a value to be used as an <tref>active object</tref> in the calling location.</p>
+ <div class="note">This algorithm does not support lists containing lists.</div>
+ <ol class="algorithm">
+ <li>
+ If <em>array</em> is empty return <code>rdf:nil</code>.
+ </li>
+ <li>
+ Otherwise, generate a <a>Quad</a> using using the <tref>active subject</tref>, <tref>active property</tref>
+ and a newly generated <tref>blank node</tref> identified as <em>first <tref>blank node</tref></em>.
+ </li>
+ <li>
+ For each element in <em>array</em> other than the last element:
+ <ol class="algorithm">
+ <li>Create a processor state using
+ <em>first blank node</em> as the <tref>active subject</tref>, and
+ <code>rdf:first</code> as the <tref>active property</tref>.
+ <ol class="algorithm">
+ <li>Process the value starting at <a href="#processing-step-associative">Step 1</a>.</li>
+ <li>Proceed using the previous <tref>processor state</tref>.</li>
+ </ol>
+ </li>
+ <li>Unless this is the last element in <em>array</em>, generate a new <tref>blank node</tref> identified as
+ <em>rest blank node</em>, otherwise use <code>rdf:nil</code>.</li>
+ <li>Generate a new <a>Quad</a> using <em>first blank node</em>,
+ <code>rdf:rest</code> and <em>rest blank node</em>.</li>
+ <li>Set <em>first blank node</em> to
+ <em>rest blank node</em>.</li>
+ <li>Return <em>first blank node</em>.</li>
+ </ol>
+ </li>
+ </ol>
+</section>
+
+<section>
+ <h2>Convert from RDF Algorithm</h2>
+ <p>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 <ldtref title="quad">Quads</ldtref> into a JSON-LD document.</p>
+ <p>When expanding <tref>typed literal</tref> values having a datatype of <code>xsd:string</code>,
+ the <code>@type</code> MUST NOT be set to <code>xsd:string</code> and the resulting value
+ MUST have only a <code>@value</code> property.</p>
+ <p>The conversion algorithm takes a single parameter <em>input</em> in the form of an
+ array of <a>Quad</a> representations.</p>
+ <ol class="algorithm">
+ <li id="new_graph">Construct <em>defaultGraph</em> as a <tref>JSON object</tref>
+ containing <em>subjects</em> and <em>listMap</em>, each an empty <tref>JSON object</tref>.</li>
+ <li>Construct <em>graphs</em> as a <tref>JSON object</tref> containing <em>defaultGraph</em>
+ identified by
+ an empty <tref>string</tref>.</li>
+ <li>For each quad in <em>input</em>:
+ <ol class="algorithm">
+ <li>Set <em>graph</em> to the entry in <em>graphs</em> identified
+ by <em>name</em>, initializing it to a new entry using the mechanism
+ described in <a href="#new_graph">Step 1</a>.</li>
+ <li>If <em>property</em> is <code>rdf:first</code>,
+ use the entry in <em>graph.listMap</em> indexed by <em>subject</em>,
+ initializing it to a new <tref>JSON object</tref> if nesessary. Represent
+ <em>object</em> in expanded form, as described in
+ <a href="#value-expansion">Value Expansion</a>. Add the
+ resulting <em>object representation</em> to the entry indexed by
+ <em>first</em>, and skip to the next quad.</li>
+ <li>If <em>property</em> is <code>rdf:rest</code>:
+ <ol class="algorithm">
+ <li>If <em>object</em> is a <tref>blank node</tref>, use the entry in
+ <em>graph.listMap</em> indexed by <em>subject</em>, initializing it
+ to a new <tref>JSON object</tref> if necessary. Add the <em>nominalValue</em> of
+ <em>object</em> to the entry indexed by <em>rest</em>.
+ </li>
+ <li>Skip to the next quad.</li>
+ </ol>
+ </li>
+ <li>If <em>name</em> is not <tref>null</tref>, and <em>defaultGraph.subjects</em>
+ does not contain an entry for <em>name</em>,
+ create a new entry for <em>name</em> from a new
+ <tref>JSON object</tref> with key/value pair of <code>@id</code> and
+ a string representation of <em>name</em>.</li>
+ <li>Set <em>value</em> as the entry from <em>graph.subjects</em> for
+ <em>subject</em>, initializing it to a new
+ <tref>JSON object</tref> with key/value pair of <code>@id</code> and
+ a string representation of <em>subject</em> if necessary.</li>
+ <li>If <em>property</em> is <code>rdf:type</code> and the
+ <code class="idlMemberName"><a href="#widl-JsonLdOptions-useRdfType">useRdfType</a></code>
+ option is not present or <tref>false</tref>:
+ <ol class="algorithm">
+ <li>Append the string representation of <em>object</em> to the array value for the
+ key <code>@type</code>, creating an entry in <em>value</em> if necessary.</li>
+ </ol>
+ </li>
+ <li>Otherwise, if <em>object</em> is <code>rdf:nil</code>:
+ <ol class="algorithm">
+ <li>Let <em>key</em> be the string representation of <em>property</em>.</li>
+ <li>Append an empty <code>@list</code> representation to the array value for
+ <em>key</em>, creating an entry in <em>value</em> if necessary.</li>
+ </ol>
+ </li>
+ <li>Otherwise,
+ <ol class="algorithm">
+ <li>Let <em>key</em> be the string representation of <em>property</em> and let
+ <em>object representation</em>
+ be <em>object</em> represented in expanded form as described in
+ <a href="#value-expansion">Value Expansion</a>.</li>
+ <li>If <em>object</em> is a <tref>blank node</tref>,
+ use the entry in <em>graph.listMap</em> indexed by <em>object</em>,
+ initializing it to a new <tref>JSON object</tref> if nesessary.
+ Add an entry for <em>head</em> with <em>object representation</em>.</li>
+ <li>Append <em>object representation</em> to the array value for
+ <em>key</em>, creating an entry in <em>value</em> if necessary.</li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ <li>For each <em>name</em> and <em>graph</em> in <em>graphs</em>:
+ <ol class="algorithm">
+ <li>For each <em>subject</em> and <em>entry</em> in <em>graph</em>
+ where <em>entry</em> has both <em>head</em> and <em>first</em> keys:
+ <ol class="algorithm">
+ <li>Set <em>value</em> to the value of <em>head</em> in <em>entry</em>.</li>
+ <li>Remove the entry for <code>@id</code> in <em>value</em>.</li>
+ <li>Add an entry to <em>value</em> for <code>@list</code> initialized to a new array
+ containing the value of <em>first</em> from <em>entry</em>.</li>
+ <li>While <em>entry</em> has a key for <em>rest</em>:
+ <ol class="algorithm">
+ <li>Set <em>entry</em> to the value of <em>graph.listMap</em> for <em>entry.rest</em>.</li>
+ <li>Add the value for <em>entry.first</em> to the list array.</li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ <li>Create <em>array</em> as an empty <tref>array</tref>.</li>
+ <li>For each <em>subject</em> and <em>entry</em> in <em>defaultGraph.subjects</em>
+ ordered by <em>subject</em>:
+ <ol class="algorithm">
+ <li>Add <em>entry</em> to <em>array</em>.</li>
+ <li>If <em>graphs</em> has an entry for <em>subject</em>, add a property
+ <code>@graph</code> in <em>entry</em> containing the ordered entries
+ from <em>graphs[subject].subjects</em>.</li>
+ </ol>
+ </li>
+ <li>Return <em>array</em> as the result.</li>
+ </ol>
+</section>
+</section>
+
+</section>
+
+<section>
+<h3>Data Round Tripping</h3>
+
+<p>When <a href="#rdf-conversion">converting JSON-LD to RDF</a> JSON-native types such as
+ <em>numbers</em> and <em>booleans</em> are automatically coerced to <strong>xsd:integer</strong>,
+ <strong>xsd:double</strong>, or <strong>xsd:boolean</strong>. Implementers MUST ensure that the
+ result is a canonical lexical form in the form of a <tref>string</tref>. A
+ <tdef>canonical lexical form</tdef> 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.</p>
+
+<p>The canonical lexical form of an <em>integer</em>, i.e., a number without fractions
+ or a number coerced to <strong>xsd:integer</strong>, is a finite-length sequence of decimal
+ digits (<code>0-9</code>) with an optional leading minus sign; leading zeroes are prohibited.
+ To convert the number in JavaScript, implementers can use the following snippet of code:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+(value).toFixed(0).toString()
+-->
+</pre>
+
+<p>The canonical lexical form of a <em>double</em>, i.e., a number with fractions
+ or a number coerced to <strong>xsd:double</strong>, 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 (<code>+</code>) are prohibited
+ in the exponent. If the exponent is zero, it must be indicated by <code>E0</code>.
+ 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 <code>0.0E0</code>.
+ <strong>xsd:double</strong>'s value space is defined by the IEEE double-precision 64-bit
+ floating point type [[!IEEE-754-1985]]; in JSON-LD the mantissa is rounded to 15 digits after the
+ decimal point.</p>
+
+<p>To convert the number in JavaScript, implementers can use the following snippet of code:</p>
+
+<pre class="example" data-transform="updateExample">
+<!--
+(value).toExponential(15).replace(/(\d)0*e\+?/,'$1E')
+-->
+</pre>
+
+<p class="note">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 <strong>xsd:double</strong> values. Authors should instead use the expanded object form to
+ set the canonical lexical form directly.</p>
+
+<p>The canonical lexical form of the <em>boolean</em> values <code>true</code> and <code>false</code>
+ are the strings <strong>true</strong> and <strong>false</strong>.</p>
+
+<p>When JSON-native <tref>number</tref>s, are type coerced, lossless data round-tripping can not
+ be guaranted as rounding errors might occur. Additionally, only literals typed as
+ <strong>xsd:integer</strong>, <strong>xsd:double</strong>, and <strong>xsd:boolean</strong> are
+ automatically converted back to their JSON-native counterparts in when
+ <a href="#rdf-conversion">converting from RDF</a>.</p>
+
+<p class="issue" data-number="150">It is being
+ <a href="https://github.com/json-ld/json-ld.org/issues/150">discussed</a> if the automatic mapping
+ of JSON-native types to the XSD type system should be configurable or not.</p>
+
+<p class="note">Some JSON serializers, such as PHP's native implementation in some versions,
+ backslash-escape the forward slash character. For example, the value
+ <code>http://example.com/</code> would be serialized as <code>http:\/\/example.com\/</code>.
+ 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.</p>
+
+</section>
+
+<section class="appendix">
+<h1>Acknowledgements</h1>
+
+<p>A large amount of thanks goes out to the JSON-LD Community Group
+participants who worked through many of the technical issues on the mailing
+list and the weekly telecons - of special mention are Niklas Lindström,
+François Daoust, and Zdenko 'Denny' Vrandečić.
+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.
+The work of Dave Lehn and Mike Johnson are appreciated for reviewing,
+and performing several implementations of the specification. Ian Davis is
+thanked for this work on 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.
+</p></section>
+
+</body>
+</html>