Skip to content

Commit a932976

Browse files
#160: Allow lists at sh:class and sh:datatype (#395)
* #160: Allow lists at sh:class and sh:datatype * Update shacl12-core/index.html Co-authored-by: Ted Thibodeau Jr <tthibodeau@openlinksw.com> * Update shacl12-core/index.html Co-authored-by: Ted Thibodeau Jr <tthibodeau@openlinksw.com> --------- Co-authored-by: Ted Thibodeau Jr <tthibodeau@openlinksw.com>
1 parent 5e715ec commit a932976

File tree

6 files changed

+291
-14
lines changed

6 files changed

+291
-14
lines changed

shacl12-core/index.html

Lines changed: 83 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3125,7 +3125,7 @@ <h3>Value Type Constraint Components</h3>
31253125
<section id="ClassConstraintComponent">
31263126
<h4>sh:class</h4>
31273127
<p>
3128-
The condition specified by <code>sh:class</code> is that each <a>value node</a> is a <a>SHACL instance</a> of a given type.
3128+
The condition specified by <code>sh:class</code> is that each <a>value node</a> is a <a>SHACL instance</a> of the given type(s).
31293129
</p>
31303130
<p>
31313131
<span class="component-class">Constraint Component IRI</span>: <code>sh:ClassConstraintComponent</code>
@@ -3141,23 +3141,29 @@ <h4>sh:class</h4>
31413141
<td><code>sh:class</code></td>
31423142
<td>
31433143
The type of all value nodes.
3144-
<span data-syntax-rule="class-nodeKind">The values of <code>sh:class</code> in a shape are IRIs.</span>
3144+
<span data-syntax-rule="class-nodeKind">The values of <code>sh:class</code> in a shape are either <a>IRIs</a>
3145+
or <a>blank nodes</a> that are <a>well-formed</a> <a>SHACL lists</a> where all <a>members</a> are <a>IRIs</a>.</span>
31453146
</td>
31463147
</tr>
31473148
</table>
31483149
<div class="def def-text">
31493150
<div class="def-header">TEXTUAL DEFINITION</div>
31503151
<div class="def-text-body" data-validator="Class">
31513152
Let <code>$class</code> be a <a>parameter value</a> for <code>sh:class</code>.
3153+
Let <code>classes</code> be a set of <a>IRIs</a> so that
3154+
when <code>$class</code> is an <a>IRI</a> then the set only consists of exactly that IRI,
3155+
and when <code>$class</code> is a <a>blank node</a> <a>SHACL list</a> then the set consists of
3156+
exactly the members of the list.<br /><br />
31523157
For each <a>value node</a>
3153-
that is either a <a>literal</a>, or a non-literal that is not a <a>SHACL instance</a> of <code>$class</code> in the <a>data graph</a>,
3158+
that is either a <a>literal</a>, or a non-literal that is not a <a>SHACL instance</a> of any of the <code>classes</code> in the <a>data graph</a>,
31543159
there is a <a>validation result</a> with the <a>value node</a> as <code>sh:value</code>.
31553160
</div>
31563161
</div>
31573162
<p><em>The remainder of this section is informative.</em></p>
31583163
<p>
31593164
Note that multiple values for <code>sh:class</code> are interpreted as a conjunction,
3160-
i.e. the values need to be SHACL instances of all of them.
3165+
i.e., the values need to be SHACL instances of all of them.
3166+
Use lists for union semantics.
31613167
</p>
31623168
<aside class="example">
31633169
<div class="shapes-graph">
@@ -3231,6 +3237,37 @@ <h4>sh:class</h4>
32313237
</div>
32323238
</div>
32333239
</aside>
3240+
<p>
3241+
The following example illustrates the list-based syntax for <code>sh:class</code>,
3242+
meaning that the values of the property <code>ex:pet</code> must be either cats or dogs.
3243+
</p>
3244+
<aside class="example">
3245+
<div class="shapes-graph">
3246+
<div class="turtle">
3247+
ex:ClassListExampleShape
3248+
a sh:NodeShape ;
3249+
<span class="target-can-be-skipped">sh:targetClass ex:Person ;</span>
3250+
sh:property [
3251+
sh:path ex:pet ;
3252+
sh:class ( ex:Cat ex:Dog ) ;
3253+
] .
3254+
</div>
3255+
<div class="jsonld">
3256+
</div>
3257+
</div>
3258+
<div class="data-graph">
3259+
<div class="turtle">
3260+
ex:Tessie a ex:Cat .
3261+
ex:Rusty a ex:Dog .
3262+
ex:Fluffy a ex:Unicorn .
3263+
3264+
ex:Alice a ex:Person ; ex:pet ex:Tessie, ex:Rusty .
3265+
<span class="focus-node-error">ex:Bob</span> a ex:Person ; ex:pet ex:Fluffy .
3266+
</div>
3267+
<div class="jsonld">
3268+
</div>
3269+
</div>
3270+
</aside>
32343271
</section>
32353272

32363273
<section id="DatatypeConstraintComponent">
@@ -3251,19 +3288,24 @@ <h4>sh:datatype</h4>
32513288
<tr>
32523289
<td><code>sh:datatype</code></td>
32533290
<td>
3254-
The datatype of all value nodes (e.g., <code>xsd:integer</code>).
3255-
<span data-syntax-rule="datatype-nodeKind">The values of <code>sh:datatype</code> in a shape are <a>IRIs</a>.</span>
3291+
The allowed datatype(s) of all value nodes (e.g., <code>xsd:integer</code>).
32563292
<span data-syntax-rule="datatype-maxCount">A shape has at most one value for <code>sh:datatype</code>.</span>
3293+
<span data-syntax-rule="datatype-nodeKind">The value of <code>sh:datatype</code> in a shape is either an <a>IRI</a>
3294+
or a <a>blank node</a> that is a <a>well-formed</a> <a>SHACL list</a> where all <a>members</a> are <a>IRIs</a>.</span>
32573295
</td>
32583296
</tr>
32593297
</table>
32603298
<div class="def def-text">
32613299
<div class="def-header">TEXTUAL DEFINITION</div>
32623300
<div class="def-text-body" data-validator="Datatype">
32633301
Let <code>$datatype</code> be a <a>parameter value</a> for <code>sh:datatype</code>.
3302+
Let <code>datatypes</code> be a set of <a>IRIs</a> so that
3303+
when <code>$datatype</code> is an <a>IRI</a> then the set only consists of exactly that IRI,
3304+
and when <code>$datatype</code> is a <a>blank node</a> <a>SHACL list</a> then the set consists of
3305+
exactly the members of the list.<br /><br />
32643306
For each <a>value node</a>
3265-
that is not a <a>literal</a>, or is a <a>literal</a> with a datatype that does not match <code>$datatype</code>,
3266-
there is a <a>validation result</a> with the <a>value node</a> as <code>sh:value</code>.
3307+
that is not a <a>literal</a>, or is a <a>literal</a> with a datatype that matches none of the <code>datatypes</code>,
3308+
there is a <a>validation result</a> with the <a>value node</a> as <code>sh:value</code>.<br /><br />
32673309
The datatype of a literal is determined following the <a data-cite="sparql12-query/#func-datatype">datatype</a> function of SPARQL 1.2.
32683310
A <a>literal</a> matches a datatype if the <a>literal</a>'s datatype has the same <a>IRI</a>
32693311
and, for the datatypes supported by SPARQL 1.2, is not an <a data-cite="rdf12-concepts#section-Graph-Literal">ill-typed</a> literal.
@@ -3272,9 +3314,8 @@ <h4>sh:datatype</h4>
32723314
<p><em>The remainder of this section is informative.</em></p>
32733315
<p>
32743316
The values of <code>sh:datatype</code> are typically <a>datatypes</a>, such as <code>xsd:string</code>.
3275-
Note that using <code>rdf:langString</code> as value of <code>sh:datatype</code> can be used to test if value nodes have a language tag.
32763317
</p>
3277-
<aside class="example" title="Shape with sh:datatype property constraint">
3318+
<aside class="example" title="Shape with an IRI as sh:datatype property constraint">
32783319
<div class="shapes-graph">
32793320
<div class="turtle">
32803321
ex:DatatypeExampleShape
@@ -3343,6 +3384,34 @@ <h4>sh:datatype</h4>
33433384
</div>
33443385
</div>
33453386
</aside>
3387+
<p>
3388+
The following example illustrates the list-based syntax, meaning that all values of
3389+
<code>rdfs:label</code> must be either <code>xsd:string</code> or <code>rdf:langString</code>.
3390+
Note that using <code>rdf:langString</code> as value of <code>sh:datatype</code> can be used to test if value nodes have a language tag.
3391+
</p>
3392+
<aside class="example" title="Shape with a list of IRIs as sh:datatype property constraint">
3393+
<div class="shapes-graph">
3394+
<div class="turtle">
3395+
ex:TextExampleShape
3396+
a sh:NodeShape ;
3397+
<span class="target-can-be-skipped">sh:targetNode ex:Estonia, ex:GreatBritain ;</span>
3398+
sh:property [
3399+
sh:path rdfs:label ;
3400+
sh:datatype ( xsd:string rdf:langString ) ;
3401+
] .
3402+
</div>
3403+
<div class="jsonld">
3404+
</div>
3405+
</div>
3406+
<div class="data-graph">
3407+
<div class="turtle">
3408+
ex:Estonia rdfs:label "Estonia", "Estland"@de .
3409+
<span class="focus-node-error">ex:GreatBritain</span> rdfs:label "Great Britain", "&lt;b&gt;Great&lt/b&gt; Britain"^^rdf:HTML .
3410+
</div>
3411+
<div class="jsonld">
3412+
</div>
3413+
</div>
3414+
</aside>
33463415
</section>
33473416

33483417
<section id="NodeKindConstraintComponent">
@@ -6866,10 +6935,10 @@ <h2>Changes between SHACL 1.0 Core and SHACL 1.2 Core</h2>
68666935
<ul>
68676936
<li>Introduced <a>node expressions</a> as an extension point to dynamically compute lists of nodes. Generalized <code>sh:targetNode</code>, <code>sh:deactivated</code> and <code>sh:defaultValue</code>, and introduced <code>sh:values</code> to support node expressions.</li>
68686937
<li>Added the new constraint component <a href="#SingleLineConstraintComponent"><code>sh:singleLine</code></a>, see <a href="https://github.com/w3c/data-shapes/issues/177">Issue 177</a></li>
6869-
<li>Added the new class <a href="#ShapeClass"><code>sh:ShapeClass</code></a> for implicit class targets, see <a href="https://github.com/w3c/data-shapes/issues/212">Issue 212</a></li>
6870-
<li>Moved SPARQL-based validators from Core to an Appendix of SHACL-SPARQL, see <a href="https://github.com/w3c/data-shapes/issues/271">Issue 271</a></li>
6871-
<li>Added the new constraint component <a href="#ExpressionConstraintComponent"><code>sh:expression</code></a>, see <a href="https://github.com/w3c/data-shapes/issues/357">Issue 357</a></li>
6872-
<li>Values for <a href="#deactivated"><code>sh:deactivated</code></a>, <a href="#message"><code>sh:message</code></a> and <a href="#severity"><code>sh:severity</code></a> can now be specified using RDF 1.2 reification, see <a href="https://github.com/w3c/data-shapes/issues/173">Issue 173</a></li>
6938+
<li>Added the new class <a href="#ShapeClass"><code>sh:ShapeClass</code></a> for implicit class targets; see <a href="https://github.com/w3c/data-shapes/issues/212">Issue 212</a></li>
6939+
<li>Moved SPARQL-based validators from Core to an Appendix of SHACL-SPARQL; see <a href="https://github.com/w3c/data-shapes/issues/271">Issue 271</a></li>
6940+
<li>Added the new constraint component <a href="#ExpressionConstraintComponent"><code>sh:expression</code></a>; see <a href="https://github.com/w3c/data-shapes/issues/357">Issue 357</a></li>
6941+
<li>The values of <a href="#ClassConstraintComponent"><code>sh:class</code></a> and <a href="#DatatypeConstraintComponent"><code>sh:datatype</code></a> can now also be lists, indicating a union of choices; see <a href="https://github.com/w3c/data-shapes/issues/160">Issue 160</a></li>
68736942
</ul>
68746943
</section>
68756944
</body>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
@prefix dash: <http://datashapes.org/dash#> .
2+
@prefix ex: <http://datashapes.org/sh/tests/core/node/datatype-003.test#> .
3+
@prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
4+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
5+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
6+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
7+
@prefix sh: <http://www.w3.org/ns/shacl#> .
8+
@prefix sht: <http://www.w3.org/ns/shacl-test#> .
9+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
10+
11+
ex:TestShape
12+
rdf:type sh:NodeShape ;
13+
sh:datatype ( xsd:string rdf:langString ) ;
14+
sh:targetNode "<span>Hello</span>"^^rdf:HTML ;
15+
sh:targetNode "G'day"@en-AU ;
16+
sh:targetNode "Hallo"@de ;
17+
sh:targetNode "Hello" ;
18+
.
19+
<>
20+
rdf:type mf:Manifest ;
21+
mf:entries (
22+
<datatype-003>
23+
) ;
24+
.
25+
<datatype-003>
26+
rdf:type sht:Validate ;
27+
rdfs:label "Test of sh:datatype at node shape 003" ;
28+
mf:action [
29+
sht:dataGraph <> ;
30+
sht:shapesGraph <> ;
31+
] ;
32+
mf:result [
33+
rdf:type sh:ValidationReport ;
34+
sh:conforms "false"^^xsd:boolean ;
35+
sh:result [
36+
rdf:type sh:ValidationResult ;
37+
sh:focusNode "<span>Hello</span>"^^rdf:HTML ;
38+
sh:resultSeverity sh:Violation ;
39+
sh:sourceConstraintComponent sh:DatatypeConstraintComponent ;
40+
sh:sourceShape ex:TestShape ;
41+
sh:value "<span>Hello</span>"^^rdf:HTML ;
42+
] ;
43+
] ;
44+
mf:status sht:approved ;
45+
.

shacl12-test-suite/tests/core/node/manifest.ttl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
mf:include <closed-002.ttl> ;
1515
mf:include <datatype-001.ttl> ;
1616
mf:include <datatype-002.ttl> ;
17+
mf:include <datatype-003.ttl> ;
1718
mf:include <disjoint-001.ttl> ;
1819
mf:include <equals-001.ttl> ;
1920
mf:include <expression-001.ttl> ;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
@prefix dash: <http://datashapes.org/dash#> .
2+
@prefix ex: <http://datashapes.org/sh/tests/core/property/class-002.test#> .
3+
@prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
4+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
5+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
6+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
7+
@prefix sh: <http://www.w3.org/ns/shacl#> .
8+
@prefix sht: <http://www.w3.org/ns/shacl-test#> .
9+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
10+
11+
ex:InvalidResource1
12+
rdf:type rdfs:Resource ;
13+
ex:testProperty ex:InvalidResource1 ;
14+
ex:testProperty "A string" ;
15+
.
16+
ex:OtherClass
17+
rdf:type rdfs:Class ;
18+
.
19+
ex:OtherClassInstance
20+
rdf:type ex:OtherClass ;
21+
.
22+
ex:SubClass
23+
rdf:type rdfs:Class ;
24+
rdfs:subClassOf ex:SuperClass ;
25+
.
26+
ex:SubClassInstance
27+
rdf:type ex:SubClass ;
28+
.
29+
ex:SuperClass
30+
rdf:type rdfs:Class ;
31+
.
32+
ex:SuperClassInstance
33+
rdf:type ex:SuperClass ;
34+
.
35+
ex:TestShape
36+
rdf:type sh:NodeShape ;
37+
sh:property ex:TestShape-testProperty ;
38+
sh:targetNode ex:InvalidResource1 ;
39+
sh:targetNode ex:ValidResource1 ;
40+
sh:targetNode ex:ValidResource2 ;
41+
.
42+
ex:TestShape-testProperty
43+
sh:path ex:testProperty ;
44+
rdfs:label "test property" ;
45+
sh:class ( ex:SuperClass ex:OtherClass ) ;
46+
.
47+
ex:ValidResource1
48+
rdf:type rdfs:Resource ;
49+
ex:testProperty ex:OtherClassInstance ;
50+
ex:testProperty ex:SubClassInstance ;
51+
ex:testProperty ex:SuperClassInstance ;
52+
.
53+
ex:ValidResource2
54+
rdf:type rdfs:Resource ;
55+
ex:testProperty [
56+
rdf:type ex:SubClass ;
57+
] ;
58+
ex:testProperty [
59+
rdf:type ex:SuperClass ;
60+
] ;
61+
.
62+
<>
63+
rdf:type mf:Manifest ;
64+
mf:entries (
65+
<class-002>
66+
) ;
67+
.
68+
<class-002>
69+
rdf:type sht:Validate ;
70+
rdfs:label "Test of sh:class at property shape 002" ;
71+
mf:action [
72+
sht:dataGraph <> ;
73+
sht:shapesGraph <> ;
74+
] ;
75+
mf:result [
76+
rdf:type sh:ValidationReport ;
77+
sh:conforms "false"^^xsd:boolean ;
78+
sh:result [
79+
rdf:type sh:ValidationResult ;
80+
sh:focusNode ex:InvalidResource1 ;
81+
sh:resultPath ex:testProperty ;
82+
sh:resultSeverity sh:Violation ;
83+
sh:sourceConstraintComponent sh:ClassConstraintComponent ;
84+
sh:sourceShape ex:TestShape-testProperty ;
85+
sh:value ex:InvalidResource1 ;
86+
] ;
87+
sh:result [
88+
rdf:type sh:ValidationResult ;
89+
sh:focusNode ex:InvalidResource1 ;
90+
sh:resultPath ex:testProperty ;
91+
sh:resultSeverity sh:Violation ;
92+
sh:sourceConstraintComponent sh:ClassConstraintComponent ;
93+
sh:sourceShape ex:TestShape-testProperty ;
94+
sh:value "A string" ;
95+
] ;
96+
] ;
97+
mf:status sht:approved ;
98+
.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
@prefix dash: <http://datashapes.org/dash#> .
2+
@prefix ex: <http://datashapes.org/sh/tests/core/property/datatype-004.test#> .
3+
@prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
4+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
5+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
6+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
7+
@prefix sh: <http://www.w3.org/ns/shacl#> .
8+
@prefix sht: <http://www.w3.org/ns/shacl-test#> .
9+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
10+
11+
ex:InvalidInstance1
12+
ex:value 42 ;
13+
.
14+
ex:TestShape
15+
rdf:type sh:NodeShape ;
16+
sh:property ex:TestShape-value ;
17+
sh:targetNode ex:InvalidInstance1 ;
18+
sh:targetNode ex:ValidInstance1 ;
19+
sh:targetNode ex:ValidInstance2 ;
20+
sh:targetNode ex:ValidInstance3 ;
21+
.
22+
ex:TestShape-value
23+
sh:path ex:value ;
24+
sh:datatype ( xsd:string rdf:langString ) ;
25+
.
26+
ex:ValidInstance1
27+
ex:value "A" ;
28+
.
29+
ex:ValidInstance2
30+
ex:value "A" ;
31+
.
32+
ex:ValidInstance3
33+
ex:value "A"@en ;
34+
.
35+
<>
36+
rdf:type mf:Manifest ;
37+
mf:entries (
38+
<datatype-004>
39+
) ;
40+
.
41+
<datatype-004>
42+
rdf:type sht:Validate ;
43+
rdfs:label "Test of sh:datatype at property shape 004" ;
44+
mf:action [
45+
sht:dataGraph <> ;
46+
sht:shapesGraph <> ;
47+
] ;
48+
mf:result [
49+
rdf:type sh:ValidationReport ;
50+
sh:conforms "false"^^xsd:boolean ;
51+
sh:result [
52+
rdf:type sh:ValidationResult ;
53+
sh:focusNode ex:InvalidInstance1 ;
54+
sh:resultPath ex:value ;
55+
sh:resultSeverity sh:Violation ;
56+
sh:sourceConstraintComponent sh:DatatypeConstraintComponent ;
57+
sh:sourceShape ex:TestShape-value ;
58+
sh:value 42 ;
59+
] ;
60+
] ;
61+
mf:status sht:approved ;
62+
.

shacl12-test-suite/tests/core/property/manifest.ttl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
rdfs:label "Tests converted from http://datashapes.org/sh/tests/tests/core/property" ;
88
mf:include <and-001.ttl> ;
99
mf:include <class-001.ttl> ;
10+
mf:include <class-002.ttl> ;
1011
mf:include <datatype-001.ttl> ;
1112
mf:include <datatype-002.ttl> ;
1213
mf:include <datatype-003.ttl> ;
14+
mf:include <datatype-004.ttl> ;
1315
mf:include <datatype-ill-formed.ttl> ;
1416
mf:include <disjoint-001.ttl> ;
1517
mf:include <equals-001.ttl> ;

0 commit comments

Comments
 (0)