Skip to content

Commit 97fa49f

Browse files
committed
Add sh:nodeByExpression to spec
1 parent a932976 commit 97fa49f

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

shacl12-core/index.html

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2520,6 +2520,7 @@ <h2>Node Expressions</h2>
25202520
<ul>
25212521
<li>At <a href="#property-shapes"><code>sh:values</code> and <code>sh:defaultValue</code></a> to derive the value nodes of a property shape.</li>
25222522
<li>At <a href="#targetNode"><code>sh:targetNode</code></a> to dynamically compute the targets of a shape.</li>
2523+
<li>At <a href="#NodeByExpressionConstraintComponent"><code>sh:nodeByExpression</code></a> to validate nodes against a dynamically computed set of node shapes.</li>
25232524
<li>At <a href="#ExpressionConstraintComponent"><code>sh:expression</code></a> to validate nodes against a condition.</li>
25242525
<li>At <a href="#deactivated"><code>sh:deactivated</code></a> to deactivate certain shapes under specific conditions.</li>
25252526
</ul>
@@ -6074,6 +6075,220 @@ <h4>sh:reifierShape, sh:reificationRequired</h4>
60746075
</div>
60756076
</aside>
60766077
</section>
6078+
6079+
<section id="NodeByExpressionConstraintComponent">
6080+
<h4>sh:nodeByExpression</h4>
6081+
<p>
6082+
<code>sh:nodeByExpression</code> specifies the condition that each <a>value node</a> conforms to the
6083+
<a>node shapes</a> produced by a <a>node expression</a>.
6084+
The evaluation of these node expressions is repeated for all <a>value nodes</a> of the <a>shape</a>
6085+
as the <a>focus node</a>.
6086+
</p>
6087+
<p>
6088+
<span class="component-class">Constraint Component IRI</span>: <code>sh:NodeByExpressionConstraintComponent</code>
6089+
</p>
6090+
6091+
<div class="parameters">Parameters:</div>
6092+
<table class="term-table">
6093+
<tr>
6094+
<th>Property</th>
6095+
<th>Summary and Syntax Rules</th>
6096+
</tr>
6097+
<tr>
6098+
<td><code>sh:nodeByExpression</code></td>
6099+
<td>
6100+
The <a>node shapes</a> that all value nodes need to conform to.
6101+
<span data-syntax-rule="nodeByExpression-scope">The <a>values</a> of <code>sh:nodeByExpression</code> in a shape must be <a>well-formed</a> <a>node expressions</a>.</span>
6102+
</td>
6103+
</tr>
6104+
</table>
6105+
<div class="def def-text">
6106+
<div class="def-header">TEXTUAL DEFINITION</div>
6107+
<div class="def-text-body" data-validator="NodeByExpression">
6108+
Let <code>$expr</code> be a <a>value</a> of <code>sh:nodeByExpression</code>.
6109+
For each <a>value node</a> <code>v</code>: perform <a>conformance checking</a> of <code>v</code> against each <a>output node</a>
6110+
of <code>evalExpr(expr, <a>data graph</a>, v, {})</code> <code>s</code> that is a <a>node shape</a> in the <a>shapes graph</a>.
6111+
For each conformance check, a <a>failure</a> MUST be produced if the <a>conformance checking</a> of <code>v</code> against <code>s</code> produces a <a>failure</a>.
6112+
Otherwise, if <code>v</code> does not <a>conform</a> to <code>s</code>,
6113+
there is a <a>validation result</a> with <code>v</code> as <code>sh:value</code> and a <a>deep copy</a> of <code>s</code> as <code>sh:sourceConstraint</code>.
6114+
</div>
6115+
</div>
6116+
<p><em>The remainder of this section is informative.</em></p>
6117+
<p>
6118+
<code>sh:nodeByExpression</code> functions similarly to <code>sh:node</code>, but instead of referencing a fixed <a>node shape</a>,
6119+
a referenced <a>node expression</a> is used to dynamically compute the set of <a>node shapes</a> to which each <a>value node</a> must conform.
6120+
</p>
6121+
<p>
6122+
Note that `sh:node` and `sh:nodeByExpression` exhibit the same behavior when given a <a>value</a> that is an <a>IRI</a> of a <a>node shape</a>.
6123+
In this case, `sh:node` directly validates against the specified <a>node shape</a>, whereas `sh:nodeByExpression` interprets the <a>IRI</a>
6124+
as an <a>IRI expression</a> that evaluates to a set containing the same <a>node shape</a>.
6125+
</p>
6126+
<p>
6127+
In the following example, all values of the property <code>ex:address</code> must fulfill the
6128+
constraints expressed by the <a>shape</a> <code>ex:AddressShape</code>.
6129+
</p>
6130+
<aside class="example">
6131+
<div class="shapes-graph">
6132+
<div class="turtle">
6133+
ex:AddressShape
6134+
a sh:NodeShape ;
6135+
sh:property [
6136+
sh:path ex:postalCode ;
6137+
sh:datatype xsd:string ;
6138+
sh:maxCount 1 ;
6139+
] .
6140+
6141+
ex:PersonShape
6142+
a sh:NodeShape ;
6143+
<span class="target-can-be-skipped">sh:targetClass ex:Person ;</span>
6144+
sh:property [ # _:b1
6145+
sh:path ex:address ;
6146+
sh:minCount 1 ;
6147+
sh:node ex:AddressShape ;
6148+
] .
6149+
</div>
6150+
<div class="jsonld">
6151+
<pre class="jsonld">{
6152+
"@graph": [
6153+
{
6154+
"@id": "ex:AddressShape",
6155+
"@type": "sh:NodeShape",
6156+
"sh:property": {
6157+
"sh:datatype": {
6158+
"@id": "xsd:string"
6159+
},
6160+
"sh:maxCount": {
6161+
"@type": "xsd:integer",
6162+
"@value": "1"
6163+
},
6164+
"sh:path": {
6165+
"@id": "ex:postalCode"
6166+
}
6167+
}
6168+
},
6169+
{
6170+
"@id": "ex:PersonShape",
6171+
"@type": "sh:NodeShape",
6172+
"sh:property": {
6173+
"sh:minCount": {
6174+
"@type": "xsd:integer",
6175+
"@value": "1"
6176+
},
6177+
"sh:node": {
6178+
"@id": "ex:AddressShape"
6179+
},
6180+
"sh:path": {
6181+
"@id": "ex:address"
6182+
}
6183+
},
6184+
"sh:targetClass": {
6185+
"@id": "ex:Person"
6186+
}
6187+
}
6188+
]
6189+
}</pre>
6190+
</div>
6191+
</div>
6192+
<div class="data-graph">
6193+
<div class="turtle">
6194+
ex:Bob a ex:Person ;
6195+
ex:address ex:BobsAddress .
6196+
6197+
ex:BobsAddress
6198+
ex:postalCode "1234" .
6199+
6200+
<span class="focus-node-error">ex:Reto</span> a ex:Person ;
6201+
ex:address ex:RetosAddress .
6202+
6203+
ex:RetosAddress
6204+
ex:postalCode 5678 .
6205+
</div>
6206+
<div class="jsonld">
6207+
<pre class="jsonld">{
6208+
"@graph": [
6209+
{
6210+
"@id": "ex:Bob",
6211+
"@type": "ex:Person",
6212+
"ex:address": {
6213+
"@id": "ex:BobsAddress"
6214+
}
6215+
},
6216+
{
6217+
"@id": "ex:BobsAddress",
6218+
"ex:postalCode": "1234"
6219+
},
6220+
{
6221+
"@id": "ex:Reto",
6222+
"@type": "ex:Person",
6223+
"ex:address": {
6224+
"@id": "ex:RetosAddress"
6225+
}
6226+
},
6227+
{
6228+
"@id": "ex:RetosAddress",
6229+
"ex:postalCode": {
6230+
"@type": "xsd:integer",
6231+
"@value": "5678"
6232+
}
6233+
}
6234+
]
6235+
}</pre>
6236+
</div>
6237+
</div>
6238+
<div class="results-graph">
6239+
<div class="turtle">
6240+
[ a sh:ValidationReport ;
6241+
sh:conforms false ;
6242+
sh:result [
6243+
a sh:ValidationResult ;
6244+
sh:resultSeverity sh:Violation ;
6245+
sh:focusNode ex:Reto ;
6246+
sh:resultPath ex:address ;
6247+
sh:value ex:RetosAddress ;
6248+
sh:resultMessage "Value does not conform to shape ex:AddressShape." ;
6249+
sh:sourceConstraint ex:AddressShape ;
6250+
sh:sourceConstraintComponent sh:NodeByExpressionConstraintComponent ;
6251+
sh:sourceShape _:b1 ;
6252+
]
6253+
] .
6254+
</div>
6255+
<div class="jsonld">
6256+
<pre class="jsonld">{
6257+
"@type": "sh:ValidationReport",
6258+
"sh:conforms": {
6259+
"@type": "xsd:boolean",
6260+
"@value": "false"
6261+
},
6262+
"sh:result": {
6263+
"@type": "sh:ValidationResult",
6264+
"sh:focusNode": {
6265+
"@id": "ex:Reto"
6266+
},
6267+
"sh:resultMessage": "Value does not conform to shape ex:AddressShape.",
6268+
"sh:resultPath": {
6269+
"@id": "ex:address"
6270+
},
6271+
"sh:resultSeverity": {
6272+
"@id": "sh:Violation"
6273+
},
6274+
"sh:sourceConstraint": {
6275+
"@id": "ex:AddressShape"
6276+
},
6277+
"sh:sourceConstraintComponent": {
6278+
"@id": "sh:NodeByExpressionConstraintComponent"
6279+
},
6280+
"sh:sourceShape": {
6281+
"@id": "_:b66_b1"
6282+
},
6283+
"sh:value": {
6284+
"@id": "ex:RetosAddress"
6285+
}
6286+
}
6287+
}</pre>
6288+
</div>
6289+
</div>
6290+
</aside>
6291+
</section>
60776292
</section>
60786293

60796294
<section id="core-components-others">
@@ -6938,6 +7153,7 @@ <h2>Changes between SHACL 1.0 Core and SHACL 1.2 Core</h2>
69387153
<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>
69397154
<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>
69407155
<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>
7156+
<li>Added the new constraint component <a href="#NodeByExpressionConstraintComponent"><code>sh:nodeByExpression</code></a>, see <a href="https://github.com/w3c/data-shapes/issues/408">Issue 408</a></li>
69417157
<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>
69427158
</ul>
69437159
</section>

0 commit comments

Comments
 (0)