@@ -600,8 +600,8 @@ <h2>Getting started with Node Expressions</h2>
600600 < p >
601601 The following diagram illustrates how this node expression is interpreted, from a logical point of view.
602602 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 >
605605 and is an < a > instancesOf expression</ a > .
606606 This will produce all instances of the given class, < code > ex:Company</ code > .
607607 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>
669669 sh:datatype xsd:integer ;
670670 sh:values < b > [
671671 shnex:count [
672- shnex:path ex:employee ;
672+ shnex:pathValues ex:employee ;
673673 ]
674674 ]</ b > .
675675 </ div >
@@ -859,14 +859,14 @@ <h3>List Parameter Functions</h3>
859859 sh:values < b > [
860860 ex:coalesce (
861861 [
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 ;
864864 ]
865865 [
866866 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
868868 " " # 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
870870 )
871871 ]
872872 )
@@ -1055,7 +1055,7 @@ <h3>List Expressions</h3>
10551055 sh:values [
10561056 shnex:nodes [
10571057 # This returns all transitive superclasses of the current focus node
1058- shnex:path [ sh:zeroOrMorePath rdfs:subClassOf ] ;
1058+ shnex:pathValues [ sh:zeroOrMorePath rdfs:subClassOf ] ;
10591059 ] ;
10601060 # This removes any superclasses that are in the list below
10611061 shnex:minus < b > ( owl:Thing rdfs:Resource )</ b > ;
@@ -1069,12 +1069,12 @@ <h3>List Expressions</h3>
10691069 </ p >
10701070 </ section >
10711071
1072- < section id ="PathExpression ">
1073- < h3 > Path Expressions</ h3 >
1072+ < section id ="PathValuesExpression ">
1073+ < h3 > Path Values Expressions</ h3 >
10741074 < p class ="syntax ">
1075- < span data-syntax-rule ="PathExpression -syntax ">
1075+ < span data-syntax-rule ="PathValuesExpression -syntax ">
10761076 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 > :
10781078 < table class ="term-table ">
10791079 < thead >
10801080 < th > Property</ th >
@@ -1083,7 +1083,7 @@ <h3>Path Expressions</h3>
10831083 </ thead >
10841084 < tbody >
10851085 < tr >
1086- < td > < b > < code > shnex:path </ code > </ b > </ td >
1086+ < td > < b > < code > shnex:pathValues </ code > </ b > </ td >
10871087 < td >
10881088 Must be a < a > well-formed</ a > < a > SHACL property path</ a > .
10891089 </ td >
@@ -1092,41 +1092,49 @@ <h3>Path Expressions</h3>
10921092 </ td >
10931093 </ tr >
10941094 < tr >
1095- < td > < code > shnex:nodes </ code > </ td >
1095+ < td > < code > shnex:focusNode </ code > </ td >
10961096 < td >
10971097 Optional, must be a < a > well-formed</ a > < a > node expression</ a > .
10981098 </ td >
10991099 < 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.
11021102 </ td >
11031103 </ tr >
11041104 </ tbody >
11051105 </ table >
11061106 </ span >
11071107 </ 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 >
11101110 < 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 > .
11181120 </ p >
11191121 </ div >
11201122 < p > < em > The remainder of this section is informative.</ em > </ p >
11211123 < 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
11231131 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
11261134 number of top concepts.
11271135 </ p >
11281136 < 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 ">
11301138 < div class ="shapes-graph ">
11311139 < div class ="turtle ">
11321140skos:ConceptScheme
@@ -1141,18 +1149,40 @@ <h3>Path Expressions</h3>
11411149 sh:maxCount 1 ;
11421150 sh:name "top concept count" ;
11431151 sh:values [
1144- shnex:count [
1145- < b > shnex:path skos:hasTopConcept</ b > ;
1146- ] ;
1152+ shnex:count < b > [
1153+ shnex:pathValues skos:hasTopConcept ;
1154+ ]</ b > ;
11471155 ] .
11481156 </ div >
11491157 < div class ="jsonld ">
11501158 TODO
11511159 </ div >
11521160 </ div >
11531161 </ 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 >
11541185 </ p >
1155- < p class ="todo "> TODO: Add second example that uses shnex:nodes</ p >
11561186 </ section >
11571187
11581188 < section id ="ExistsExpression ">
@@ -1279,15 +1309,15 @@ <h3>If Expressions</h3>
12791309 sh:path ex:fillColor ;
12801310 sh:datatype xsd:string ;
12811311 sh:name "fill color" ;
1282- sh:values [
1283- < b > shnex:if [
1312+ sh:values < b > [
1313+ shnex:if [
12841314 shnex:exists [
1285- shnex:path ex:capitalOf ;
1315+ shnex:pathValues ex:capitalOf ;
12861316 ] ;
12871317 ] ;
12881318 shnex:then "blue" ;
1289- shnex:else "red" ;</ b >
1290- ] .
1319+ shnex:else "red" ;
1320+ ]</ b > .
12911321 </ div >
12921322 < div class ="jsonld ">
12931323 TODO
@@ -1360,16 +1390,16 @@ <h3>Distinct Expressions</h3>
13601390 a sh:PropertyShape ;
13611391 sh:path ex:superClassesIncludingRoot ;
13621392 sh:description "The superclasses of this, always including rdfs:Resource." ;
1363- sh:values [
1364- < b > shnex:distinct [
1393+ sh:values < b > [
1394+ shnex:distinct [
13651395 shnex:union (
13661396 [
1367- shnex:path [ sh:zeroOrMorePath rdfs:subClassOf ] ;
1397+ shnex:pathValues [ sh:zeroOrMorePath rdfs:subClassOf ] ;
13681398 ]
13691399 ( rdfs:Resource )
13701400 )
1371- ] ; </ b >
1372- ] .</ b >
1401+ ]</ b > ;
1402+ ] .
13731403 </ div >
13741404 < div class ="jsonld ">
13751405 TODO
@@ -1426,12 +1456,12 @@ <h3>Intersection Expressions</h3>
14261456 < div class ="turtle ">
14271457ex:DualCitizenShape
14281458 a sh:NodeShape ;
1429- sh:targetNode [
1430- < b > shnex:intersection (
1459+ sh:targetNode < b > [
1460+ shnex:intersection (
14311461 [ shnex:instancesOf ex:Australian ]
14321462 [ shnex:instancesOf ex:German ]
1433- )</ b >
1434- ] .
1463+ )
1464+ ]</ b > .
14351465 </ div >
14361466 < div class ="jsonld ">
14371467 TODO
@@ -1540,11 +1570,11 @@ <h3>Minus Expressions</h3>
15401570 </ section >
15411571
15421572 < section id ="FilterShapeExpression ">
1543- < h3 > FilterShape Expressions</ h3 >
1573+ < h3 > Filter Shape Expressions</ h3 >
15441574 < p class ="syntax ">
15451575 < span data-syntax-rule ="FilterShapeExpression-syntax ">
15461576 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 > :
15481578 < table class ="term-table ">
15491579 < thead >
15501580 < th > Property</ th >
@@ -1575,11 +1605,11 @@ <h3>FilterShape Expressions</h3>
15751605 </ span >
15761606 </ p >
15771607 < 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 >
15791609 < p >
15801610 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
15831613 < code > evalExpr(nodes, focusGraph, focusNode, scope)</ code > except those that do not < a > conform</ a > to
15841614 the < a > shape</ a > < code > filterShape</ code > , preserving the order in the list.
15851615 </ p >
@@ -1604,7 +1634,7 @@ <h3>FilterShape Expressions</h3>
16041634 sh:class ex:Person ;
16051635 sh:values < b > [
16061636 shnex:nodes</ b > [
1607- shnex:path ex:child ;
1637+ shnex:pathValues ex:child ;
16081638 ] ;
16091639 < b > shnex:filterShape [
16101640 sh:property [
@@ -1694,7 +1724,7 @@ <h3>Limit Expressions</h3>
16941724 sh:values < b > [
16951725 shnex:nodes</ b > [
16961726 shnex:nodes [
1697- shnex:path ex:child ;
1727+ shnex:pathValues ex:child ;
16981728 ] ;
16991729 shnex:orderBy ex:dateOfBirth ;
17001730 ] ;
@@ -1781,7 +1811,7 @@ <h3>Offset Expressions</h3>
17811811 sh:values < b > [
17821812 shnex:nodes</ b > [
17831813 shnex:nodes [
1784- shnex:path ex:child ;
1814+ shnex:pathValues ex:child ;
17851815 ] ;
17861816 shnex:orderBy ex:dateOfBirth ;
17871817 ] ;
@@ -1867,7 +1897,7 @@ <h3>Count Expressions</h3>
18671897 sh:name "top concept count" ;
18681898 sh:values [
18691899 shnex:count [
1870- shnex:path skos:hasTopConcept ;
1900+ shnex:pathValues skos:hasTopConcept ;
18711901 ] ;
18721902 ] .
18731903 </ div >
@@ -1940,7 +1970,7 @@ <h3>Min Expressions</h3>
19401970 sh:name "min start date" ;
19411971 sh:values [
19421972 shnex:min [
1943- shnex:path ( ex:employee ex:startDate ) ;
1973+ shnex:pathValues ( ex:employee ex:startDate ) ;
19441974 ] ;
19451975 ] .
19461976 </ div >
@@ -2035,8 +2065,8 @@ <h3>Sum Expressions</h3>
20352065 < p >
20362066 Note that < code > shnex:sum</ code > needs to be used with care and may be often misunderstood,
20372067 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 > .
20402070 As a result, only the distinct values will be added up.
20412071 </ p >
20422072 < p class ="todo "> TODO: Find good example, or drop the feature if none makes sense</ p >
@@ -2183,7 +2213,7 @@ <h3>sh:expression</h3>
21832213 [
21842214 sparql:ucase (
21852215 [
2186- shnex:path ( ex:country ex:code )
2216+ shnex:pathValues ( ex:country ex:code )
21872217 shnex:nodes [ shnex:var "focusNode" ]
21882218 ]
21892219 )
@@ -2292,7 +2322,7 @@ <h3>sh:nodeByExpression</h3>
22922322 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 > .
22932323 Building upon examples 5 and 6 from the Data Cube Vocabulary documentation, Data Structure Definition is extended with the property < code > eg:hasShape</ code > ,
22942324 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 >
22962326 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.
22972327 </ p >
22982328 < aside class ="example ">
@@ -2325,7 +2355,7 @@ <h3>sh:nodeByExpression</h3>
23252355 a sh:NodeShape ;
23262356 sh:targetClass qb:Observation ;
23272357 sh:nodeByExpression [
2328- shnex:path (qb:dataSet qb:structure eg:hasShape) ;
2358+ shnex:pathValues (qb:dataSet qb:structure eg:hasShape) ;
23292359 ] .
23302360 </ div >
23312361 < div class ="jsonld ">
@@ -2403,7 +2433,7 @@ <h3>sh:nodeByExpression</h3>
24032433 "@id": "qb:Observation"
24042434 },
24052435 "sh:nodeByExpression": {
2406- "shnex:path ": {
2436+ "shnex:pathValues ": {
24072437 "@list": [
24082438 {
24092439 "@id": "qb:dataSet"
0 commit comments