@@ -600,8 +600,8 @@ <h2>Getting started with Node Expressions</h2>
600
600
< p >
601
601
The following diagram illustrates how this node expression is interpreted, from a logical point of view.
602
602
During validation, a SHACL processor will determine the < a > target</ a > nodes of the shape
603
- by evaluating the < a > filterShape expression</ a > .
604
- However, the filterShape expression first evaluates its input expression, which is specified via < code > sh:nodes</ code >
603
+ by evaluating the < a > filter shape expression</ a > .
604
+ However, the filter shape expression first evaluates its input expression, which is specified via < code > sh:nodes</ code >
605
605
and is an < a > instancesOf expression</ a > .
606
606
This will produce all instances of the given class, < code > ex:Company</ code > .
607
607
The < code > shnex:filterShape</ code > is then applied to all of these instances, to keep only the companies
@@ -669,7 +669,7 @@ <h2>Getting started with Node Expressions</h2>
669
669
sh:datatype xsd:integer ;
670
670
sh:values < b > [
671
671
shnex:count [
672
- shnex:path ex:employee ;
672
+ shnex:pathValues ex:employee ;
673
673
]
674
674
]</ b > .
675
675
</ div >
@@ -859,14 +859,14 @@ <h3>List Parameter Functions</h3>
859
859
sh:values < b > [
860
860
ex:coalesce (
861
861
[
862
- # This is a path expression that is expected to return zero or one values
863
- shnex:path ex:fullName ;
862
+ # This is a path values expression that is expected to return zero or one values
863
+ shnex:pathValues ex:fullName ;
864
864
]
865
865
[
866
866
ex:concat (
867
- [ shnex:path ex:firstName ] # Path expression with at most one value
867
+ [ shnex:pathValues ex:firstName ] # Path values expression with at most one value
868
868
" " # A constant literal expression
869
- [ shnex:path ex:lastName ] # Path expression with at most one value
869
+ [ shnex:pathValues ex:lastName ] # Path values expression with at most one value
870
870
)
871
871
]
872
872
)
@@ -1055,7 +1055,7 @@ <h3>List Expressions</h3>
1055
1055
sh:values [
1056
1056
shnex:nodes [
1057
1057
# This returns all transitive superclasses of the current focus node
1058
- shnex:path [ sh:zeroOrMorePath rdfs:subClassOf ] ;
1058
+ shnex:pathValues [ sh:zeroOrMorePath rdfs:subClassOf ] ;
1059
1059
] ;
1060
1060
# This removes any superclasses that are in the list below
1061
1061
shnex:minus < b > ( owl:Thing rdfs:Resource )</ b > ;
@@ -1069,12 +1069,12 @@ <h3>List Expressions</h3>
1069
1069
</ p >
1070
1070
</ section >
1071
1071
1072
- < section id ="PathExpression ">
1073
- < h3 > Path Expressions</ h3 >
1072
+ < section id ="PathValuesExpression ">
1073
+ < h3 > Path Values Expressions</ h3 >
1074
1074
< p class ="syntax ">
1075
- < span data-syntax-rule ="PathExpression -syntax ">
1075
+ < span data-syntax-rule ="PathValuesExpression -syntax ">
1076
1076
A < a > blank node</ a > that is the < a > subject</ a > of the following properties
1077
- is called a < dfn > path expression</ dfn > with the < a > function name</ a > < code > shnex:PathExpression </ code > :
1077
+ is called a < dfn > path values expression</ dfn > with the < a > function name</ a > < code > shnex:PathValuesExpression </ code > :
1078
1078
< table class ="term-table ">
1079
1079
< thead >
1080
1080
< th > Property</ th >
@@ -1083,7 +1083,7 @@ <h3>Path Expressions</h3>
1083
1083
</ thead >
1084
1084
< tbody >
1085
1085
< tr >
1086
- < td > < b > < code > shnex:path </ code > </ b > </ td >
1086
+ < td > < b > < code > shnex:pathValues </ code > </ b > </ td >
1087
1087
< td >
1088
1088
Must be a < a > well-formed</ a > < a > SHACL property path</ a > .
1089
1089
</ td >
@@ -1092,41 +1092,49 @@ <h3>Path Expressions</h3>
1092
1092
</ td >
1093
1093
</ tr >
1094
1094
< tr >
1095
- < td > < code > shnex:nodes </ code > </ td >
1095
+ < td > < code > shnex:focusNode </ code > </ td >
1096
1096
< td >
1097
1097
Optional, must be a < a > well-formed</ a > < a > node expression</ a > .
1098
1098
</ td >
1099
1099
< td >
1100
- A node expression producing the < a > focus nodes </ a > , defaulting
1101
- to the current focus node from the evaluation context.
1100
+ A node expression producing the < a > focus node </ a > ,
1101
+ defaulting to the current focus node from the evaluation context.
1102
1102
</ td >
1103
1103
</ tr >
1104
1104
</ tbody >
1105
1105
</ table >
1106
1106
</ span >
1107
1107
</ p >
1108
- < div class ="def " id ="PathExpression -evaluation ">
1109
- < div class ="def-header "> EVALUATION OF PATH EXPRESSIONS</ div >
1108
+ < div class ="def " id ="PathValuesExpression -evaluation ">
1109
+ < div class ="def-header "> EVALUATION OF PATH VALUES EXPRESSIONS</ div >
1110
1110
< p >
1111
- Let < code > path</ code > be the < a > value</ a > of < code > shnex:path</ code > ,
1112
- and < code > nodes</ code > be the < a > value</ a > of < code > shnex:nodes</ code > in the < a > path expression</ a > .
1113
- If < code > shnex:nodes</ code > is not given, < code > nodes</ code > is the list consistent of exactly the < a > focus node</ a > .
1114
- Let < code > N</ code > be the nodes produced by < code > evalExpr(nodes, focusGraph, focusNode, scope)</ code > .
1115
- The < a > output nodes</ a > of the < a > path expression</ a > are the list of < a > nodes</ a > produced by concatenating
1116
- the < a > value nodes</ a > of the < code > path</ code > at each < a > node</ a > in < code > N</ code > .
1117
- < span class ="todo "> TODO: Clarify if those can contain duplicates.</ span >
1111
+ Let < code > $pathValues</ code > be the < a > value</ a > of < code > shnex:pathValues</ code > ,
1112
+ and < code > $focusNode</ code > be the < a > value</ a > of < code > shnex:focusNode</ code > in a < a > path values expression</ a > .
1113
+ If < code > shnex:focusNode</ code > is not given, < code > $focusNode</ code > is the list consisting of exactly the < a > focus node</ a >
1114
+ from the evaluation context.< br /> < br />
1115
+ Let < code > N</ code > be the nodes produced by < code > evalExpr($focusNode, focusGraph, focusNode, scope)</ code > .
1116
+ If < code > N</ code > has 0 members, then the < a > output nodes</ a > are the empty list.
1117
+ If < code > N</ code > has more than 1 member, an < a > evaluation failure</ a > is reported.
1118
+ Otherwise, the < a > output nodes</ a > of the < a > path values expression</ a > are the list of < a > value nodes</ a > of the < code > path</ code >
1119
+ for the (only) member of < code > N</ code > .
1118
1120
</ p >
1119
1121
</ div >
1120
1122
< p > < em > The remainder of this section is informative.</ em > </ p >
1121
1123
< p >
1122
- The following example illustrates the use of a < a > path expression</ a > to compute the value
1124
+ Note that by definition, the < a > value nodes</ a > of a property shape may be derived properties,
1125
+ based on < code > sh:values</ code > or < code > sh:defaultValue</ code > expressions.
1126
+ This means that if the provided < code > shnex:pathValues</ code > path is an < a > IRI</ a > , then a path values expression
1127
+ may cause the evaluation of other node expressions, as a simple kind of rule chaining.
1128
+ </ p >
1129
+ < p >
1130
+ The following example illustrates the use of a < a > path values expression</ a > to compute the value
1123
1131
of the property < code > ex:topConceptCount</ code > .
1124
- The path expression returns the values of < code > skos:hasTopConcept</ code > at each < code > skos:ConceptScheme</ code >
1125
- and these are processed by the < a href ="#CountExpression "> < code > shnex:count</ code > </ a > to return the
1132
+ The expression returns the values of < code > skos:hasTopConcept</ code > for the current < code > skos:ConceptScheme</ code >
1133
+ and these values are processed by the < a href ="#CountExpression "> < code > shnex:count</ code > </ a > to return the
1126
1134
number of top concepts.
1127
1135
</ p >
1128
1136
< p >
1129
- < aside class ="example " title ="TODO ">
1137
+ < aside class ="example " title ="A path values expression computing the number of top concepts in a scheme ">
1130
1138
< div class ="shapes-graph ">
1131
1139
< div class ="turtle ">
1132
1140
skos:ConceptScheme
@@ -1141,18 +1149,40 @@ <h3>Path Expressions</h3>
1141
1149
sh:maxCount 1 ;
1142
1150
sh:name "top concept count" ;
1143
1151
sh:values [
1144
- shnex:count [
1145
- < b > shnex:path skos:hasTopConcept</ b > ;
1146
- ] ;
1152
+ shnex:count < b > [
1153
+ shnex:pathValues skos:hasTopConcept ;
1154
+ ]</ b > ;
1147
1155
] .
1148
1156
</ div >
1149
1157
< div class ="jsonld ">
1150
1158
TODO
1151
1159
</ div >
1152
1160
</ div >
1153
1161
</ aside >
1162
+ < p >
1163
+ The next example illustrates the use of a < a > path values expression</ a > together with a specific focus node
1164
+ (instead of the default focus node provided by the evaluation context).
1165
+ The shape targets all < a > subjects</ a > that have < code > skos:Concept</ code > as their < code > rdf:type</ code >
1166
+ with a dynamically computed < code > sh:targetNode</ code > expression.
1167
+ In other words, the target nodes are the direct instances of < code > skos:Concept</ code > based on asserted
1168
+ < code > rdf:type</ code > triples, not including the subclasses of < code > skos:Concept</ code > .
1169
+ </ p >
1170
+ < aside class ="example " title ="A shape that targets the direct instances of skos:Concept, using a path values expression ">
1171
+ < div class ="shapes-graph ">
1172
+ < div class ="turtle ">
1173
+ ex:DirectInstancesOfConceptShape
1174
+ a sh:NodeShape ;
1175
+ sh:targetNode < b > [
1176
+ shnex:pathValues [ sh:inversePath rdf:type ] ;
1177
+ shnex:focusNode skos:Concept ;
1178
+ ]</ b > .
1179
+ </ div >
1180
+ < div class ="jsonld ">
1181
+ TODO
1182
+ </ div >
1183
+ </ div >
1184
+ </ aside >
1154
1185
</ p >
1155
- < p class ="todo "> TODO: Add second example that uses shnex:nodes</ p >
1156
1186
</ section >
1157
1187
1158
1188
< section id ="ExistsExpression ">
@@ -1279,15 +1309,15 @@ <h3>If Expressions</h3>
1279
1309
sh:path ex:fillColor ;
1280
1310
sh:datatype xsd:string ;
1281
1311
sh:name "fill color" ;
1282
- sh:values [
1283
- < b > shnex:if [
1312
+ sh:values < b > [
1313
+ shnex:if [
1284
1314
shnex:exists [
1285
- shnex:path ex:capitalOf ;
1315
+ shnex:pathValues ex:capitalOf ;
1286
1316
] ;
1287
1317
] ;
1288
1318
shnex:then "blue" ;
1289
- shnex:else "red" ;</ b >
1290
- ] .
1319
+ shnex:else "red" ;
1320
+ ]</ b > .
1291
1321
</ div >
1292
1322
< div class ="jsonld ">
1293
1323
TODO
@@ -1360,16 +1390,16 @@ <h3>Distinct Expressions</h3>
1360
1390
a sh:PropertyShape ;
1361
1391
sh:path ex:superClassesIncludingRoot ;
1362
1392
sh:description "The superclasses of this, always including rdfs:Resource." ;
1363
- sh:values [
1364
- < b > shnex:distinct [
1393
+ sh:values < b > [
1394
+ shnex:distinct [
1365
1395
shnex:union (
1366
1396
[
1367
- shnex:path [ sh:zeroOrMorePath rdfs:subClassOf ] ;
1397
+ shnex:pathValues [ sh:zeroOrMorePath rdfs:subClassOf ] ;
1368
1398
]
1369
1399
( rdfs:Resource )
1370
1400
)
1371
- ] ; </ b >
1372
- ] .</ b >
1401
+ ]</ b > ;
1402
+ ] .
1373
1403
</ div >
1374
1404
< div class ="jsonld ">
1375
1405
TODO
@@ -1426,12 +1456,12 @@ <h3>Intersection Expressions</h3>
1426
1456
< div class ="turtle ">
1427
1457
ex:DualCitizenShape
1428
1458
a sh:NodeShape ;
1429
- sh:targetNode [
1430
- < b > shnex:intersection (
1459
+ sh:targetNode < b > [
1460
+ shnex:intersection (
1431
1461
[ shnex:instancesOf ex:Australian ]
1432
1462
[ shnex:instancesOf ex:German ]
1433
- )</ b >
1434
- ] .
1463
+ )
1464
+ ]</ b > .
1435
1465
</ div >
1436
1466
< div class ="jsonld ">
1437
1467
TODO
@@ -1540,11 +1570,11 @@ <h3>Minus Expressions</h3>
1540
1570
</ section >
1541
1571
1542
1572
< section id ="FilterShapeExpression ">
1543
- < h3 > FilterShape Expressions</ h3 >
1573
+ < h3 > Filter Shape Expressions</ h3 >
1544
1574
< p class ="syntax ">
1545
1575
< span data-syntax-rule ="FilterShapeExpression-syntax ">
1546
1576
A < a > blank node</ a > that is the < a > subject</ a > of the following properties
1547
- is called a < dfn > filterShape expression</ dfn > with the < a > function name</ a > < code > shnex:FilterShapeExpression</ code > :
1577
+ is called a < dfn > filter shape expression</ dfn > with the < a > function name</ a > < code > shnex:FilterShapeExpression</ code > :
1548
1578
< table class ="term-table ">
1549
1579
< thead >
1550
1580
< th > Property</ th >
@@ -1575,11 +1605,11 @@ <h3>FilterShape Expressions</h3>
1575
1605
</ span >
1576
1606
</ p >
1577
1607
< div class ="def " id ="FilterShapeExpression-evaluation ">
1578
- < div class ="def-header "> EVALUATION OF FILTERSHAPE EXPRESSIONS</ div >
1608
+ < div class ="def-header "> EVALUATION OF FILTER SHAPE EXPRESSIONS</ div >
1579
1609
< p >
1580
1610
Let < code > filterShape</ code > be the < a > value</ a > of < code > shnex:filterShape</ code > ,
1581
- and < code > nodes</ code > be the < a > value</ a > of < code > shnex:nodes</ code > in a < a > filterShape expression</ a > .
1582
- The < a > output nodes</ a > of the < a > filterShape expression</ a > are the < a > output nodes</ a > of
1611
+ and < code > nodes</ code > be the < a > value</ a > of < code > shnex:nodes</ code > in a < a > filter shape expression</ a > .
1612
+ The < a > output nodes</ a > of the < a > filter shape expression</ a > are the < a > output nodes</ a > of
1583
1613
< code > evalExpr(nodes, focusGraph, focusNode, scope)</ code > except those that do not < a > conform</ a > to
1584
1614
the < a > shape</ a > < code > filterShape</ code > , preserving the order in the list.
1585
1615
</ p >
@@ -1604,7 +1634,7 @@ <h3>FilterShape Expressions</h3>
1604
1634
sh:class ex:Person ;
1605
1635
sh:values < b > [
1606
1636
shnex:nodes</ b > [
1607
- shnex:path ex:child ;
1637
+ shnex:pathValues ex:child ;
1608
1638
] ;
1609
1639
< b > shnex:filterShape [
1610
1640
sh:property [
@@ -1694,7 +1724,7 @@ <h3>Limit Expressions</h3>
1694
1724
sh:values < b > [
1695
1725
shnex:nodes</ b > [
1696
1726
shnex:nodes [
1697
- shnex:path ex:child ;
1727
+ shnex:pathValues ex:child ;
1698
1728
] ;
1699
1729
shnex:orderBy ex:dateOfBirth ;
1700
1730
] ;
@@ -1781,7 +1811,7 @@ <h3>Offset Expressions</h3>
1781
1811
sh:values < b > [
1782
1812
shnex:nodes</ b > [
1783
1813
shnex:nodes [
1784
- shnex:path ex:child ;
1814
+ shnex:pathValues ex:child ;
1785
1815
] ;
1786
1816
shnex:orderBy ex:dateOfBirth ;
1787
1817
] ;
@@ -1867,7 +1897,7 @@ <h3>Count Expressions</h3>
1867
1897
sh:name "top concept count" ;
1868
1898
sh:values [
1869
1899
shnex:count [
1870
- shnex:path skos:hasTopConcept ;
1900
+ shnex:pathValues skos:hasTopConcept ;
1871
1901
] ;
1872
1902
] .
1873
1903
</ div >
@@ -1940,7 +1970,7 @@ <h3>Min Expressions</h3>
1940
1970
sh:name "min start date" ;
1941
1971
sh:values [
1942
1972
shnex:min [
1943
- shnex:path ( ex:employee ex:startDate ) ;
1973
+ shnex:pathValues ( ex:employee ex:startDate ) ;
1944
1974
] ;
1945
1975
] .
1946
1976
</ div >
@@ -2035,8 +2065,8 @@ <h3>Sum Expressions</h3>
2035
2065
< p >
2036
2066
Note that < code > shnex:sum</ code > needs to be used with care and may be often misunderstood,
2037
2067
when used with property paths.
2038
- The problem is that when a < a > path expression</ a > is used as input to a < a > sum expression</ a > ,
2039
- the path expression will have eliminated duplicates before they can be processed by the < code > shnex:sum</ code > .
2068
+ The problem is that when a < a > path values expression</ a > is used as input to a < a > sum expression</ a > ,
2069
+ the path values expression will have eliminated duplicates before they can be processed by the < code > shnex:sum</ code > .
2040
2070
As a result, only the distinct values will be added up.
2041
2071
</ p >
2042
2072
< p class ="todo "> TODO: Find good example, or drop the feature if none makes sense</ p >
@@ -2183,7 +2213,7 @@ <h3>sh:expression</h3>
2183
2213
[
2184
2214
sparql:ucase (
2185
2215
[
2186
- shnex:path ( ex:country ex:code )
2216
+ shnex:pathValues ( ex:country ex:code )
2187
2217
shnex:nodes [ shnex:var "focusNode" ]
2188
2218
]
2189
2219
)
@@ -2292,7 +2322,7 @@ <h3>sh:nodeByExpression</h3>
2292
2322
The following example demonstrates how < code > sh:nodeByExpression</ code > could be used in the context of the < a href ="https://www.w3.org/TR/vocab-data-cube/ "> W3C Data Cube Vocabulary</ a > .
2293
2323
Building upon examples 5 and 6 from the Data Cube Vocabulary documentation, Data Structure Definition is extended with the property < code > eg:hasShape</ code > ,
2294
2324
which links to an associated < a > node shape</ a > to which relevant < code > qb:Observation</ code > instances must conform.
2295
- To validate that every < code > qb:Observation</ code > instance conforms to the appropriate shape, < code > sh:nodeByExpression</ code > with a < a > Path Expression </ a >
2325
+ To validate that every < code > qb:Observation</ code > instance conforms to the appropriate shape, < code > sh:nodeByExpression</ code > with a < a > path values expression </ a >
2296
2326
is used to locate the shape at the property path < code > qb:dataSet/qb:structure/eg:hasShape</ code > from each < code > qb:Observation</ code > instance.
2297
2327
</ p >
2298
2328
< aside class ="example ">
@@ -2325,7 +2355,7 @@ <h3>sh:nodeByExpression</h3>
2325
2355
a sh:NodeShape ;
2326
2356
sh:targetClass qb:Observation ;
2327
2357
sh:nodeByExpression [
2328
- shnex:path (qb:dataSet qb:structure eg:hasShape) ;
2358
+ shnex:pathValues (qb:dataSet qb:structure eg:hasShape) ;
2329
2359
] .
2330
2360
</ div >
2331
2361
< div class ="jsonld ">
@@ -2403,7 +2433,7 @@ <h3>sh:nodeByExpression</h3>
2403
2433
"@id": "qb:Observation"
2404
2434
},
2405
2435
"sh:nodeByExpression": {
2406
- "shnex:path ": {
2436
+ "shnex:pathValues ": {
2407
2437
"@list": [
2408
2438
{
2409
2439
"@id": "qb:dataSet"
0 commit comments