Skip to content

Commit 89f571e

Browse files
authored
Merge pull request #453 from json-ld/issue-246-nesting2
This adds a `@nest` member to term definitions used for _transparent properties_
2 parents 85bf7dd + bc97d88 commit 89f571e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+796
-16
lines changed

spec/latest/common/terms.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ <h1>General Terminology</h1>
180180
specified via the <code>@context</code> <a>keyword</a>.</dd>
181181
<dt><dfn data-lt="named graphs">named graph</dfn></dt><dd>
182182
A <a>linked data graph</a> that is identified by an <a>IRI</a> or <a>blank node</a>
183+
<dt><dfn data-lt="nested properties">nested property</dfn></dt><dd>
184+
A <a>nested property</a> is a <a>property</a> which is contained within an object referenced by
185+
a semantically meaningless <em>nesting property</em>.
186+
</dd>
183187
(the <a>graph name</a>) and a <a>graph</a>.</dd>
184188
<dt><dfn data-lt="nodes">node</dfn></dt><dd>
185189
Every <a>node</a> is an <a>IRI</a>, a <a>blank node</a>,

spec/latest/json-ld-api/index.html

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ <h3>Algorithm</h3>
903903
</li>
904904
<li>If <em>value</em> contains the key <code>@reverse</code>:
905905
<ol class="algorithm">
906-
<li>If <em>value</em> contains an <code>@id</code>, member, an
906+
<li>If <em>value</em> contains <code>@id</code> or <code>@nest</code>, members, an
907907
<a data-link-for="JsonLdErrorCode">invalid reverse property</a>
908908
error has been detected and processing is aborted.</li>
909909
<li>If the value associated with the <code>@reverse</code> key
@@ -1020,9 +1020,18 @@ <h3>Algorithm</h3>
10201020
of <em>definition</em> to <em>language</em>.</li>
10211021
</ol>
10221022
</li>
1023+
<li class="changed">If <em>value</em> contains the key <code>@nest</code>:
1024+
<ol class="algorithm">
1025+
<li>Initialize <em>nest</em> to the value associated with the
1026+
<code>@nest</code> key, which must be a <a>string</a> and
1027+
must not be a keyword other than <code>@nest</code>. Otherwise, an
1028+
<a data-link-for="JsonLdErrorCode">invalid @nest value</a>
1029+
error has been detected and processing is aborted.</li>
1030+
</ol>
1031+
</li>
10231032
<li>If the value contains any key other than <code>@id</code>,
10241033
<code>@reverse</code>, <code>@container</code>,
1025-
<code>@context</code>, or <code>@type</code>, an
1034+
<code>@context</code>, <code class="changed">@nest</code>, or <code>@type</code>, an
10261035
<a data-link-for="JsonLdErrorCode">invalid term definition</a> error has
10271036
been detected and processing is aborted.</li>
10281037
<li>Set the <a>term definition</a> of <em>term</em> in
@@ -1270,7 +1279,7 @@ <h3>Algorithm</h3>
12701279
passing <a>active context</a> and the value of the
12711280
<code>@context</code> key as <a>local context</a>.</li>
12721281
<li>Initialize an empty <a>JSON object</a>, <em>result</em>.</li>
1273-
<li>For each <em>key</em> and <em>value</em> in <em>element</em>,
1282+
<li id="alg-expand-each-key-value">For each <em>key</em> and <em>value</em> in <em>element</em>,
12741283
ordered lexicographically by <em>key</em>:
12751284
<ol class="algorithm">
12761285
<li>If <em>key</em> is <code>@context</code>, continue to
@@ -1418,6 +1427,10 @@ <h3>Algorithm</h3>
14181427
<li>Continue with the next <em>key</em> from <em>element</em>.</li>
14191428
</ol>
14201429
</li>
1430+
<li class="changed">If <em>expanded property</em> is <code>@nest</code>,
1431+
add <em>key</em> to <em>nests</em>, initializing it to an empty <a>array</a>,
1432+
if necessary.
1433+
Continue with the next <em>key</em> from <em>element</em>.</li>
14211434
<li class="changed">When the <code>frame expansion</code> flag is set,
14221435
if <em>expanded property</em> is any other
14231436
framing keyword (<code>@explicit</code>, <code>@default</code>,
@@ -1559,6 +1572,22 @@ <h3>Algorithm</h3>
15591572
member of <em>result</em>.</li>
15601573
</ol>
15611574
</li>
1575+
<li class="changed">For each key <em>nesting-key</em> in <em>nests</em>
1576+
<ol class="algorithm">
1577+
<li>Set <em>nested values</em> to the value of <em>nesting-key</em>
1578+
in <em>element</em>, ensuring that it is an <a>array</a>.</li>
1579+
<li>For each <em>nested value</em> in <em>nested values</em>:
1580+
<ol class="algorithm">
1581+
<li>If <em>nested value</em> is not a <a>JSON object</a>, or any key within
1582+
<em>nested value</em> expands to <code>@value</code>, an
1583+
<a data-link-for="JsonLdErrorCode">invalid @nest value</a> error
1584+
has been detected and processing is aborted.</li>
1585+
<li>Recursively repeat <a href="#alg-expand-each-key-value">step 7</a>
1586+
using <em>nested value</em> for <em>element</em>.</li>
1587+
</ol>
1588+
</li>
1589+
</ol>
1590+
</li>
15621591
</ol>
15631592
</li>
15641593
<li>If <em>result</em> contains the key <code>@value</code>:
@@ -1942,7 +1971,22 @@ <h3>Algorithm</h3>
19421971
<em>expanded value</em> for <em>value</em>,
19431972
<code>true</code> for <em>vocab</em>, and
19441973
<em>inside reverse</em>.</li>
1945-
<li>If <em>result</em> does not have the key that equals
1974+
<li class="changed">If the <a>term definition</a> for <em>item active property</em>
1975+
in the <em>active context</em> has a <code>@nest</code>
1976+
member, that value (<em>nest term</em>) must be
1977+
<code>@nest</code>, or a <a>term definition</a> in the
1978+
<em>active context</em> that expands to <code>@nest</code>,
1979+
otherwise an <a data-link-for="JsonLdErrorCode">invalid @nest
1980+
value</a> error has been detected, and processing is aborted.
1981+
If <em>result</em> does not have the key that equals <em>nest
1982+
term</em>, initialize it to an empty JSON object (<em>nest
1983+
object</em>). If <em>nest object</em> does not have the key
1984+
that equals <em>item active property</em>, set this key's
1985+
value in <em>nest object</em> to an empty
1986+
<a>array</a>.Otherwise, if the key's value is not an
1987+
<a>array</a>, then set it to one containing only the
1988+
value.</li>
1989+
<li>Otherwise, if <em>result</em> does not have the key that equals
19461990
<em>item active property</em>, set this key's value in
19471991
<em>result</em> to an empty <a>array</a>. Otherwise, if
19481992
the key's value is not an <a>array</a>, then set it
@@ -1962,6 +2006,16 @@ <h3>Algorithm</h3>
19622006
<em>expanded item</em> for <em>value</em>,
19632007
<code>true</code> for <em>vocab</em>, and
19642008
<em>inside reverse</em>.</li>
2009+
<li class="changed">If the <a>term definition</a> for <em>item active property</em>
2010+
in the <em>active context</em> has a <code>@nest</code>
2011+
member, that value (<em>nest term</em>) must be
2012+
<code>@nest</code>, or a <a>term definition</a> in the
2013+
<em>active context</em> that expands to <code>@nest</code>,
2014+
otherwise an <a data-link-for="JsonLdErrorCode">invalid @nest
2015+
value</a> error has been detected, and processing is aborted.
2016+
Set <em>nest result</em> to the value of <em>nest term</em> in <em>result</em>,
2017+
initializing it to a new <a>JSON object</a>, if necessary; otherwise
2018+
set <em>nest result</em> to <em>result</em>.</li>
19652019
<li>Initialize <em>container</em> to <code>null</code>. If there
19662020
is a <a>container mapping</a> for
19672021
<em>item active property</em> in <a>active context</a>,
@@ -1999,7 +2053,7 @@ <h3>Algorithm</h3>
19992053
</ol>
20002054
</li>
20012055
<li>Otherwise, <em>item active property</em> must not be a key
2002-
in <em>result</em> because there cannot be two
2056+
in <em class="changed">nest result</em> because there cannot be two
20032057
<a>list objects</a> associated
20042058
with an <a>active property</a> that has a
20052059
<a>container mapping</a>; a
@@ -2013,14 +2067,17 @@ <h3>Algorithm</h3>
20132067
or <code>@type</code></span>:
20142068
<ol class="algorithm">
20152069
<li>If <em>item active property</em> is not a key in
2016-
<em>result</em>, initialize it to an empty <a>JSON object</a>.
2070+
<em class="changed">nest result</em>, initialize it to an empty <a>JSON object</a>.
20172071
Initialize <em>map object</em> to the value of <em>item active property</em>
2018-
in <em>result</em>.</li>
2072+
in <em class="changed">nest result</em>.</li>
20192073
<li>Set <em>compacted container</em> to the result of calling the
20202074
<a href="#iri-compaction">IRI Compaction algorithm</a>
20212075
passing <a>active context</a>,
20222076
<em>container</em> as <em>iri</em>, and <code>true</code>
20232077
for <em>vocab</em>.</li>
2078+
<li>Initialize <em>map key</em> to the value associated with
2079+
with the key that equals <em>container</em> in
2080+
<em>expanded item</em>.</li>
20242081
<li>If <em>container</em> is <code>@language</code> and
20252082
<em>compacted item</em> contains the key
20262083
<code>@value</code>, then set <em>compacted item</em>
@@ -2063,9 +2120,9 @@ <h3>Algorithm</h3>
20632120
<li>If <em>item active property</em> is not a key in
20642121
<em>result</em> then add the key-value pair,
20652122
(<em>item active property</em>-<em>compacted item</em>),
2066-
to <em>result</em>.</li>
2123+
to <em class="changed">nest result</em>.</li>
20672124
<li>Otherwise, if the value associated with the key that
2068-
equals <em>item active property</em> in <em>result</em>
2125+
equals <em>item active property</em> in <em class="changed">nest result</em>
20692126
is not an <a>array</a>, set it to a new
20702127
<a>array</a> containing only the value. Then
20712128
append <em>compacted item</em> to the value if
@@ -4082,6 +4139,7 @@ <h4>JsonLdErrorCode</h4>
40824139
"cyclic IRI mapping",
40834140
"invalid @id value",
40844141
"invalid @index value",
4142+
"invalid @nest value",
40854143
"invalid @reverse value",
40864144
"invalid base IRI",
40874145
"invalid container mapping",
@@ -4133,6 +4191,8 @@ <h4>JsonLdErrorCode</h4>
41334191
<dt><dfn>invalid @index value</dfn></dt>
41344192
<dd>An <code>@index</code> member was encountered whose value was
41354193
not a <a>string</a>.</dd>
4194+
<dt class="changed"><dfn>invalid @nest value</dfn></dt>
4195+
<dd class="changed">An invalid value for <code>@nest</code> has been found.</dd>
41364196
<dt><dfn>invalid @reverse value</dfn></dt>
41374197
<dd>An invalid value for an <code>@reverse</code> member has been detected,
41384198
i.e., the value was not a <a>JSON object</a>.</dd>
@@ -4242,6 +4302,12 @@ <h2>Changes since 1.0 Recommendation of 16 January 2014</h2>
42424302
<li>A new <a href="#merge-node-maps" class="sectionRef"></a> is required
42434303
for framing, to create a single graph from the <a data-lt="default graph">default</a>
42444304
and <a>named graphs</a>.</li>
4305+
<li>An <a>expanded term definition</a> can now have an
4306+
<code>@nest</code> property, which identifies a term expanding to
4307+
<code>@nest</code> which is used for containing properties using the same
4308+
<code>@nest</code> mapping. When expanding, the values of a property
4309+
expanding to <code>@nest</code> are treated as if they were contained
4310+
within the enclosing <a>node object</a> directly.</li>
42454311
<li><code>@container</code> values within an <a>expanded term definition</a> may now
42464312
include <code>@id</code> and <code>@type</code>, corresponding to <a>id maps</a> and <a>type maps</a>.</li>
42474313
</ul>

spec/latest/json-ld/index.html

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,8 @@ <h2>Syntax Tokens and Keywords</h2>
395395
<a>IRI</a>. This keyword is described in <a class="sectionRef" href="#default-vocabulary"></a>.</dd>
396396
<dt><code>@graph</code></dt><dd>Used to express a <a>graph</a>.
397397
This keyword is described in <a class="sectionRef" href="#named-graphs"></a>.</dd>
398+
<dt class="changed"><code>@nest</code></dt><dd class="changed">Collects a set of <a>nested properties</a> within
399+
a <a>node object</a>.</dd>
398400
<dt><code>:</code></dt>
399401
<dd>The separator for JSON keys and values that use
400402
<a>compact IRIs</a>.</dd>
@@ -2684,6 +2686,85 @@ <h2>Node Type Indexing</h2>
26842686
as the <code>@type</code> property of the <a>node object</a> value.</p>
26852687
</section>
26862688

2689+
<section class="informative changed">
2690+
<h2>Nested Properties</h2>
2691+
2692+
<p>Many JSON APIs separate properties from their entities using an
2693+
intermediate object; in JSON-LD these are called <a>nested properties</a>.
2694+
For example, a set of possible labels may be grouped
2695+
under a common property:</p>
2696+
<pre class="example" data-transform="updateExample"
2697+
title="Nested properties">
2698+
<!--
2699+
{
2700+
"@context": {
2701+
"skos": "http://www.w3.org/2004/02/skos/core#",
2702+
****"labels": "@nest"****,
2703+
"main_label": {"@id": "skos:prefLabel"},
2704+
"other_label": {"@id": "skos:altLabel"},
2705+
"homepage": {"@id": "http://schema.org/description", "@type": "@id"}
2706+
},
2707+
"@id": "http://example.org/myresource",
2708+
"homepage": "http://example.org",
2709+
"labels": {
2710+
"main_label": "This is the main label for my resource",
2711+
"other_label": "This is the other label"
2712+
}
2713+
}
2714+
-->
2715+
</pre>
2716+
2717+
<p>By defining <em>labels</em> using the <a>keyword</a> <code>@nest</code>,
2718+
a <a>JSON-LD processor</a> will ignore the nesting created by using the
2719+
<em>labels</em> property and process the contents as if it were declared
2720+
directly within containing object. In this case, the <em>labels</em>
2721+
property is semantically meaningless. Defining it as equivalent to
2722+
<code>@nest</code> causes it to be ignored when expanding, making it
2723+
equivalent to the following:</p>
2724+
2725+
<pre class="example" data-transform="updateExample"
2726+
title="Nested properties folded into containing object">
2727+
<!--
2728+
{
2729+
"@context": {
2730+
"skos": "http://www.w3.org/2004/02/skos/core#",
2731+
"main_label": {"@id": "skos:prefLabel"},
2732+
"other_label": {"@id": "skos:altLabel"},
2733+
"homepage": {"@id": "http://schema.org/description", "@type": "@id"}
2734+
},
2735+
"@id": "http://example.org/myresource",
2736+
"homepage": "http://example.org",
2737+
****"main_label": "This is the main label for my resource",
2738+
"other_label": "This is the other label"****
2739+
}
2740+
-->
2741+
</pre>
2742+
2743+
<p>Similarly, node definitions may contain a <code>@nest</code> property to
2744+
reference a term aliased to <code>@nest</code> which causes such
2745+
values to be nested under that aliased term.</p>
2746+
<pre class="example" data-transform="updateExample"
2747+
title="Defining property nesting">
2748+
<!--
2749+
{
2750+
"@context": {
2751+
"skos": "http://www.w3.org/2004/02/skos/core#",
2752+
****"labels": "@nest"****,
2753+
"main_label": {"@id": "skos:prefLabel", ****"@nest": "labels"****},
2754+
"other_label": {"@id": "skos:altLabel", ****"@nest": "labels"****},
2755+
"homepage": {"@id": "http://schema.org/description", "@type": "@id"}
2756+
},
2757+
"@id": "http://example.org/myresource",
2758+
"homepage": "http://example.org",
2759+
"labels": {
2760+
"main_label": "This is the main label for my resource",
2761+
"other_label": "This is the other label"
2762+
}
2763+
}
2764+
-->
2765+
</pre>
2766+
</section>
2767+
26872768
<section class="informative">
26882769
<h3>Expanded Document Form</h3>
26892770

@@ -3090,6 +3171,7 @@ <h2>Node Objects</h2>
30903171
<li><code>@context</code>,</li>
30913172
<li><code>@id</code>,</li>
30923173
<li><code>@graph</code>,</li>
3174+
<li class="changed"><code>@nest</code>,</li>
30933175
<li><code>@type</code>,</li>
30943176
<li><code>@reverse</code>, or</li>
30953177
<li><code>@index</code></li>
@@ -3145,6 +3227,12 @@ <h2>Node Objects</h2>
31453227
<a class="sectionRef" href="#data-indexing"></a> for further discussion
31463228
on <code>@index</code> values.</p>
31473229

3230+
<p class="changed">If the <a>node object</a> contains the <code>@nest</code> key,
3231+
its value MUST be an <a>JSON object</a> or an <a>array</a> of <a>JSON objects</a>
3232+
which MUST NOT include a <a>value object</a>. See
3233+
<a class="sectionRef" href="#property-nesting"></a> for further discussion
3234+
on <code>@nest</code> values.</p>
3235+
31483236
<p>Keys in a <a>node object</a> that are not
31493237
<a>keyword</a> MAY expand to an <a>absolute IRI</a>
31503238
using the <a>active context</a>. The values associated with keys that expand
@@ -3315,6 +3403,19 @@ <h2>Type Maps</h2>
33153403
the <code>@id</code> of the <a>node object</a> value when expanding.</p>
33163404
</section>
33173405

3406+
<section class="changed">
3407+
<h2>Property Nesting</h2>
3408+
3409+
<p>A <a>nested property</a> is used to gather <a>properties</a> of a <a>node object</a> in a separate
3410+
<a>JSON object</a>, or <a>array</a> of <a>JSON objects</a> which are not
3411+
<a>value objects</a>. It is semantically transparent and is removed
3412+
during the process of expansion. Property nesting is recursive, and
3413+
collections of nested properties may contain further nesting.</p>
3414+
3415+
<p>Semantically, nesting is treated as if the properties and values were declared directly
3416+
within the containing <a>node object</a>.</p>
3417+
</section>
3418+
33183419
<section class="normative">
33193420
<h2>Context Definitions</h2>
33203421

@@ -3354,7 +3455,7 @@ <h2>Context Definitions</h2>
33543455
<a>expanded term definition</a> SHOULD NOT contain any other keys.</p>
33553456

33563457
<p>If an <a>expanded term definition</a> has an <code>@reverse</code> member,
3357-
it MUST NOT have an <code>@id</code> member at the same time. If an
3458+
it MUST NOT have <code>@id</code> or <code>@nest</code> members at the same time. If an
33583459
<code>@container</code> member exists, its value MUST be <a>null</a>,
33593460
<code>@set</code>, or <code>@index</code>.</p>
33603461

@@ -3392,6 +3493,10 @@ <h2>Context Definitions</h2>
33923493
the definition of a term cannot depend on the definition of another term if that other
33933494
term also depends on the first term.</p>
33943495

3496+
<p>If the <a>expanded term definition</a> contains the <code>@nest</code>
3497+
<a>keyword</a>, its value MUST be either <code>@nest</code>, or a term
3498+
which expands to <code>@nest</code>.</p>
3499+
33953500
<p>See <a class="sectionRef" href="#the-context"></a> for further discussion on contexts.</p>
33963501
</section>
33973502

@@ -3582,6 +3687,12 @@ <h2>Changes since 1.0 Recommendation of 16 January 2014</h2>
35823687
a <a>property</a> identified with such a <a>term</a>.</li>
35833688
<li><code>@container</code> values within an <a>expanded term definition</a> may now
35843689
include <code>@id</code> and <code>@type</code>, corresponding to <a>id maps</a> and <a>type maps</a>.</li>
3690+
<li>An <a>expanded term definition</a> can now have an
3691+
<code>@nest</code> property, which identifies a term expanding to
3692+
<code>@nest</code> which is used for containing properties using the same
3693+
<code>@nest</code> mapping. When expanding, the values of a property
3694+
expanding to <code>@nest</code> are treated as if they were contained
3695+
within the enclosing <a>node object</a> directly.</li>
35853696
</ul>
35863697
</section>
35873698

0 commit comments

Comments
 (0)