Skip to content

Commit a7f68d9

Browse files
committed
Allow contexts to be HTML documents, with preference towards script elements of type application/ld+json;profile=http://www.w3.org/ns/json-ld#context`.
For w3c/json-ld-syntax#66.
1 parent 5e18aff commit a7f68d9

22 files changed

+336
-36
lines changed

index.html

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,7 @@ <h2>Context Processing Algorithm</h2>
963963
<h3>Overview</h3>
964964

965965
<p>First we prepare a new <a>active context</a> <var>result</var> by cloning
966-
the current <a>active context</a>. Then we normalize the form of the <span class="changed">original</span>
966+
the current <a>active context</a>. Then we normalize the form of the original
967967
<a>local context</a> to an <a>array</a>.
968968
<a>Local contexts</a> may be in the form of a
969969
<a class="changed">dictionary</a>, a <a>string</a>, or an <a>array</a> containing
@@ -979,7 +979,12 @@ <h3>Overview</h3>
979979
<p>If <a>context</a> is a <a>string</a>, it represents a reference to
980980
a remote context. We dereference the remote context and replace <a>context</a>
981981
with the value of the <code>@context</code> <a>member</a> of the top-level object in the
982-
retrieved JSON-LD document. If there's no such <a>member</a>, an
982+
retrieved JSON-LD document.
983+
<span class="changed">If the result is an HTML document,
984+
we attempt to extract JSON-LD from the first <a data-cite="HTML52/semantics-scripting.html#the-script-element">script element</a>
985+
of type <code>application/ld+json;profile=http://www.w3.org/ns/json-ld#context</code>
986+
or <code>application/ld+json</code>, if no context profile exists.</span>
987+
If there's no such <a>member</a>, an
983988
<a data-link-for="JsonLdErrorCode">invalid remote context</a>
984989
has been detected. Otherwise, we process <a>context</a> by recursively using
985990
this algorithm ensuring that there is no cyclical reference.</p>
@@ -1067,8 +1072,31 @@ <h3>Algorithm</h3>
10671072
then the processor MUST NOT do a further dereference, and
10681073
<a>context</a> is set to the
10691074
previously established <a>internal representation</a>.</li>
1070-
<li>Otherwise, dereference <var>context</var>, <span class="changed">transforming into the <a>internal representation</a></span>.
1071-
If <var>context</var> cannot be dereferenced,
1075+
<li>Otherwise, dereference <var>context</var>, <span class="changed">transforming into the <a>internal representation</a></span>.</li>
1076+
<li class="changed">If the retrieved document's <a>Content-Type</a> is <code>text/html</code>:
1077+
<ol>
1078+
<li>If the original <var>context</var>
1079+
contains a <a data-cite="RFC3986#section-3.5">fragment identifier</a>,
1080+
set <var>source</var> to the <a data-cite="DOM#dom-node-textcontent">textContent</a>
1081+
of the <a data-cite="HTML52/semantics-scripting.html#the-script-element">script element</a> in <var>context</var>
1082+
having an <a data-cite="HTML52/dom.html#element-attrdef-global-id">id attribute</a>
1083+
that matches the fragment identifier, after decoding <a data-cite="RFC3986#section-2.1">percent encoded sequences</a>.</li>
1084+
<li>Otherwise, if the retrived document has a <a data-cite="HTML52/semantics-scripting.html#the-script-element">script element</a>
1085+
of <code>type</code> <code>application/ld+json;profile=http://www.w3.org/ns/json-ld#context</code>,
1086+
set <var>source</var> to the <a data-cite="DOM#dom-node-textcontent">textContent</a>
1087+
of the first element found with that type.</li>
1088+
<li>Otherwise, if the retrived document has a <a data-cite="HTML52/semantics-scripting.html#the-script-element">script element</a>
1089+
of <code>type</code> <code>application/ld+json</code>,
1090+
set <var>source</var> to the <a data-cite="DOM#dom-node-textcontent">textContent</a>
1091+
of the first element found with that type.</li>
1092+
<li>If no element is found,
1093+
a <a data-link-for="JsonLdErrorCode">loading remote context failed</a>
1094+
error has been detected and processing is aborted.</li>
1095+
<li>Set <var>context</var> to the result of the <a href="#extract-script-content">Extract Script Content algorithm</a>,
1096+
using <var>source</var>, transforming into the <a>internal representation</a>.</li>
1097+
</ol>
1098+
</li>
1099+
<li>If <var>context</var> cannot be dereferenced,
10721100
<span class="changed">or cannot be transformed into the <a>internal representation</a></span>,
10731101
a <a data-link-for="JsonLdErrorCode">loading remote context failed</a>
10741102
error has been detected and processing is aborted. If the dereferenced document has no
@@ -4930,7 +4958,7 @@ <h3>Extract Script Content Algorithm</h3>
49304958
<p>The algorithm extracts the text content a
49314959
<a>JSON-LD script element</a> into a <a>dictionary</a> or <a>array</a> of <a>dictionaries</a>.
49324960
A <dfn>JSON-LD script element</dfn> is a <a data-cite="HTML52/semantics-scripting.html#the-script-element">script element</a>
4933-
within an HTML [[HTML52]] document with the <code>type</code> attribute set to
4961+
within an HTML [[HTML]] document with the <code>type</code> attribute set to
49344962
<code>application/ld+json</code>.</p>
49354963

49364964
<p>The algorithm takes a single required input variable: <var>source</var>,
@@ -5101,7 +5129,7 @@ <h3>The <dfn>JsonLdProcessor</dfn> Interface</h3>
51015129
The use of the <a data-cite="HTML52/infrastructure.html#document-base-url">Document Base URL</a>
51025130
from [[HTML]] for setting the <a>base IRI</a> of the enclosed JSON-LD
51035131
is an experimental feature, which may be changed in a future version of this specification.
5104-
</div>
5132+
</div></li>
51055133
<li>If the original passed <a data-lt="jsonldprocessor-expand-input">input</a> parameter
51065134
contains a <a data-cite="RFC3986#section-3.5">fragment identifier</a>,
51075135
set <var>source</var> to the <a data-cite="DOM#dom-node-textcontent">textContent</a>
@@ -5946,6 +5974,10 @@ <h2>Changes since JSON-LD Community Group Final Report</h2>
59465974
<li>Added support for <a>JSON literals</a>.</li>
59475975
<li><a>Term definitions</a> with keys which are of the form of a <a>compact IRI</a> or <a>absolute IRI</a> MUST NOT
59485976
expand to an <a>IRI</a> other than the expansion of the key itself.</li>
5977+
<li>If a retrieved context URL returns an HTML document, the first script element
5978+
of type <code>application/ld+json;profile=http://www.w3.org/ns/json-ld#context</code>,
5979+
or <code>application/ld+json</code> is used as the context for further processing.
5980+
This allows a mechanism for documenting the content of a context using HTML.</li>
59495981
</ul>
59505982
</section>
59515983

tests/.htaccess

Lines changed: 0 additions & 30 deletions
This file was deleted.

tests/expand-manifest.jsonld

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,45 @@
15071507
"input": "expand/h022-in.html#second",
15081508
"expect": "expand/h022-out.jsonld",
15091509
"option": {"specVersion": "json-ld-1.1"}
1510+
}, {
1511+
"@id": "#thc01",
1512+
"@type": ["jld:PositiveEvaluationTest", "jld:ExpandTest"],
1513+
"name": "Expands document using an HTML context",
1514+
"purpose": "Tests extracting a context from an HTML document.",
1515+
"input": "expand/hc01-in.jsonld",
1516+
"expect": "expand/hc01-out.jsonld",
1517+
"option": {"specVersion": "json-ld-1.1"}
1518+
}, {
1519+
"@id": "#thc02",
1520+
"@type": ["jld:PositiveEvaluationTest", "jld:ExpandTest"],
1521+
"name": "Expands document using an HTML context with a fragment identifier",
1522+
"purpose": "Tests extracting a context from an HTML document with script identified by fragment identifier.",
1523+
"input": "expand/hc02-in.jsonld",
1524+
"expect": "expand/hc02-out.jsonld",
1525+
"option": {"specVersion": "json-ld-1.1"}
1526+
}, {
1527+
"@id": "#thc03",
1528+
"@type": ["jld:PositiveEvaluationTest", "jld:ExpandTest"],
1529+
"name": "Expands document using an HTML context with preference to context profile",
1530+
"purpose": "Tests extracting a context from an HTML document, skipping other contexts.",
1531+
"input": "expand/hc03-in.jsonld",
1532+
"expect": "expand/hc03-out.jsonld",
1533+
"option": {"specVersion": "json-ld-1.1"}
1534+
}, {
1535+
"@id": "#thc04",
1536+
"@type": ["jld:PositiveEvaluationTest", "jld:ExpandTest"],
1537+
"name": "Expands document using an HTML context with expandContext",
1538+
"purpose": "Tests extracting a context from an HTML document, using expandContext API option.",
1539+
"input": "expand/hc04-in.jsonld",
1540+
"expect": "expand/hc04-out.jsonld",
1541+
"option": {"expandContext": "hc04-context.html", "specVersion": "json-ld-1.1"}
1542+
}, {
1543+
"@id": "#thc05",
1544+
"@type": [ "jld:NegativeEvaluationTest", "jld:ExpandTest" ],
1545+
"name": "Errors if given an HTML file for a context where no context script element is found",
1546+
"purpose": "Verifies that an exception is raised on expansion when a remote context is an HTML file but does not contain a script element which is an object containing @context",
1547+
"input": "expand/hc05-in.jsonld",
1548+
"expect": "invalid remote context"
15101549
}, {
15111550
"@id": "#tjs01",
15121551
"@type": ["jld:PositiveEvaluationTest", "jld:ExpandTest"],

tests/expand/hc01-context.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<html>
2+
<head>
3+
<script type="application/ld+json;profile=http://www.w3.org/ns/json-ld#context">
4+
{
5+
"@context": {
6+
"t1": "http://example.com/t1",
7+
"t2": "http://example.com/t2",
8+
"term1": "http://example.com/term1",
9+
"term2": "http://example.com/term2",
10+
"term3": "http://example.com/term3",
11+
"term4": "http://example.com/term4",
12+
"term5": "http://example.com/term5"
13+
}
14+
}
15+
</script>
16+
</head>
17+
</html>

tests/expand/hc01-in.jsonld

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"@context": "hc01-context.html",
3+
"@id": "http://example.com/id1",
4+
"@type": "t1",
5+
"term1": "v1",
6+
"term2": {"@value": "v2", "@type": "t2"},
7+
"term3": {"@value": "v3", "@language": "en"},
8+
"term4": 4,
9+
"term5": [50, 51]
10+
}

tests/expand/hc01-out.jsonld

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[{
2+
"@id": "http://example.com/id1",
3+
"@type": ["http://example.com/t1"],
4+
"http://example.com/term1": [{"@value": "v1"}],
5+
"http://example.com/term2": [{"@value": "v2", "@type": "http://example.com/t2"}],
6+
"http://example.com/term3": [{"@value": "v3", "@language": "en"}],
7+
"http://example.com/term4": [{"@value": 4}],
8+
"http://example.com/term5": [{"@value": 50}, {"@value": 51}]
9+
}]

tests/expand/hc02-context.html

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<html>
2+
<head>
3+
<script type="application/ld+json;profile=http://www.w3.org/ns/json-ld#context">
4+
{
5+
"@context": {
6+
"@vocab": "http://wrong.example.org/"
7+
}
8+
}
9+
</script>
10+
<!-- this will skip the profile'd version to use that identified by a fragment identifier -->
11+
<script id="context" type="application/ld+json">
12+
{
13+
"@context": {
14+
"t1": "http://example.com/t1",
15+
"t2": "http://example.com/t2",
16+
"term1": "http://example.com/term1",
17+
"term2": "http://example.com/term2",
18+
"term3": "http://example.com/term3",
19+
"term4": "http://example.com/term4",
20+
"term5": "http://example.com/term5"
21+
}
22+
}
23+
</script>
24+
</head>
25+
</html>

tests/expand/hc02-in.jsonld

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"@context": "hc02-context.html#context",
3+
"@id": "http://example.com/id1",
4+
"@type": "t1",
5+
"term1": "v1",
6+
"term2": {"@value": "v2", "@type": "t2"},
7+
"term3": {"@value": "v3", "@language": "en"},
8+
"term4": 4,
9+
"term5": [50, 51]
10+
}

tests/expand/hc02-out.jsonld

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[{
2+
"@id": "http://example.com/id1",
3+
"@type": ["http://example.com/t1"],
4+
"http://example.com/term1": [{"@value": "v1"}],
5+
"http://example.com/term2": [{"@value": "v2", "@type": "http://example.com/t2"}],
6+
"http://example.com/term3": [{"@value": "v3", "@language": "en"}],
7+
"http://example.com/term4": [{"@value": 4}],
8+
"http://example.com/term5": [{"@value": 50}, {"@value": 51}]
9+
}]

tests/expand/hc03-context.html

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<html>
2+
<head>
3+
<script type="application/ld+json">
4+
{
5+
"@context": {
6+
"@vocab": "http://wrong.example.org/"
7+
}
8+
}
9+
</script>
10+
<!-- this will skip the non profiled script element to favor the script with the context profile -->
11+
<script id="context" type="application/ld+json;profile=http://www.w3.org/ns/json-ld#context">
12+
{
13+
"@context": {
14+
"t1": "http://example.com/t1",
15+
"t2": "http://example.com/t2",
16+
"term1": "http://example.com/term1",
17+
"term2": "http://example.com/term2",
18+
"term3": "http://example.com/term3",
19+
"term4": "http://example.com/term4",
20+
"term5": "http://example.com/term5"
21+
}
22+
}
23+
</script>
24+
</head>
25+
</html>

tests/expand/hc03-in.jsonld

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"@context": "hc03-context.html#context",
3+
"@id": "http://example.com/id1",
4+
"@type": "t1",
5+
"term1": "v1",
6+
"term2": {"@value": "v2", "@type": "t2"},
7+
"term3": {"@value": "v3", "@language": "en"},
8+
"term4": 4,
9+
"term5": [50, 51]
10+
}

tests/expand/hc03-out.jsonld

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[{
2+
"@id": "http://example.com/id1",
3+
"@type": ["http://example.com/t1"],
4+
"http://example.com/term1": [{"@value": "v1"}],
5+
"http://example.com/term2": [{"@value": "v2", "@type": "http://example.com/t2"}],
6+
"http://example.com/term3": [{"@value": "v3", "@language": "en"}],
7+
"http://example.com/term4": [{"@value": 4}],
8+
"http://example.com/term5": [{"@value": 50}, {"@value": 51}]
9+
}]

tests/expand/hc04-context.html

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<html>
2+
<head>
3+
<script type="application/ld+json">
4+
{
5+
"@context": {
6+
"@vocab": "http://wrong.example.org/"
7+
}
8+
}
9+
</script>
10+
<!-- this will skip the non profiled script element to favor the script with the context profile -->
11+
<script id="context" type="application/ld+json;profile=http://www.w3.org/ns/json-ld#context">
12+
{
13+
"@context": {
14+
"t1": "http://example.com/t1",
15+
"t2": "http://example.com/t2",
16+
"term1": "http://example.com/term1",
17+
"term2": "http://example.com/term2",
18+
"term3": "http://example.com/term3",
19+
"term4": "http://example.com/term4",
20+
"term5": "http://example.com/term5"
21+
}
22+
}
23+
</script>
24+
</head>
25+
</html>

tests/expand/hc04-in.jsonld

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"@id": "http://example.com/id1",
3+
"@type": "t1",
4+
"term1": "v1",
5+
"term2": {"@value": "v2", "@type": "t2"},
6+
"term3": {"@value": "v3", "@language": "en"},
7+
"term4": 4,
8+
"term5": [50, 51]
9+
}

tests/expand/hc04-out.jsonld

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[{
2+
"@id": "http://example.com/id1",
3+
"@type": ["http://example.com/t1"],
4+
"http://example.com/term1": [{"@value": "v1"}],
5+
"http://example.com/term2": [{"@value": "v2", "@type": "http://example.com/t2"}],
6+
"http://example.com/term3": [{"@value": "v3", "@language": "en"}],
7+
"http://example.com/term4": [{"@value": 4}],
8+
"http://example.com/term5": [{"@value": 50}, {"@value": 51}]
9+
}]

tests/expand/hc05-context.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<html>
2+
<head>
3+
<!-- this script is not properly typed and will cause an error -->
4+
<script>
5+
{
6+
"@context": {
7+
"t1": "http://example.com/t1",
8+
"t2": "http://example.com/t2",
9+
"term1": "http://example.com/term1",
10+
"term2": "http://example.com/term2",
11+
"term3": "http://example.com/term3",
12+
"term4": "http://example.com/term4",
13+
"term5": "http://example.com/term5"
14+
}
15+
}
16+
</script>
17+
</head>
18+
</html>

tests/expand/hc05-in.jsonld

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"@context": "hc05-context.html",
3+
"@id": "http://example.com/id1",
4+
"@type": "t1",
5+
"term1": "v1",
6+
"term2": {"@value": "v2", "@type": "t2"},
7+
"term3": {"@value": "v3", "@language": "en"},
8+
"term4": 4,
9+
"term5": [50, 51]
10+
}

tests/remote-doc-manifest.jsonld

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@
124124
},
125125
"input": "remote-doc/0012-in.json",
126126
"expect": "multiple context link headers"
127+
}, {
128+
"@id": "#t0013",
129+
"@type": ["jld:PositiveEvaluationTest", "jld:ExpandTest"],
130+
"name": "load JSON document with link to HTML document",
131+
"purpose": "If a context is specified in a link header, it is used for JSON, extracting from HTML.",
132+
"option": {
133+
"httpLink": "<0013-context.html>; rel=\"http://www.w3.org/ns/json-ld#context\""
134+
},
135+
"input": "remote-doc/0013-in.json",
136+
"expect": "remote-doc/0013-out.jsonld"
127137
}
128138
]
129139
}

0 commit comments

Comments
 (0)