Skip to content

Commit ef4d05b

Browse files
committed
Add sh:nodeByExpression to spec
1 parent 984d90d commit ef4d05b

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
@@ -2531,6 +2531,7 @@ <h2>Node Expressions</h2>
25312531
<ul>
25322532
<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>
25332533
<li>At <a href="#targetNode"><code>sh:targetNode</code></a> to dynamically compute the targets of a shape.</li>
2534+
<li>At <a href="#NodeByExpressionConstraintComponent"><code>sh:nodeByExpression</code></a> to validate nodes against a dynamically computed set of node shapes.</li>
25342535
<li>At <a href="#ExpressionConstraintComponent"><code>sh:expression</code></a> to validate nodes against a condition.</li>
25352536
<li>At <a href="#deactivated"><code>sh:deactivated</code></a> to deactivate certain shapes under specific conditions.</li>
25362537
</ul>
@@ -6619,6 +6620,220 @@ <h4>sh:reifierShape, sh:reificationRequired</h4>
66196620
}
66206621
}
66216622
}
6623+
}</pre>
6624+
</div>
6625+
</div>
6626+
</aside>
6627+
</section>
6628+
6629+
<section id="NodeByExpressionConstraintComponent">
6630+
<h4>sh:nodeByExpression</h4>
6631+
<p>
6632+
<code>sh:nodeByExpression</code> specifies the condition that each <a>value node</a> conforms to the
6633+
<a>node shapes</a> produced by a <a>node expression</a>.
6634+
The evaluation of these node expressions is repeated for all <a>value nodes</a> of the <a>shape</a>
6635+
as the <a>focus node</a>.
6636+
</p>
6637+
<p>
6638+
<span class="component-class">Constraint Component IRI</span>: <code>sh:NodeByExpressionConstraintComponent</code>
6639+
</p>
6640+
6641+
<div class="parameters">Parameters:</div>
6642+
<table class="term-table">
6643+
<tr>
6644+
<th>Property</th>
6645+
<th>Summary and Syntax Rules</th>
6646+
</tr>
6647+
<tr>
6648+
<td><code>sh:nodeByExpression</code></td>
6649+
<td>
6650+
The <a>node shapes</a> that all value nodes need to conform to.
6651+
<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>
6652+
</td>
6653+
</tr>
6654+
</table>
6655+
<div class="def def-text">
6656+
<div class="def-header">TEXTUAL DEFINITION</div>
6657+
<div class="def-text-body" data-validator="NodeByExpression">
6658+
Let <code>$expr</code> be a <a>value</a> of <code>sh:nodeByExpression</code>.
6659+
For each <a>value node</a> <code>v</code>: perform <a>conformance checking</a> of <code>v</code> against each <a>output node</a>
6660+
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>.
6661+
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>.
6662+
Otherwise, if <code>v</code> does not <a>conform</a> to <code>s</code>,
6663+
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>.
6664+
</div>
6665+
</div>
6666+
<p><em>The remainder of this section is informative.</em></p>
6667+
<p>
6668+
<code>sh:nodeByExpression</code> functions similarly to <code>sh:node</code>, but instead of referencing a fixed <a>node shape</a>,
6669+
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.
6670+
</p>
6671+
<p>
6672+
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>.
6673+
In this case, `sh:node` directly validates against the specified <a>node shape</a>, whereas `sh:nodeByExpression` interprets the <a>IRI</a>
6674+
as an <a>IRI expression</a> that evaluates to a set containing the same <a>node shape</a>.
6675+
</p>
6676+
<p>
6677+
In the following example, all values of the property <code>ex:address</code> must fulfill the
6678+
constraints expressed by the <a>shape</a> <code>ex:AddressShape</code>.
6679+
</p>
6680+
<aside class="example">
6681+
<div class="shapes-graph">
6682+
<div class="turtle">
6683+
ex:AddressShape
6684+
a sh:NodeShape ;
6685+
sh:property [
6686+
sh:path ex:postalCode ;
6687+
sh:datatype xsd:string ;
6688+
sh:maxCount 1 ;
6689+
] .
6690+
6691+
ex:PersonShape
6692+
a sh:NodeShape ;
6693+
<span class="target-can-be-skipped">sh:targetClass ex:Person ;</span>
6694+
sh:property [ # _:b1
6695+
sh:path ex:address ;
6696+
sh:minCount 1 ;
6697+
sh:node ex:AddressShape ;
6698+
] .
6699+
</div>
6700+
<div class="jsonld">
6701+
<pre class="jsonld">{
6702+
"@graph": [
6703+
{
6704+
"@id": "ex:AddressShape",
6705+
"@type": "sh:NodeShape",
6706+
"sh:property": {
6707+
"sh:datatype": {
6708+
"@id": "xsd:string"
6709+
},
6710+
"sh:maxCount": {
6711+
"@type": "xsd:integer",
6712+
"@value": "1"
6713+
},
6714+
"sh:path": {
6715+
"@id": "ex:postalCode"
6716+
}
6717+
}
6718+
},
6719+
{
6720+
"@id": "ex:PersonShape",
6721+
"@type": "sh:NodeShape",
6722+
"sh:property": {
6723+
"sh:minCount": {
6724+
"@type": "xsd:integer",
6725+
"@value": "1"
6726+
},
6727+
"sh:node": {
6728+
"@id": "ex:AddressShape"
6729+
},
6730+
"sh:path": {
6731+
"@id": "ex:address"
6732+
}
6733+
},
6734+
"sh:targetClass": {
6735+
"@id": "ex:Person"
6736+
}
6737+
}
6738+
]
6739+
}</pre>
6740+
</div>
6741+
</div>
6742+
<div class="data-graph">
6743+
<div class="turtle">
6744+
ex:Bob a ex:Person ;
6745+
ex:address ex:BobsAddress .
6746+
6747+
ex:BobsAddress
6748+
ex:postalCode "1234" .
6749+
6750+
<span class="focus-node-error">ex:Reto</span> a ex:Person ;
6751+
ex:address ex:RetosAddress .
6752+
6753+
ex:RetosAddress
6754+
ex:postalCode 5678 .
6755+
</div>
6756+
<div class="jsonld">
6757+
<pre class="jsonld">{
6758+
"@graph": [
6759+
{
6760+
"@id": "ex:Bob",
6761+
"@type": "ex:Person",
6762+
"ex:address": {
6763+
"@id": "ex:BobsAddress"
6764+
}
6765+
},
6766+
{
6767+
"@id": "ex:BobsAddress",
6768+
"ex:postalCode": "1234"
6769+
},
6770+
{
6771+
"@id": "ex:Reto",
6772+
"@type": "ex:Person",
6773+
"ex:address": {
6774+
"@id": "ex:RetosAddress"
6775+
}
6776+
},
6777+
{
6778+
"@id": "ex:RetosAddress",
6779+
"ex:postalCode": {
6780+
"@type": "xsd:integer",
6781+
"@value": "5678"
6782+
}
6783+
}
6784+
]
6785+
}</pre>
6786+
</div>
6787+
</div>
6788+
<div class="results-graph">
6789+
<div class="turtle">
6790+
[ a sh:ValidationReport ;
6791+
sh:conforms false ;
6792+
sh:result [
6793+
a sh:ValidationResult ;
6794+
sh:resultSeverity sh:Violation ;
6795+
sh:focusNode ex:Reto ;
6796+
sh:resultPath ex:address ;
6797+
sh:value ex:RetosAddress ;
6798+
sh:resultMessage "Value does not conform to shape ex:AddressShape." ;
6799+
sh:sourceConstraint ex:AddressShape ;
6800+
sh:sourceConstraintComponent sh:NodeByExpressionConstraintComponent ;
6801+
sh:sourceShape _:b1 ;
6802+
]
6803+
] .
6804+
</div>
6805+
<div class="jsonld">
6806+
<pre class="jsonld">{
6807+
"@type": "sh:ValidationReport",
6808+
"sh:conforms": {
6809+
"@type": "xsd:boolean",
6810+
"@value": "false"
6811+
},
6812+
"sh:result": {
6813+
"@type": "sh:ValidationResult",
6814+
"sh:focusNode": {
6815+
"@id": "ex:Reto"
6816+
},
6817+
"sh:resultMessage": "Value does not conform to shape ex:AddressShape.",
6818+
"sh:resultPath": {
6819+
"@id": "ex:address"
6820+
},
6821+
"sh:resultSeverity": {
6822+
"@id": "sh:Violation"
6823+
},
6824+
"sh:sourceConstraint": {
6825+
"@id": "ex:AddressShape"
6826+
},
6827+
"sh:sourceConstraintComponent": {
6828+
"@id": "sh:NodeByExpressionConstraintComponent"
6829+
},
6830+
"sh:sourceShape": {
6831+
"@id": "_:b66_b1"
6832+
},
6833+
"sh:value": {
6834+
"@id": "ex:RetosAddress"
6835+
}
6836+
}
66226837
}</pre>
66236838
</div>
66246839
</div>
@@ -7526,6 +7741,7 @@ <h2>Changes between SHACL 1.0 Core and SHACL 1.2 Core</h2>
75267741
<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>
75277742
<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>
75287743
<li>Added the new value <code>sh:ByTypes</code> for <a href="#ClosedConstraintComponent"><code>sh:closed</code></a>; see <a href="https://github.com/w3c/data-shapes/issues/172">Issue 172</a></li>
7744+
<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>
75297745
<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>
75307746
</ul>
75317747
</section>

0 commit comments

Comments
 (0)