--- a/playground/jsonld.js Wed May 23 22:32:46 2012 -0400
+++ b/playground/jsonld.js Wed May 23 22:36:24 2012 -0400
@@ -309,7 +309,7 @@
var framed = new Processor().frame(_input, _frame, options);
}
catch(ex) {
- callback(ex);
+ return callback(ex);
}
// compact result (force @graph option to true)
@@ -754,20 +754,28 @@
* @param value the value to add.
* @param [propertyIsArray] true if the property is always an array, false
* if not (default: false).
+ * @param [propertyIsList] true if the property is a @list, false
+ * if not (default: false).
*/
-jsonld.addValue = function(subject, property, value, propertyIsArray) {
+jsonld.addValue = function(
+ subject, property, value, propertyIsArray, propertyIsList) {
propertyIsArray = _isUndefined(propertyIsArray) ? false : propertyIsArray;
+ propertyIsList = (_isUndefined(propertyIsList) ?
+ (property === '@list') : propertyIsList);
if(_isArray(value)) {
if(value.length === 0 && propertyIsArray && !(property in subject)) {
subject[property] = [];
}
for(var i in value) {
- jsonld.addValue(subject, property, value[i], propertyIsArray);
+ jsonld.addValue(
+ subject, property, value[i], propertyIsArray, propertyIsList);
}
}
else if(property in subject) {
- var hasValue = jsonld.hasValue(subject, property, value);
+ // check if subject already has value unless property is list
+ var hasValue = (!propertyIsList &&
+ jsonld.hasValue(subject, property, value));
// make property an array if value not present or always an array
if(!_isArray(subject[property]) && (!hasValue || propertyIsArray)) {
@@ -1140,7 +1148,7 @@
(_isArray(v) && v.length === 0));
// add compact value
- jsonld.addValue(rval, prop, v, isArray);
+ jsonld.addValue(rval, prop, v, isArray, (container === '@list'));
}
}
return rval;
--- a/playground/playground.css Wed May 23 22:32:46 2012 -0400
+++ b/playground/playground.css Wed May 23 22:36:24 2012 -0400
@@ -30,7 +30,7 @@
overflow: hidden;
width: 100%;
padding-top: 10px;
-}
+}
.input-header .left {
display: inline-block;
@@ -97,3 +97,5 @@
}
#frame {display: none;}
+
+#markup-container { clear: both }
--- a/playground/playground.js Wed May 23 22:32:46 2012 -0400
+++ b/playground/playground.js Wed May 23 22:36:24 2012 -0400
@@ -201,12 +201,12 @@
var options = {base: document.baseURI};
if(playground.activeTab === 'tab-normalized') {
+ options.format = 'application/nquads';
jsonld.normalize(input, options, function(err, normalized) {
if(err) {
return callback(err);
}
- $('#normalized').html(js_beautify(JSON.stringify(normalized),
- {'indent_size': 2, 'brace_style': 'expand'}));
+ $('#normalized').html(playground.htmlEscape(normalized));
callback();
});
}
@@ -248,7 +248,7 @@
return callback(err);
}
$('#nquads').html(playground.htmlEscape(nquads));
- return callback();
+ callback();
});
}
};
--- a/spec/ED/json-ld-syntax/20120522/index.html Wed May 23 22:32:46 2012 -0400
+++ b/spec/ED/json-ld-syntax/20120522/index.html Wed May 23 22:36:24 2012 -0400
@@ -2338,7 +2338,8 @@
deterministically transform the author's markup into valid JSON-LD.</p>
<p class="issue">The final nuanced details of the exact grammar are still being
-discussed, as well as the best mechanism to express these restrictions. EBNF
+discussed (see <a href="https://github.com/json-ld/json-ld.org/issues/114#issuecomment-5820544">ISSUE-114</a>),
+as well as the best mechanism to express these restrictions. EBNF
seems like overkill since it's a subset of JSON. EBNF doesn't quite capture
some of the more esoteric restrictions in the language.
</p>
--- a/spec/latest/json-ld-api/index.html Wed May 23 22:32:46 2012 -0400
+++ b/spec/latest/json-ld-api/index.html Wed May 23 22:36:24 2012 -0400
@@ -68,9 +68,10 @@
ref = ref.replace(/\s+/g, '_') ;
}
var sp = document.createElement( 'a' ) ;
- sp.className = 'datatype';
+ sp.className = 'datatype idlType';
sp.title = ref ;
- sp.innerHTML = con ;
+ sp.setAttribute('href', '#idl-def-' + ref);
+ sp.innerHTML = '<code>' + con + '</code>';
p.replaceChild(sp, item) ;
}
// external datatype references
@@ -658,10 +659,10 @@
</dd>
<dt>void fromRDF()</dt>
- <dd>Creates a JSON-LD document given an set of <a>Statement</a>s.
+ <dd>Creates a JSON-LD document given an set of <ldtref title="quad">Quads</ldtref>.
<dl class="parameters">
- <dt>Statement[] input</dt>
- <dd>An array of RDF statements.</dd>
+ <dt>Quad[] input</dt>
+ <dd>An array of RDF quads.</dd>
<dt>JsonLdCallback callback</dt>
<dd>A callback that is called when processing is complete on
the given <code>input</code>.</dd>
@@ -676,14 +677,15 @@
<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 <a>Statement</a> generated.
+ the provided <code>callback</code> for each <a>Quad</a> generated.
<dl class="parameters">
<dt>object or object[] or URL input</dt>
<dd>The JSON-LD object or array of JSON-LD objects to convert to RDF or an <tref>IRI</tref>
referencing the JSON-LD document to convert to RDF.</dd>
- <dt>StatementCallback callback</dt>
- <dd>A callback that is called when a <a>Statement</a> is created from processing
- the given <code>input</code>.</dd>
+ <dt>QuadCallback callback</dt>
+ <dd>A callback that is called when a <a>Quad</a> 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>
@@ -730,18 +732,18 @@
</dl>
</section>
<section>
- <h3>StatementCallback</h3>
- <p>The <a>StatementCallback</a> is called whenever the processor generates a
- statement during the <code>statement()</code> call.</p>
+ <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 StatementCallback"
+ <dl title="[NoInterfaceObject Callback] interface QuadCallback"
class="idl">
- <dt>void statement()</dt>
- <dd>This callback is invoked whenever a statement is generated by the processor.
+ <dt>void quad()</dt>
+ <dd>This callback is invoked whenever a quad is generated by the processor.
<dl class="parameters">
- <dt>Statement statement</dt>
- <dd>The statement.</dd>
+ <dt>Quad quad</dt>
+ <dd>The quad.</dd>
</dl>
</dd>
</dl>
@@ -785,33 +787,39 @@
</section>
<p>The following data structures are used for representing data about
- RDF statements (triples or quads). They are used for normalization, <a>fromRDF</a>,
+ RDF quads. They are used for normalization, <a>fromRDF</a>,
and from <a>toRDF</a> interfaces.
</p>
<section>
- <h3>Statement</h3>
- <p>The <a>Statement</a> interface represents an RDF Statement.</p>
- <dl title="[NoInterfaceObject] interface Statement" class="idl">
+ <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 subject associated with the <a>Statement</a>.</dd>
+ <dd>The subject associated with the <a>Quad</a>.</dd>
<dt>readonly attribute Node property</dt>
- <dd>The property associated with the <a>Statement</a>.</dd>
+ <dd>The property associated with the <a>Quad</a>.</dd>
<dt>readonly attribute Node object</dt>
- <dd>The object associated with the <a>Statement</a>.</dd>
+ <dd>The object associated with the <a>Quad</a>.</dd>
<dt>readonly attribute Node? name</dt>
- <dd>The name associated with the <a>Statement</a> identifying
+ <dd>The name associated with the <a>Quad</a> identifying
it as a member of a named graph. If the attribute is present,
- it indicates that this statement is a member of a <em>named graph</em>
- associated with <em>name</em>. If it is missing, the statement
- is a member of the <em>default graph</em>.</dd>
+ it indicates that this quad is a member of a <em>named graph</em>
+ associated with <em>name</em>. If it is missing, the quad
+ is a member of the <em>default graph</em>.
+ <div class="issue">This element is at risk, and may be removed.</div>
+ </dd>
</dl>
</section>
<section>
<h3>Node</h3>
- <p><a>Node</a> is the base class of <a>NamedNode</a>,
- <a>BlankNode</a>, and <a>LiteralNode</a>.</p>
+ <p><a>Node</a> is the base class of <ldtref>IRI</ldtref>,
+ <a>BlankNode</a>, and <ldtref>Literal</ldtref>.</p>
<dl title="[NoInterfaceObject] interface Node" class="idl">
<dt>readonly attribute DOMString nominalValue</dt>
<dd>
@@ -821,18 +829,19 @@
<dt>readonly attribute DOMString interfaceName</dt>
<dd>
<p>Provides access to the string name of the current interface,
- normally one of <code>"IRI"</code>, <code>"BlankNode"</code> or <code>"LiteralNode"</code>.</p>
+ normally one of <code>"IRI"</code>, <code>"BlankNode"</code> or <code>"Literal"</code>.</p>
<p>This method serves to disambiguate instances of <a>Node</a> which
- are otherwise identical, such as <a>NamedNode</a> and <a>BlankNode</a>.</p>
+ are otherwise identical, such as <ldtref>IRI</ldtref> and <a>BlankNode</a>.</p>
</dd>
</dl>
</section>
<section>
- <h3>NamedNode</h3>
- <p>A node identified by an <tref>IRI</tref>. NamedNodes are defined by International
- Resource Identifier [[!IRI]].</p>
- <dl title="[NoInterfaceObject] interface NamedNode : Node"
+ <h3>IRI</h3>
+ <p>A node identified by an <tref>IRI</tref>. IRIs are defined by International
+ Resource Identifier [[!IRI]]. See [[!RDF-CONCEPTS]] definition for
+ <cite><a href="http://www.w3.org/TR/rdf11-concepts/#dfn-iri">IRI</a></cite>.</p>
+ <dl title="[NoInterfaceObject] interface IRI : Node"
class="idl">
<dt>readonly attribute DOMString nominalValue</dt>
<dd>The IRI identifier of the node.</dd>
@@ -843,8 +852,9 @@
<h3>Blank Node</h3>
<p>A <a>BlankNode</a> is a reference to an unnamed resource
- (one for which an IRI is not known), and may be used in a <a>Statement</a>
- as a unique reference to that unnamed resource.</p>
+ (one for which an IRI may not be known), and may be used in a <a>Quad</a>
+ as a unique reference to that unnamed node. See [[!RDF-CONCEPTS]] definition for
+ <cite><a href="http://www.w3.org/TR/rdf11-concepts/#dfn-blank-node">blank node</a></cite>.</p>
<dl title="[NoInterfaceObject] interface BlankNode : Node" class="idl">
<dt>readonly attribute DOMString nominalValue</dt>
@@ -856,45 +866,48 @@
<p class="note">Developers and authors must not assume that the
nominalValue of a <a>BlankNode</a> will remain the same between two
processing runs. <a>BlankNode</a> nominalValues are only valid for the
- most recent processing run on the document. <a>BlankNode</a>s
+ most recent processing run on the document. <ldtref title="blanknode">BlankNodes</ldtref>
nominalValues will often be generated differently by different processors.</p>
<p class="note">Implementers MUST ensure that <a>BlankNode</a> nominalValues are unique
- within the current environment, two <a>BlankNode</a>s are considered equal if, and only if,
+ within the current environment, two <ldtref title="blanknode">BlankNodes</ldtref> are considered equal if, and only if,
their nominalValues are strictly equal.</p>
</section>
<section>
- <h3>LiteralNode</h3>
- <p>LiteralNodes represent values such as numbers, dates and strings in
- RDF data. A <a>LiteralNode</a> is comprised of three attributes:
+ <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 representation of the <code>nominalValue</code></li>
<li>an optional <code>language</code> represented by a string token</li>
- <li>an optional <code>datatype</code> specified by a <a>NamedNode</a></li>
+ <li>an optional <code>datatype</code> specified by an <ldtref>IRI</ldtref></li>
</ul>
- <p>LiteralNodes representing plain text in a natural language may have a
+ <p>Literals representing plain text in a natural language may have a
<code>language</code> attribute specified by a text string token, as specified in
[[!BCP47]], normalized to lowercase
(e.g., <code>'en'</code>, <code>'fr'</code>, <code>'en-gb'</code>).
They may also have a datatype attribute such as <code>xsd:string</code>.
</p>
- <p>LiteralNodes representing values with a specific datatype, such as
+ <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>NamedNode</a> (e.g.,
+ of a <a>IRI</a> (e.g.,
<code><http://www.w3.org/2001/XMLSchema#integer></code>).</p>
- <dl title="[NoInterfaceObject] interface LiteralNode : Node" class="idl">
+ <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 nominalValue</dt>
- <dd>The lexical representation of the LiteralNodes value.</dd>
+ <dd>The lexical representation of the Literals value.</dd>
<dt>readonly attribute DOMString? language</dt>
<dd>An optional language string as defined in [[!BCP47]], normalized to lowercase.</dd>
- <dt>readonly attribute NamedNode? datatype</dt>
- <dd>An optional datatype identified by a NamedNode.</dd>
+ <dt>readonly attribute IRI? datatype</dt>
+ <dd>An optional datatype identified by a IRI.</dd>
</dl>
</section>
</section>
@@ -1296,8 +1309,8 @@
<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>Otherwise, if the <tref>active property</tref> is the target of language tagging, set the second key-value
+ <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>
@@ -1307,7 +1320,7 @@
<section>
<h2>Value Compaction</h2>
- <p>Some values, such as IRIs and typed literals, may be expressed in an
+ <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>
@@ -1328,7 +1341,7 @@
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 typed literal, the compacted
+ <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>
@@ -1880,30 +1893,24 @@
<li>If <em>element</em> is an array, process each entry in <em>element</em> recursively, using this algorithm
and return.</li>
<li>If <em>element</em> is not a <tref>JSON object</tref> or if it has a <code>@value</code> property,
- then if <em>list</em> is not <tref>null</tref>, append <em>element</em> to <em>list</em> and return.
- </li>
+ then if <em>list</em> is not <tref>null</tref>, append <em>element</em> to <em>list</em> and return.</li>
<li>If the <code>@id</code> property exists and is an <tref>IRI</tref>, set <em>id</em> to its value, otherwise
set it to a <tref>blank node</tref> identifer created by the
- <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a> algorithm.
- </li>
+ <a href="#generate-blank-node-identifier">Generate Blank Node Identifier</a> algorithm.</li>
<li>If <em>list</em> is not <tref>null</tref>, append a new <tref>subject reference</tref> to <em>list</em> using
- <em>id</em> at the value for <code>@id</code>.
- </li>
+ <em>id</em> at the value for <code>@id</code>.</li>
<li>Let <em>subjects</em> be the value in <em>subjectMap</em> where the key is <em>graph</em>; if no such
value exists, insert a new <tref>JSON object</tref> for the key <em>graph</em>. If <em>id</em> is not in
<em>subjects</em>, create a new <tref>JSON object</tref> <em>subject</em> with <em>id</em> as the value
for <code>@id</code>. Let <em>subject</em> be the value of <em>id</em> in <em>subjects</em>.</li>
- </li>
<li>For each <em>property</em> that is not <code>@id</code> and each <em>value</em> in <em>element</em> ordered
by <em>property</em>:
<ol class="algorithm">
<li>If <em>property</em> is <code>@graph</code>, recursively call this algorithm passing <em>value</em>
for <em>element</em>, <em>subjectMap</em>, <tref>null</tref> for <em>list</em> and if <em>graph</em>
- is <code>merged</code> use <em>graph</em>, otherwise use <em>id</em> for <em>graph</em> and then continue.
- </li>
+ is <code>merged</code> use <em>graph</em>, otherwise use <em>id</em> for <em>graph</em> and then continue.</li>
<li>If <em>property</em> is not <code>@type</code> and is a keyword, merge <code>property</code> and
- <code>value</code> into <code>subject</code> and then continue.
- </li>
+ <code>value</code> into <code>subject</code> and then continue.</li>
<li>For each value <em>v</em> in the array <em>value</em>:
<ol class="algorithm">
<li>If <em>v</em> is a <tref>subject definition</tref> or <tref>subject reference</tref>:
@@ -1911,23 +1918,19 @@
<li>If the property <code>@id</code> is not an <tref>IRI</tref> or it does not exist,
map <em>v</em> to a <a href="#generate-blank-node-identifier">new blank node identifier</a>
to avoid collisions. If one does not already exist, add a <tref>subject reference</tref> for
- <em>v</em> into <em>subject</em> for <em>property</em>.
- </li>
+ <em>v</em> into <em>subject</em> for <em>property</em>.</li>
<li>Recursively call this algorithm passing <em>v</em> for <em>value</em>, <em>subjectMap</em>,
- <em>graph</em>, and <tref>null</tref> for <em>list</em>.
- </li>
+ <em>graph</em>, and <tref>null</tref> for <em>list</em>.</li>
</ol>
</li>
<li>Otherwise if <em>v</em> has the property <code>@list</code> then recursively call this algorithm
with the value of <code>@list</code> as <em>element</em>, <em>subjectMap</em>, <em>graph</em>, and
a new array <em>flattenedList</em> as <em>list</em>. Create a new <tref>JSON object</tref> with the
property <code>@list</code> set to <em>flattenedList</em> and add it to <em>subject</em> for
- <em>property</em>.
- </li>
+ <em>property</em>.</li>
<li>Otherwise, if <em>property</em> is <code>@type</code> and <em>v</em> is not an <tref>IRI</tref>,
generate a <a href="#generate-blank-node-identifier">new blank node identifier</a> and add it
- to <em>subject</em> for <em>property</em>.
- </li>
+ to <em>subject</em> for <em>property</em>.</li>
<li>Otherwise, add <em>v</em> to <em>subject</em> for <em>property</em>.</li>
</ol>
</li>
@@ -1937,7 +1940,7 @@
<p>After the above outlined algorithm has been executed, the subject map for all graphs including the default graph are contained in
<em>subjectMap</em>. To also create the subject map for the merged graph, execute the algorithm again, but pass <code>merged</code>
- for <em>graph</em>.
+ for <em>graph</em>.</p>
</section>
@@ -2081,6 +2084,313 @@
</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 <tdef>resource</tdef>. Resources may be of three basic types: <ldtref>IRI</ldtref>, representing
+ <tref title="IRI">IRIs</tref> for describing
+ externally named entities, <a>BlankNode</a>, resources for which an external name does not
+ exist, or is not known, and <ldtref>Literal</ldtref>, which describe terminal entities such as strings,
+ dates and other representations having a lexical representation possibly including
+ an explicit language or datatype.
+ </p>
+ <p>Data described with JSON-LD may be considered to be the representation of a graph made
+ up of <tref>subject</tref> and <tref>object</tref> <tref>resource</tref>s related via a
+ <tref>property</tref> <tref>resource</tref>.
+ However, specific implementations may choose to operate on the document as a normal
+ JSON description of objects having attributes.</p>
+</section>
+
+<section>
+ <h4>RDF Conversion Algorithm Terms</h4>
+ <dl>
+ <dt><tdef>graph name</tdef></dt>
+ <dd>
+ A <ldtref>IRI</ldtref> or <ldtref>BlankNode</ldtref> used to identify quads belonging to a
+ <em>named graph</em>.
+ </dd>
+ </dl>
+</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 <ldtref title="quad">Quads</ldtref> 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.</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, set the <tref>active object</tref> to a <tref>plain literal</tref>. If <em>element</em>
+ contains a <code>@language</code> property, use its value to set the language of the plain literal.
+ </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 <a>BlankNode</a> 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 <a>BlankNode</a> 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 <a>BlankNode</a> 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>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 <a>BlankNode</a>, 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 <a>BlankNode</a>,
+ 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>
@@ -2165,313 +2475,6 @@
</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>Statement</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 statements 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 <tdef>resource</tdef>. Resources may be of three basic types: <a>NamedNode</a>, representing
- IRIs for describing
- externally named entities, <a>BlankNode</a>, resources for which an external name does not
- exist, or is not known, and <a>LiteralNode</a>, which describe terminal entities such as strings,
- dates and other representations having a lexical representation possibly including
- an explicit language or datatype.
- </p>
- <p>Data described with JSON-LD may be considered to be the representation of a graph made
- up of <tref>subject</tref> and <tref>object</tref> <tref>resource</tref>s related via a
- <tref>property</tref> <tref>resource</tref>.
- However, specific implementations may choose to operate on the document as a normal
- JSON description of objects having attributes.</p>
-</section>
-
-<section>
- <h4>RDF Conversion Algorithm Terms</h4>
- <dl>
- <dt><tdef>graph name</tdef></dt>
- <dd>
- A <tref>IRI</tref> or <tref>Blank Node</tref> used to identify statements belonging to a
- <em>named graph</em>.
- </dd>
- </dl>
-</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 <a>Statement</a>s 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.</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, set the <tref>active object</tref> to a <tref>plain literal</tref>. If <em>element</em>
- contains a <code>@language</code> property, use its value to set the language of the plain literal.
- </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>Statement</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 <tref>IRI</tref>).</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 <tref>IRI</tref>.</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>Statement</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>Statement</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 <tref>blank node</tref></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 <tref>blank node</tref></em>, otherwise use <code>rdf:nil</code>.</li>
- <li>Generate a new <a>Statement</a> using <em>first <tref>blank node</tref></em>,
- <code>rdf:rest</code> and <em>rest <tref>blank node</tref></em>.</li>
- <li>Set <em>first <tref>blank node</tref></em> to
- <em>rest <tref>blank node</tref></em>.</li>
- <li>Return <em>first <tref>blank node</tref></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 <a>Statement</a>s into a JSON-LD document.</p>
- <p>The conversion algorithm takes a single parameter <em>input</em> in the form of an
- array of <a>Statement</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 statement 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 statement.</li>
- <li>If <em>property</em> is <code>rdf:rest</code>:
- <ol class="algorithm">
- <li>If <em>object</em> is a <a>BlankNode</a>, 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 statement.</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 <a>BlankNode</a>,
- 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 class="appendix informative">
<h1>IANA Considerations</h1>
--- a/spec/latest/json-ld-syntax/index.html Wed May 23 22:32:46 2012 -0400
+++ b/spec/latest/json-ld-syntax/index.html Wed May 23 22:36:24 2012 -0400
@@ -304,13 +304,13 @@
<p>
JSON, as specified in [[!RFC4627]], is a simple language for representing
-data on the Web. <tref>Linked Data</tref> is a technique for creating a network
-of inter-connected data across different Web documents and Web sites.
+data on the Web. <tref>Linked Data</tref> is a technique for creating a network
+of inter-connected data across different Web documents and Web sites.
A <em>thing</em> in this data network is typically identified using an
-<tref>IRI</tref> (Internationalized Resource Identifier), which is typically
-dereference-able, and thus may be used to find more information about the
-<em>thing</em>. The <tref>IRI</tref> allows
-a software program to start at one <em>thing</em> and follow links to other
+<tref>IRI</tref> (Internationalized Resource Identifier), which is typically
+dereference-able, and thus may be used to find more information about the
+<em>thing</em>. The <tref>IRI</tref> allows
+a software program to start at one <em>thing</em> and follow links to other
<em>things</em> in order to learn more about all of the things described on the
Web.
</p>
@@ -329,9 +329,9 @@
The syntax does not necessarily require applications to change their JSON, but
allows one to easily add meaning by simply adding or referencing a context.
The syntax is designed to not disturb already deployed systems
-running on JSON, but provide a smooth upgrade path from JSON to JSON-LD.
+running on JSON, but provide a smooth upgrade path from JSON to JSON-LD.
Finally, the format is intended to be easy to parse, efficient
-to generate, and only requires a very small memory footprint in order to
+to generate, and only requires a very small memory footprint in order to
operate.
</p>
@@ -380,8 +380,8 @@
unless specific markup is provided (see <a href="#sets-and-lists">Sets and Lists</a>).
</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
+ 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>
@@ -410,7 +410,7 @@
<section>
<h2>Syntax Tokens and Keywords</h2>
- <p>JSON-LD specifies a number of syntax tokens and <tdef title="keyword">keywords</tdef>
+ <p>JSON-LD specifies a number of syntax tokens and <tdef title="keyword">keywords</tdef>
that are a core part of the language:</p>
<dl>
@@ -497,7 +497,7 @@
<dd>No extra
processors or software libraries should be necessary to use JSON-LD in its most
basic form. The language will provide developers with a very easy
- learning curve. Developers need only know JSON and two
+ learning curve. Developers need only know JSON and two
<tref title="keyword">keywords</tref> (<code>@context</code>
and <code>@id</code>) to use the basic functionality in JSON-LD.</dd>
<dt>Compatibility</dt>
@@ -514,18 +514,18 @@
linked was an approach that was driven by pragmatism. JSON-LD attempts to be
more practical than theoretical in its approach to Linked Data.</dd>-->
<dt>Zero Edits, most of the time</dt>
- <dd>JSON-LD must provide a
+ <dd>JSON-LD must provide a
<a href="#referencing-contexts-from-json-documents">mechanism</a>
- that allows developers to specify <tref>context</tref> in a way that is
+ that allows developers to specify <tref>context</tref> in a way that is
out-of-band.
This allows organizations that have
already deployed large JSON-based infrastructure to add meaning to their
JSON documents in a way that is not disruptive to their day-to-day operations and is
transparent to their current customers. At times, mapping JSON to
a graph representation can become difficult. In these instances, rather than
- having JSON-LD support an esoteric use case, we chose not to support the
- use case and support a simplified syntax instead. So, while Zero Edits is
- a goal, it is not always possible without adding great complexity to
+ having JSON-LD support an esoteric use case, we chose not to support the
+ use case and support a simplified syntax instead. So, while Zero Edits is
+ a goal, it is not always possible without adding great complexity to
the language.
</dd>
<dt>One-pass Processing</dt>
@@ -852,12 +852,12 @@
<p>JSON keys that do not expand to an absolute IRI are ignored, or removed
in some cases, by the [[JSON-LD-API]]. However, JSON keys that do not include
a mapping in the <tref>context</tref> are still considered valid expressions
-in JSON-LD documents - the keys just don't have any machine-readable,
+in JSON-LD documents - the keys just don't have any machine-readable,
semantic meaning.</p>
<p><tref>Prefix</tref>es are expanded when the form of the value is a
<tref>compact IRI</tref> represented as a <code>prefix:suffix</code>
- combination, and the prefix matches a <tref>term</tref> defined within the
+ combination, and the prefix matches a <tref>term</tref> defined within the
<tref>active context</tref>:</p>
<pre class="example" data-transform="updateExample">
@@ -920,8 +920,8 @@
-->
</pre>
-<p>In the example above, even though the value
-<code>http://manu.sporny.org/</code> is expressed as a JSON
+<p>In the example above, even though the value
+<code>http://manu.sporny.org/</code> is expressed as a JSON
<tref>string</tref>, the type <tref>coercion</tref> rules will transform
the value into an IRI when processed by a JSON-LD Processor.</p>
@@ -965,7 +965,7 @@
<p>A <tref>JSON object</tref> used to define property values is called a
<tref>subject definition</tref>. <tref title="subject definition">Subject definitions</tref>
- do not require an <code>@id</code>. A
+ do not require an <code>@id</code>. A
<tref>subject definition</tref>
that does not contain an <code>@id</code> property is called an
<tref>unlabeled node</tref>.</p>
@@ -1095,7 +1095,7 @@
-->
</pre>
-<p class="note">JSON-LD allows one to associate language information with
+<p class="note">JSON-LD allows one to associate language information with
<tref>term</tref>s.
See <a href="#expanded-term-definition">Expanded Term Definition</a> for
more details.</p>
@@ -1107,7 +1107,7 @@
<p>A JSON-LD author can express multiple values in a compact way by using
<tref>array</tref>s. Since graphs do not describe ordering for links
- between nodes, arrays in JSON-LD do not provide an ordering of the
+ between nodes, arrays in JSON-LD do not provide an ordering of the
listed objects by default. This is exactly the opposite from regular JSON
arrays, which are ordered by default. For example, consider the following
simple document:</p>
@@ -1231,7 +1231,7 @@
contains a single value.</p>
<p class="note">The use of <code>@container</code> in the body of a JSON-LD
- document, i.e., outside <code>@context</code> MUST be ignored by
+ document, i.e., outside <code>@context</code> MUST be ignored by
JSON-LD processors.</p>
</section>
@@ -1285,7 +1285,7 @@
</pre>
<p>The <em>modified</em> key's value above is automatically type coerced to a
-datetime value because of the information specified in the
+datetime value because of the information specified in the
<code>@context</code>.</p>
<p>The second example uses the expanded form of setting the type information
@@ -1683,10 +1683,10 @@
within the current active context. This mechanism is mainly used to associate type or language
information with a <tref>compact IRI</tref> or an <tref>absolute IRI</tref>.</p>
-<p class="note">While it is possible to define a
+<p class="note">While it is possible to define a
<tref>compact IRI</tref>, or an absolute IRI to expand to some
- other unrelated IRI (for example, <code>foaf:name</code> expanding to
- <code>http://example.org/unrelated#species</code>),
+ other unrelated IRI (for example, <code>foaf:name</code> expanding to
+ <code>http://example.org/unrelated#species</code>),
such usage is strongly discouraged.</p>
</section>
@@ -1788,7 +1788,7 @@
</pre>
<p>In this case the <code>@id</code> definition is optional, but if it does exist, the <tref>compact IRI</tref>
- or <tref>IRI</tref> is treated as a term (not a <code>prefix:suffix</code> construct)
+ or <tref>IRI</tref> is treated as a term (not a <code>prefix:suffix</code> construct)
so that the actual definition of a <tref>prefix</tref> becomes unnecessary.</p>
<p class="note">Keys in the context are treated as <tref title="term">terms</tref> for the purpose of
@@ -1796,18 +1796,18 @@
For example, one could specify that <code>dog</code> and <code>cat</code> both expanded to <code>http://example.com/vocab#animal</code>.
Doing this could be useful for establishing different type coercion or language specification rules. It also allows a <tref>compact IRI</tref> (or even an
absolute <tref>IRI</tref>) to be defined as something else entirely. For example, one could specify that
- the <tref>term</tref> <code>http://example.org/zoo</code> should expand to
- <code>http://example.org/river</code>, but this usage is discouraged because it would lead to a
+ the <tref>term</tref> <code>http://example.org/zoo</code> should expand to
+ <code>http://example.org/river</code>, but this usage is discouraged because it would lead to a
great deal of confusion among developers attempting to understand the JSON-LD document.</p>
-<p>Type coercion is performed using the unexpanded value of the key,
+<p>Type coercion is performed using the unexpanded value of the key,
which MUST have an exact match for an entry in the <tref>active context</tref>.</p>
</section>
<section>
<h3>IRI Expansion Within a Context</h3>
- <p>In general, normal IRI expansion rules apply
+ <p>In general, normal IRI expansion rules apply
anywhere an IRI is expected (see <a href="#iris">IRIs</a>). Within
a <tref>context</tref> definition, this can mean that terms defined
within the context MAY also be used within that context as long as
@@ -1867,7 +1867,7 @@
</pre>
<p><tref title="compact iri">Compact IRIs</tref>
- and <tref title="iri">IRIs</tref> MAY be used on the left-hand side of a
+ and <tref title="iri">IRIs</tref> MAY be used on the left-hand side of a
<tref>term</tref> definition.</p>
<pre class="example" data-transform="updateExample">
@@ -1900,7 +1900,7 @@
<code>@type</code> associated with the <tref>term</tref>. In the second
approach, only the <code>@type</code> associated with the <tref>term</tref> is
specified. The JSON-LD processor will derive the full <tref>IRI</tref> for
-<code>foaf:homepage</code> by looking up the <code>foaf</code>
+<code>foaf:homepage</code> by looking up the <code>foaf</code>
<tref>prefix</tref> in the
<tref>context</tref>.
</p>
@@ -1996,9 +1996,9 @@
<section>
<h2>Named Graphs</h2>
- <p>The <code>@graph</code> <tref>keyword</tref> is used to express a set of
- JSON-LD <tref>subject definition</tref>s that may not be directly related
- to one another through a property. The mechanism may also be used where
+ <p>The <code>@graph</code> <tref>keyword</tref> is used to express a set of
+ JSON-LD <tref>subject definition</tref>s that may not be directly related
+ to one another through a property. The mechanism may also be used where
<tref>embedding</tref> is not desirable to the application. For example:</p>
<pre class="example" data-transform="updateExample">
@@ -2051,13 +2051,13 @@
-->
</pre>
- <p>JSON-LD allows you to <em>name</em> things on the Web by assigning
+ <p>JSON-LD allows you to <em>name</em> things on the Web by assigning
an <code>@id</code> to them, which is typically an <tref>IRI</tref>.
This notion extends to the ability to identify graphs in the same
- manner. A developer may name data expressed using the <code>@graph</code>
- <tref>keyword</tref> by pairing it with an <code>@id</code>
- <tref>keyword</tref>. This enables the developer to make statements
- about the <tref>linked data graph</tref> itself,
+ manner. A developer may name data expressed using the <code>@graph</code>
+ <tref>keyword</tref> by pairing it with an <code>@id</code>
+ <tref>keyword</tref>. This enables the developer to make statements
+ about the <tref>linked data graph</tref> itself,
rather than just a single JSON-LD object.</p>
<pre class="example" data-transform="updateExample">
@@ -2086,7 +2086,7 @@
-->
</pre>
- <p>The example above expresses a <em>named</em>
+ <p>The example above expresses a <em>named</em>
<tref>linked data graph</tref> that is identified by the <tref>IRI</tref>
<code>http://example.org/graphs/73</code>. That graph is composed of the
statements about Manu and Gregg and a reference to another IRI, which could
@@ -2106,7 +2106,7 @@
<code>@id</code> <tref>keyword</tref>. However, authors may provide identifiers for
unlabeled nodes by using the special <code>_</code> (underscore)
<tref>prefix</tref>. This allows one to reference the node locally within the
-document, but makes it impossible to reference the node from an
+document, but makes it impossible to reference the node from an
external document. The <tref>unlabeled node</tref> identifier is scoped to the
document in which it is used.</p>
@@ -2133,10 +2133,10 @@
<section>
<h2>Aliasing Keywords</h2>
-<p>Each of the JSON-LD <tref title="keyword">keywords</tref>,
+<p>Each of the JSON-LD <tref title="keyword">keywords</tref>,
except for <code>@context</code>, MAY be aliased to application-specific
keywords. This feature allows legacy JSON content to be utilized
-by JSON-LD by re-using JSON keys that already exist in legacy documents.
+by JSON-LD by re-using JSON keys that already exist in legacy documents.
This feature also allows developers to design domain-specific implementations
using only the JSON-LD <tref>context</tref>.</p>
@@ -2165,10 +2165,10 @@
<section>
<h3>Expanded Document Form</h3>
-<p>The JSON-LD API [[JSON-LD-API]] defines an method for <em>expanding</em> a
+<p>The JSON-LD API [[JSON-LD-API]] defines an method for <em>expanding</em> a
JSON-LD document.
Expansion is the process of taking a JSON-LD document and applying a
- <code>@context</code> such that all IRIs, datatypes, and values
+ <code>@context</code> such that all IRIs, datatypes, and values
are expanded so that the <code>@context</code> is no longer necessary.</p>
<p>For example, assume the following JSON-LD input document:</p>
@@ -2211,7 +2211,7 @@
<p>Expanded document form is useful when an application has to process input
data in a deterministic form. It has been optimized to ensure that the code
that developers have to write is minimized compared to the code that would
-have to be written to operate on
+have to be written to operate on
<a href="#compact-document-form">compact document form</a>.</p>
</section>
@@ -2283,9 +2283,9 @@
application-specific compacted form by first <a href="#expanded-document-form">expanding the document</a>.
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. This powerful mechanism, along with another
- JSON-LD API technique called <em>framing</em>, allows the developer to
- re-shape the incoming JSON data into a format that is optimized for
+ provided by the developer. This powerful mechanism, along with another
+ JSON-LD API technique called <em>framing</em>, allows the developer to
+ re-shape the incoming JSON data into a format that is optimized for
their application.</p>
</section>
@@ -2299,7 +2299,7 @@
means that an invalid JSON document can never be a valid
JSON-LD document. Furthermore, JSON-LD places a number of restrictions on
the JSON syntax in order to define a set of authoring <em>guidelines</em>
-that is used to express <em>well-formed</em> JSON-LD documents. At times,
+that are used to express <em>well-formed</em> JSON-LD documents. At times,
even if these guidelines are violated, a JSON-LD processor will do its best
to recover from the mistake and will deterministically transform the author's
markup into well-formed JSON-LD.</p>
@@ -2361,7 +2361,7 @@
such as RDF, Turtle, RDFa, Microformats,
and Microdata. These sections are merely provided as proof that JSON-LD is
very flexible in what it can express across different <tref>Linked Data</tref> approaches.
- Further information on transforming JSON-LD into RDF are detailed in the
+ Further information on transforming JSON-LD into RDF are detailed in the
[[JSON-LD-API]].</p>
<section>
@@ -2386,7 +2386,7 @@
<section>
<h4>Prefix definitions</h4>
-<p>The JSON-LD context has direct equivalents for the Turtle
+<p>The JSON-LD context has direct equivalents for the Turtle
<code>@prefix</code> declaration:</p>
<pre class="example" data-transform="updateExample">
@@ -2415,8 +2415,8 @@
</pre>
<div class="note">
-<p>JSON-LD has no equivalent for the Turtle <code>@base</code> declaration.
- Instead, authors may use a prefix definition to resolve
+<p>JSON-LD has no equivalent for the Turtle <code>@base</code> declaration.
+ Instead, authors may use a prefix definition to resolve
<tref>relative IRI</tref>s:</p>
<pre class="example" data-transform="updateExample">
<!--
--- a/test-suite/tests/compact-0019-context.jsonld Wed May 23 22:32:46 2012 -0400
+++ b/test-suite/tests/compact-0019-context.jsonld Wed May 23 22:36:24 2012 -0400
@@ -1,3 +1,6 @@
{
- "@context": {"": "http://example.com/default#"}
-}
+ "@context": {
+ "mylist": {"@id": "http://example.com/mylist", "@container": "@list"},
+ "myset": {"@id": "http://example.com/myset", "@container": "@set"}
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-suite/tests/compact-0019-in.jsonld Wed May 23 22:36:24 2012 -0400
@@ -0,0 +1,16 @@
+[{
+ "@id": "http://example.org/id",
+ "http://example.com/mylist": [{
+ "@list": [
+ {"@value": 1},
+ {"@value": 2},
+ {"@value": 2},
+ {"@value": 3}
+ ]
+ }],
+ "http://example.com/myset": [
+ {"@value": 1},
+ {"@value": 2},
+ {"@value": 3}
+ ]
+}]
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-suite/tests/compact-0019-out.jsonld Wed May 23 22:36:24 2012 -0400
@@ -0,0 +1,9 @@
+{
+ "@context": {
+ "mylist": {"@id": "http://example.com/mylist", "@container": "@list"},
+ "myset": {"@id": "http://example.com/myset", "@container": "@set"}
+ },
+ "@id": "http://example.org/id",
+ "mylist": [1, 2, 2, 3],
+ "myset": [1, 2, 3]
+}
\ No newline at end of file
--- a/test-suite/tests/compact-manifest.jsonld Wed May 23 22:32:46 2012 -0400
+++ b/test-suite/tests/compact-manifest.jsonld Wed May 23 22:36:24 2012 -0400
@@ -113,5 +113,11 @@
"input": "compact-0018-in.jsonld",
"context": "compact-0018-context.jsonld",
"expect": "compact-0018-out.jsonld"
+ }, {
+ "@type": ["test:TestCase", "jld:CompactTest"],
+ "name": "Keep duplicate values in @list, remove from @set",
+ "input": "compact-0019-in.jsonld",
+ "context": "compact-0019-context.jsonld",
+ "expect": "compact-0019-out.jsonld"
}]
}
--- a/test-suite/tests/frame-0021-frame.jsonld Wed May 23 22:32:46 2012 -0400
+++ b/test-suite/tests/frame-0021-frame.jsonld Wed May 23 22:36:24 2012 -0400
@@ -1,6 +1,7 @@
{
"@context": {
"dc": "http://purl.org/dc/elements/1.1/",
- "ex": "http://example.org/vocab#"
+ "ex": "http://example.org/vocab#",
+ "dc:list": {"@container": "@list"}
}
}
\ No newline at end of file
--- a/test-suite/tests/frame-0021-in.jsonld Wed May 23 22:32:46 2012 -0400
+++ b/test-suite/tests/frame-0021-in.jsonld Wed May 23 22:36:24 2012 -0400
@@ -5,7 +5,8 @@
"xsd": "http://www.w3.org/2001/XMLSchema#",
"ex:contains": {
"@type": "@id"
- }
+ },
+ "dc:list": {"@container": "@list"}
},
"@graph": [
{
--- a/test-suite/tests/frame-0021-out.jsonld Wed May 23 22:32:46 2012 -0400
+++ b/test-suite/tests/frame-0021-out.jsonld Wed May 23 22:36:24 2012 -0400
@@ -1,7 +1,8 @@
{
"@context": {
"dc": "http://purl.org/dc/elements/1.1/",
- "ex": "http://example.org/vocab#"
+ "ex": "http://example.org/vocab#",
+ "dc:list": {"@container": "@list"}
},
"@graph": [
{
@@ -20,7 +21,7 @@
"@type": "ex:Chapter",
"dc:description": "An introductory chapter on The Republic.",
"dc:title": "The Introduction",
- "dc:list": [1, 2, 3, 4, 5]
+ "dc:list": [1, 2, 3, 4, 4, 4, 5]
}
}
}, {
@@ -31,7 +32,7 @@
"@type": "ex:Chapter",
"dc:description": "An introductory chapter on The Republic.",
"dc:title": "The Introduction",
- "dc:list": [1, 2, 3, 4, 5]
+ "dc:list": [1, 2, 3, 4, 4, 4, 5]
},
"dc:creator": "Plato",
"dc:title": "The Republic"
@@ -39,7 +40,7 @@
"@id": "http://example.org/library/the-republic#introduction",
"@type": "ex:Chapter",
"dc:description": "An introductory chapter on The Republic.",
- "dc:list": [1, 2, 3, 4, 5],
+ "dc:list": [1, 2, 3, 4, 4, 4, 5],
"dc:title": "The Introduction"
}]
}
\ No newline at end of file