Skip to content

Commit 1aee238

Browse files
committed
Support JSON Literals. Uses JCS normatively for RDF output, with atrisk issue.
For w3c/json-ld-syntax#4.
1 parent 42d1159 commit 1aee238

Some content is hidden

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

93 files changed

+824
-10
lines changed

Gemfile.lock

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
GIT
22
remote: git://github.com/ruby-rdf/json-ld.git
3-
revision: d88f81b143a602a6174b8b9da79c2fc6c04d127b
3+
revision: 2a11745bc50eab0d5a4c5c3a5cd98b840176896e
44
branch: develop
55
specs:
66
json-ld (3.0.2)
7+
json-canonicalization (~> 0.1)
78
link_header (~> 0.0, >= 0.0.8)
89
multi_json (~> 1.13)
910
rack (>= 1.6, < 3.0)
@@ -33,6 +34,7 @@ GEM
3334
htmlentities (4.3.4)
3435
i18n (1.6.0)
3536
concurrent-ruby (~> 1.0)
37+
json-canonicalization (0.1.0)
3638
json-ld-preloaded (3.0.2)
3739
json-ld (~> 3.0)
3840
multi_json (~> 1.12)

index.html

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,10 @@ <h2>RDF Serialization/Deserialization</h2>
894894
<th>IRI</th>
895895
</tr></thead>
896896
<tbody>
897+
<tr>
898+
<td>jsonld</td>
899+
<td>http://www.w3.org/ns/json-ld#</td>
900+
</tr>
897901
<tr>
898902
<td>rdf</td>
899903
<td>http://www.w3.org/1999/02/22-rdf-syntax-ns#</td>
@@ -1247,7 +1251,7 @@ <h3>Algorithm</h3>
12471251
<code>true</code> for <var>vocab</var>,
12481252
<var>local context</var>, and <var>defined</var>. If the expanded <var>type</var> is
12491253
neither <code>@id</code>, nor <code>@vocab</code>,
1250-
<span class="changed">nor, if <a>processing mode</a> is <code>json-ld-1.1</code>, <code>@none</code>,</span>
1254+
<span class="changed">nor, if <a>processing mode</a> is <code>json-ld-1.1</code>, <code>@json</code> nor <code>@none</code>,</span>
12511255
nor an <a>absolute IRI</a>, an
12521256
<a data-link-for="JsonLdErrorCode">invalid type mapping</a>
12531257
error has been detected and processing is aborted.</li>
@@ -1715,7 +1719,12 @@ <h3>Algorithm</h3>
17151719
</ol>
17161720
</li>
17171721
<li>Initialize an empty <a class="changed">dictionary</a>, <var>result</var>.</li>
1718-
<li id="alg-expand-each-key-value">For each <var>key</var> and <var>value</var> in <var>element</var>,
1722+
<li id="alg-expand-each-key-value">
1723+
<span class="changed">
1724+
Initialize an empty <a>dictionary</a>, <var>nests</var>, and
1725+
<var>input type</var> to the last value of any <a>member</a> expanding to <code>@type</code>.
1726+
</span>
1727+
For each <var>key</var> and <var>value</var> in <var>element</var>,
17191728
ordered lexicographically by <var>key</var> <span class="changed">if <a data-link-for="JsonLdOptions">ordered</a> is <code>true</code></span>:
17201729
<ol>
17211730
<li>If <var>key</var> is <code>@context</code>, continue to
@@ -1778,7 +1787,11 @@ <h3>Algorithm</h3>
17781787
and <a data-link-for="JsonLdOptions">ordered</a> flags</span>,
17791788
<span class="changed">
17801789
ensuring that <var>expanded value</var> is an <a>array</a> of one or more <a>dictionaries</a></span>.</li>
1781-
<li>If <var>expanded property</var> is <code>@value</code> and
1790+
<li>Otherwise, if <var>expanded property</var> is <code>@value</code>,
1791+
<span class="changed"><a>processing mode</a> is <code>json-ld-1.1</code>, and
1792+
<var>input type</var> is <code>@json</code>,
1793+
set <var>expanded value</var> to <var>value</var>.
1794+
Otherwise, if</span>
17821795
<var>value</var> is not a <a>scalar</a> or <code>null</code>, an
17831796
<a data-link-for="JsonLdErrorCode">invalid value object value</a>
17841797
error has been detected and processing is aborted. Otherwise,
@@ -1903,7 +1916,11 @@ <h3>Algorithm</h3>
19031916
set <var>term context</var> to <var>active context</var>.</li>
19041917
<li>Set <var>container mapping</var> to <var>key</var>'s <a>container mapping</a> in
19051918
<var class="changed">term context</var>.</li>
1906-
<li>If <var>container mapping</var> <span class="changed">includes</span> <code>@language</code> and
1919+
<li class="changed">If <var>key</var>'s <a>term definition</a> in <var>active context</var>
1920+
has a <a>type mapping</a> of <code>@json</code>,
1921+
set <var>expanded value</var> to a new <a>dictionary</a> the the <a>member</a>
1922+
<code>@value</code> set to <var>value</var>, and <code>@type</code> set to <code>@json</code>.</li>
1923+
<li>Otherwise, if <var>container mapping</var> <span class="changed">includes</span> <code>@language</code> and
19071924
<var>value</var> is a <a class="changed">dictionary</a> then <var>value</var>
19081925
is expanded from a <a>language map</a>
19091926
as follows:
@@ -2077,7 +2094,7 @@ <h3>Algorithm</h3>
20772094
<var>nested value</var> expands to <code>@value</code>, an
20782095
<a data-link-for="JsonLdErrorCode">invalid @nest value</a> error
20792096
has been detected and processing is aborted.</li>
2080-
<li>Recursively repeat <a href="#alg-expand-each-key-value">step 7</a>
2097+
<li>Recursively repeat <a href="#alg-expand-each-key-value">step 9</a>
20812098
using <var>nested value</var> for <var>element</var>.</li>
20822099
</ol>
20832100
</li>
@@ -2096,6 +2113,9 @@ <h3>Algorithm</h3>
20962113
error has been detected and processing is aborted.</li>
20972114
<li>If the value of <var>result</var>'s <code>@value</code> <a>member</a> is
20982115
<code>null</code>, then set <var>result</var> to <code>null</code>.</li>
2116+
<li class="changed">Otherwise, if the <var>result</var>'s <code>@type</code> <a>member</a>
2117+
is <code>@json</code>, then the <code>@value</code> <a>member</a> may
2118+
contain any value, and is treated as a <a>JSON literal</a>.</li>
20992119
<li>Otherwise, if the value of <var>result</var>'s <code>@value</code> <a>member</a>
21002120
is not a <a>string</a> and <var>result</var> contains the <a>member</a>
21012121
<code>@language</code>, an
@@ -2220,7 +2240,7 @@ <h3>Algorithm</h3>
22202240
<var>value</var>.</li>
22212241
<li>If <var>active property</var> has a <a>type mapping</a> in
22222242
<var>active context</var>,
2223-
<span class="changed">other than <code>@id</code> or <code>@vocab</code>, or <code>@none</code>,</span>
2243+
<span class="changed">other than <code>@id</code>, <code>@vocab</code>, or <code>@none</code>,</span>
22242244
add an <code>@type</code> <a>member</a> to
22252245
<var>result</var> and set its value to the value associated with the
22262246
<a>type mapping</a>.</li>
@@ -2372,7 +2392,10 @@ <h3>Algorithm</h3>
23722392
<a href="#value-compaction">Value Compaction algorithm</a>,
23732393
passing <var>active context</var>, <var>inverse context</var>,
23742394
<var>active property</var>,and <var>element</var> as <var>value</var> is
2375-
a <a>scalar</a>, return that result.</li>
2395+
a <a>scalar</a>,
2396+
<span class="changed">or the <a>term definition</a> for <var>active property</var>
2397+
has a <a>type mapping</a> of <code>@json</code>,</span>
2398+
return that result.</li>
23762399
<li class="changed">If <var>element</var> is a
23772400
<a>list object</a>, and the <a>container mapping</a> for
23782401
<var>active property</var> in <var>active context</var> is <code>@list</code>,
@@ -4235,6 +4258,13 @@ <h3>Algorithm</h3>
42354258
<li class="changed">If <var>datatype</var> is not <a>well-formed</a>, return <code>null</code>.</li>
42364259
<li class="changed">If <var>item</var> has a <code>@language</code>
42374260
<a>member</a> which is not <a>well-formed</a>, return <code>null</code>.</li>
4261+
<li class="changed">If <var>datatype</var> is <code>@json</code>,
4262+
convert <var>value</var> to the <a>canonical lexical form</a> as defined in [[JCS]]
4263+
using the result of transforming the <a>internal representation</a> of <var>value</var>
4264+
to JSON and set <var>datatype</var> to <code>jsonld:JSON</code>.
4265+
<div class="issue atrisk">JCS is still in draft form, and normatively requiring
4266+
JSON canonicalization may be removed in a future draft, or
4267+
a JSON-LD specific canonicalization form may be defined.</div></li>
42384268
<li>If <var>value</var> is <code>true</code> or
42394269
<code>false</code>, set <var>value</var> to the <a>string</a>
42404270
<code>true</code> or <code>false</code> which is the
@@ -4552,6 +4582,11 @@ <h3>Overview</h3>
45524582
<a>value objects</a> whereas <a>IRIs</a> and
45534583
<a>blank node identifiers</a> are
45544584
transformed to <a>node objects</a>.
4585+
<span class="changed">Literals with datatype <code>jsonld:JSON</code>
4586+
are transformed into a value object using the internal representation
4587+
based on the lexical-to-value mapping defined in
4588+
<a data-cite="JSON-LD11#dfn-json-datatype" class="externalDfn">JSON datatype</a> in [[JSON-LD11]]</span>,
4589+
and <code>@type</code> of <code>@json</code>.</span>
45554590
If the <a data-link-for="JsonLdOptions">useNativeTypes</a> flag is set to <code>true</code>,
45564591
<a>RDF literals</a> with a
45574592
<a>datatype IRI</a>
@@ -4610,6 +4645,11 @@ <h3>Algorithm</h3>
46104645
to a JSON <a>number</a>.</li>
46114646
</ol>
46124647
</li>
4648+
<li class="changed">Otherwise, if <a>processing mode</a> is <code>json-ld-1.1</code>,
4649+
and <var>value</var> is a <a>JSON literal</a>,
4650+
set the <code>@value</code> <a>member</a> to the result of
4651+
turning the lexical value of <var>value</var>
4652+
into the <a>JSON-LD internal representation</a>, and set <var>type</var> to <code>@json</code>.</li>
46134653
<li>Otherwise, if <var>value</var> is a
46144654
<a>language-tagged string</a>
46154655
add a <a>member</a> <code>@language</code> to <var>result</var> and set its value to the
@@ -4638,9 +4678,10 @@ <h2>Data Round Tripping</h2>
46384678
or not (the result of a modulo&#8209;1 operation), the boolean values
46394679
<code>true</code> and <code>false</code> are coerced to <code>xsd:boolean</code>,
46404680
and <a>strings</a> are coerced to <code>xsd:string</code>.
4641-
The numeric or boolean values themselves are converted to
4681+
The JSON, numeric, or boolean values themselves are converted to
46424682
<dfn>canonical lexical form</dfn>, i.e., a deterministic string
4643-
representation as defined in [[XMLSCHEMA11-2]].</p>
4683+
representation as defined in [[XMLSCHEMA11-2]]
4684+
<span class="changed">and [[JCS]]</span>.
46444685

46454686
<p>The <a>canonical lexical form</a> of an <em>integer</em>, i.e., a
46464687
<a>number</a> with no non-zero fractional part or a <a>number</a>
@@ -4692,6 +4733,56 @@ <h2>Data Round Tripping</h2>
46924733
values <code>true</code> and <code>false</code> are the strings
46934734
<code>true</code> and <code>false</code>.</p>
46944735

4736+
<p class="changed">The <a>canonical lexical form</a> of the <a>JSON literal</a>
4737+
values are defined in [[JCS]]. The internal representation
4738+
of value objects having @type @json are converted to JSON
4739+
and canonicalized to reduce unnecessary whitespace,
4740+
order object members, and use a standard representation
4741+
for strings and numbers.</p>
4742+
4743+
<aside class="example changed" data-ignore
4744+
title="Canonicalized JSON literal">
4745+
<pre class="original" data-transform="updateExample">
4746+
<!--
4747+
{
4748+
"@context": {
4749+
"@version": 1.1,
4750+
"e": {"@id": "http://example.org/vocab#c14n", ****"@type": "@json"****}
4751+
},
4752+
"e": ****[
4753+
56.0,
4754+
{
4755+
"d": true,
4756+
"10": null,
4757+
"1": [ ]
4758+
}
4759+
]****
4760+
}
4761+
-->
4762+
</pre>
4763+
4764+
<p>The example shows the value of "e" as a native JSON array including
4765+
unnecssary whitespace, a number and an object. The result
4766+
eliminates the whitespace, uses a canonical number representation,
4767+
and reorders the object members lexicographically:</p>
4768+
4769+
<pre class="turtle"
4770+
data-content-type="text/turtle"
4771+
data-result-for="Canonicalized JSON literal-original"
4772+
data-transform="updateExample"
4773+
data-to-rdf>
4774+
<!--
4775+
@prefix ex: <http://example.org/vocab#> .
4776+
@prefix jsonld: <http://www.w3.org/ns/json-ld#> .
4777+
[ex:c14n ****"""[56,{"1":[],"10":null,"d":true}]"""^^jsonld:JSON****] .
4778+
-->
4779+
</pre>
4780+
</aside>
4781+
4782+
<p class="issue atrisk">JCS is still in draft form, and normatively requiring
4783+
JSON canonicalization may be removed in a future draft, or
4784+
a JSON-LD specific canonicalization form may be defined.</p>
4785+
46954786
<p>When JSON-native <a>numbers</a> are deserialized
46964787
to RDF, lossless data round-tripping cannot be guaranteed, as rounding
46974788
errors might occur. When
@@ -5731,6 +5822,7 @@ <h2>Changes since JSON-LD Community Group Final Report</h2>
57315822
<li>Because scoped contexts can lead to contexts being reloaded, replace the
57325823
<strong>recursive context inclusion</strong> error with a <a data-link-for="JsonLdErrorCode">context overflow</a> error.</li>
57335824
<li>Added support for <code>"@type": "@none"</code> in a <a>term definition</a> to prevent value compaction.</li>
5825+
<li>Added support for <a>JSON literals</a>.</li>
57345826
</ul>
57355827
</section>
57365828

tests/compact-manifest.jsonld

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,87 @@
11841184
"context": "compact/h004-context.jsonld",
11851185
"expect": "compact/h004-out.jsonld",
11861186
"option": {"specVersion": "json-ld-1.1", "extractAllScripts": true}
1187+
}, {
1188+
"@id": "#tjs01",
1189+
"@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"],
1190+
"name": "Compact JSON literal (boolean true)",
1191+
"purpose": "Tests compacting property with @type @json to a JSON literal (boolean true).",
1192+
"input": "compact/js01-in.jsonld",
1193+
"context": "compact/js01-context.jsonld",
1194+
"expect": "compact/js01-out.jsonld",
1195+
"option": {"specVersion": "json-ld-1.1", "processingMode": "json-ld-1.1"}
1196+
}, {
1197+
"@id": "#tjs02",
1198+
"@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"],
1199+
"name": "Compact JSON literal (boolean false)",
1200+
"purpose": "Tests compacting property with @type @json to a JSON literal (boolean false).",
1201+
"input": "compact/js02-in.jsonld",
1202+
"context": "compact/js02-context.jsonld",
1203+
"expect": "compact/js02-out.jsonld",
1204+
"option": {"specVersion": "json-ld-1.1", "processingMode": "json-ld-1.1"}
1205+
}, {
1206+
"@id": "#tjs03",
1207+
"@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"],
1208+
"name": "Compact JSON literal (double)",
1209+
"purpose": "Tests compacting property with @type @json to a JSON literal (double).",
1210+
"input": "compact/js03-in.jsonld",
1211+
"context": "compact/js03-context.jsonld",
1212+
"expect": "compact/js03-out.jsonld",
1213+
"option": {"specVersion": "json-ld-1.1", "processingMode": "json-ld-1.1"}
1214+
}, {
1215+
"@id": "#tjs04",
1216+
"@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"],
1217+
"name": "Compact JSON literal (double-zero)",
1218+
"purpose": "Tests compacting property with @type @json to a JSON literal (double-zero).",
1219+
"input": "compact/js04-in.jsonld",
1220+
"context": "compact/js04-context.jsonld",
1221+
"expect": "compact/js04-out.jsonld",
1222+
"option": {"specVersion": "json-ld-1.1", "processingMode": "json-ld-1.1"}
1223+
}, {
1224+
"@id": "#tjs05",
1225+
"@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"],
1226+
"name": "Compact JSON literal (integer)",
1227+
"purpose": "Tests compacting property with @type @json to a JSON literal (integer).",
1228+
"input": "compact/js05-in.jsonld",
1229+
"context": "compact/js05-context.jsonld",
1230+
"expect": "compact/js05-out.jsonld",
1231+
"option": {"specVersion": "json-ld-1.1", "processingMode": "json-ld-1.1"}
1232+
}, {
1233+
"@id": "#tjs06",
1234+
"@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"],
1235+
"name": "Compact JSON literal (object)",
1236+
"purpose": "Tests compacting property with @type @json to a JSON literal (object).",
1237+
"input": "compact/js06-in.jsonld",
1238+
"context": "compact/js06-context.jsonld",
1239+
"expect": "compact/js06-out.jsonld",
1240+
"option": {"specVersion": "json-ld-1.1", "processingMode": "json-ld-1.1"}
1241+
}, {
1242+
"@id": "#tjs07",
1243+
"@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"],
1244+
"name": "Compact JSON literal (array)",
1245+
"purpose": "Tests compacting property with @type @json to a JSON literal (array).",
1246+
"input": "compact/js07-in.jsonld",
1247+
"context": "compact/js07-context.jsonld",
1248+
"expect": "compact/js07-out.jsonld",
1249+
"option": {"specVersion": "json-ld-1.1", "processingMode": "json-ld-1.1"}
1250+
}, {
1251+
"@id": "#tjs08",
1252+
"@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"],
1253+
"name": "Compact already expanded JSON literal",
1254+
"purpose": "Tests compacting JSON literal does not expand terms inside json.",
1255+
"input": "compact/js08-in.jsonld",
1256+
"context": "compact/js08-context.jsonld",
1257+
"expect": "compact/js08-out.jsonld",
1258+
"option": {"specVersion": "json-ld-1.1", "processingMode": "json-ld-1.1"}
1259+
}, {
1260+
"@id": "#tjs09",
1261+
"@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"],
1262+
"name": "Compact already expanded JSON literal with aliased keys",
1263+
"purpose": "Tests compacting JSON literal in expanded form.",
1264+
"input": "compact/js09-in.jsonld",
1265+
"context": "compact/js09-context.jsonld",
1266+
"expect": "compact/js09-out.jsonld",
1267+
"option": {"specVersion": "json-ld-1.1", "processingMode": "json-ld-1.1"}
11871268
}, {
11881269
"@id": "#tm001",
11891270
"@type": ["jld:PositiveEvaluationTest", "jld:CompactTest"],

tests/compact/js01-context.jsonld

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"@context": {
3+
"@version": 1.1,
4+
"e": {"@id": "http://example.org/vocab#bool", "@type": "@json"}
5+
}
6+
}

tests/compact/js01-in.jsonld

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[{
2+
"http://example.org/vocab#bool": [{"@value": true, "@type": "@json"}]
3+
}]

tests/compact/js01-out.jsonld

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"@context": {
3+
"@version": 1.1,
4+
"e": {"@id": "http://example.org/vocab#bool", "@type": "@json"}
5+
},
6+
"e": true
7+
}

tests/compact/js02-context.jsonld

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"@context": {
3+
"@version": 1.1,
4+
"e": {"@id": "http://example.org/vocab#bool", "@type": "@json"}
5+
}
6+
}

tests/compact/js02-in.jsonld

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[{
2+
"http://example.org/vocab#bool": [{"@value": false, "@type": "@json"}]
3+
}]

tests/compact/js02-out.jsonld

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"@context": {
3+
"@version": 1.1,
4+
"e": {"@id": "http://example.org/vocab#bool", "@type": "@json"}
5+
},
6+
"e": false
7+
}

tests/compact/js03-context.jsonld

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"@context": {
3+
"@version": 1.1,
4+
"e": {"@id": "http://example.org/vocab#double", "@type": "@json"}
5+
}
6+
}

tests/compact/js03-in.jsonld

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[{
2+
"http://example.org/vocab#double": [{"@value": 1.23, "@type": "@json"}]
3+
}]

tests/compact/js03-out.jsonld

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"@context": {
3+
"@version": 1.1,
4+
"e": {"@id": "http://example.org/vocab#double", "@type": "@json"}
5+
},
6+
"e": 1.23
7+
}

tests/compact/js04-context.jsonld

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"@context": {
3+
"@version": 1.1,
4+
"e": {"@id": "http://example.org/vocab#double", "@type": "@json"}
5+
}
6+
}

0 commit comments

Comments
 (0)