Update expansion algorithm to handle aliases properly
authorMarkus Lanthaler <mark_lanthaler@gmx.net>
Sat, 07 Apr 2012 17:07:40 +0800
changeset 471 b0efa2159af1
parent 470 cfdea5a0c615
child 472 3c9c1ab0f954
Update expansion algorithm to handle aliases properly
spec/latest/json-ld-api/index.html
--- a/spec/latest/json-ld-api/index.html	Sat Apr 07 12:22:10 2012 +0800
+++ b/spec/latest/json-ld-api/index.html	Sat Apr 07 17:07:40 2012 +0800
@@ -1173,91 +1173,68 @@
 <h3>Expansion Algorithm</h3>
 
 <p>The algorithm takes three input variables: an <tref>active context</tref>, an <tref>active property</tref>,
-  and a <em>value</em> to be expanded. To begin, the <tref>active context</tref> is set to the <tref>initial
-  context</tref>, <tref>active property</tref> is set to <tref>null</tref>, and <em>value</em> is set to the <tref>JSON-LD
+  and an <em>element</em> to be expanded. To begin, the <tref>active context</tref> is set to the <tref>initial
+  context</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 item in <em>element</em> recursively
-    using this algorithm, passing copies of the <tref>active context</tref> and <tref>active property</tref>
-    and removing null entries. If any result is a <tref>JSON Object</tref> with a property of <code>@set</code>
-    (or alias thereof), remove that object, and append the array value to <em>element</em>.</li>
+  <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 the expanded entry is null, drop it. If it's an array, merge it's entries with <em>element</em>'s entries
+    unless the <tref>active property</tref> equals <code>@list</code> or has a <code>@container</code> set to <code>@list</code>;
+    in that case throw an exception as lists of lists are not allowed.</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>
+      <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>For each <em>property</em> and <em>value</em> in <em>element</em>:
+      <li>Then, proceed and process each <em>property</em> and <em>value</em> in <em>element</em> as follows:
         <ol class="algorithm">
-          <li>Set <em>property</em> as <tref>active property</tref> and the result
-            of performing <a href="#iri-expansion">IRI Expansion</a> on <em>property</em> as
-          <li>If <em>property</em> does not expand to a keyword or <tref>absolute IRI</tref>, remove
-            <em>property</em> from <em>element</em> and continue to the next property from
-            <em>element</em>.</li>
-          <li>If <em>expanded property</em> is <em>@value</em> and <em>value</em> is <code>null</code>,
-            skip further processing and return <code>null</code> as the expanded version of
-            <em>element</em>.</li>
-          <li>If <em>value</em> is <tref>null</tref>, remove <em>property</em> from <em>element</em>
-            and continue with the next property from <em>element</em>.</li>
-          <li>Otherwise, if <em>value</em> is a <tref>JSON object</tref> having either a <code>@value</code>,
-            <code>@list</code>, or <code>@set</code> property (or an alias thereof) with a <tref>null</tref> value,
-            remove <em>property</em> from <em>element</em> and continue with the next property from <em>element</em>.</li>
-            <em>expanded property</em>.</li>
-          <li>If <em>value</em> is a <tref>JSON object</tref> having a <code>@set</code>
-            property (or an alias thereof) with a non-<tref>null</tref> value, replace <em>value</em> with the
-            value of <code>@set</code>.</li>
-          <li>Otherwise, if <em>value</em> is a <tref>JSON object</tref> having a <code>@list</code> property
-            (or an alias thereof), that value MUST be an array. Process each entry of <em>value</em>
-            recursively using this algorithm, passing copies of the <tref>active context</tref> and
-            <tref>active property</tref> removing all <tref>null</tref> entries.
-            Add an entry in the output object for <em>expanded property</em> with value and continue to the
-            next entry in <em>element</em>.
-            If the output object already has a value for <em>expanded property</em>, throw an exception.
-            Continue with the next property from <em>element</em>.
-            <p class="issue">This is currently being discussed in <a href="https://github.com/json-ld/json-ld.org/issues/92">ISSUE 92</a></p>
-          </li>
-          <li>If the <em>expanded property</em> is <code>@id</code> the <em>value</em> MUST be a <tref>string</tref>.
+          <li>Remove <em>property</em> from <em>element</em>, set the <tref>active property</tref> to <em>property</em> and expand
+            <em>property</em> according to the steps outlined in <a href="#iri-expansion">IRI Expansion</a>.</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>expanded property</em> is <code>@type</code>:
-            <ol class="algorithm">
-              <li>If <em>value</em> is a <tref>string</tref> expand <em>value</em>
-                according to <a href="#iri-expansion">IRI Expansion</a>.
-                If <em>element</em> has no <code>@value</code> property (or an alias thereof),
-                replace <em>value</em> with an array whose only value is the expanded <em>value</em>.</li>
-              <li>Otherwise, if <em>value</em> is an <tref>array</tref>, expand every entry according to
-                <a href="#iri-expansion">IRI Expansion</a>.
-                Element MUST NOT have a <code>@value</code> property in this case.</li>
-              <li>If <em>value</em> expands to <code>nil</code>, remove <em>property</em>
-                from <em>element</em> and continue to next property.</li>
-            </ol>
-          </li>
-          <li>Otherwise, if the <em>expanded property</em> is <code>@value</code> or <code>@language</code>, the <em>value</em>
-            is not subject to further expansion.</li>
-          <li>Otherwise, if the <em>expanded property</em> is <code>@graph</code>,
-            replace the entire object with the result of performing this algorithm on the members
-            of the <em>value</em> and terminate further processing of this object.</li>
-          <li>Process <em>value</em> as follows:
-            <ol class="algorithm">
-              <li>If the <em>value</em> is an <tref>array</tref>, and <tref>active property</tref>
-                is subject to <code>@list</code> expansion, replace <em>value</em> with a
-                new object where the key is <code>@list</code> and value set to the
-                current <em>value</em> updated by recursively using this algorithm.</li>
-              <li>Otherwise, if <em>value</em> is not an <tref>array</tref>, replace <em>value</em>
-                with an array containing <em>value</em>.</li>
-              <li>Process each item in <em>value</em> recursively using this algorithm,
-                passing copies of the <tref>active context</tref> and <tref>active property</tref>.</li>
-            </ol>
-          </li>
-          <li>If output object already contains an entry for <em>expanded property</em>, append <em>value</em> to
-            the existing value, which MUST be an <tref>array</tref>.</li>
-          <li>Otherwise, add <em>expanded property</em> to output object with <em>value</em>.</li>
+          <li>Otherwise, if the <em>property</em> is <code>@type</code> the <em>value</em> MUST be a <tref>string</tref> or an
+            <tref>array</tref> of <tref>string</tref>s. Expand <em>value</em> or each of it's entries according to
+            <a href="#iri-expansion">IRI Expansion</a>.</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>, <code>@set</code>, or <code>@graph</code>, expand <em>value</em>
+            recursively using this algorithm, passing copies of the <tref>active context</tref> and <em>property</em>. If the expanded
+            <em>value</em> is not an <tref>array</tref>, convert it to an <tref>array</tref>.</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 the expanded <em>value</em> is not <tref>null</tref> and the <tref>active property</tref> has a <code>@container</code>
+            set to <code>@list</code>, 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>If <em>element</em> already contains a <em>property</em> property, append <em>value</em> to the existing value.</li>
+          <li>Otherwise, create a <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 <code>@value</code> is the only property or 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 it's 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>, <code>@list</code>, or <code>@graph</code> property, it MUST be the only property.
+        Set <em>element</em> to the value of <code>@set</code> or <code>@graph</code>; leave <code>@list</code> untouched.
+        <p class="issue">Whether <code>@graph</code> should always be dropped or not is currently being discussed in <a href="https://github.com/json-ld/json-ld.org/issues/99">ISSUE-99</a></p>
+      </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 <tref>active property</tref>.</li>
+    passing copies of the <tref>active context</tref> and <tref>active property</tref>.</li>
 </ol>
 </section>