Skip to content

Commit 0e5c84b

Browse files
Issue 481 - move nodeByExpression and expression to Node Expr spec and give better examples (#492)
* #481: Moved sh:expression and sh:nodeByExpression to Node Expression spec * Added example for sh:expression and changed binding of focusNode and added scope var "value" * Added example for sh:nodeByExpression * Fixed tabs vs spaces * Moved test cases from core into node-expr * Taking out the ability to specify sh:message in sh:expression * PR feedback applied --------- Co-authored-by: Matt Goldberg <[email protected]>
1 parent d691679 commit 0e5c84b

File tree

8 files changed

+570
-287
lines changed

8 files changed

+570
-287
lines changed

shacl12-core/index.html

Lines changed: 0 additions & 283 deletions
Original file line numberDiff line numberDiff line change
@@ -2591,8 +2591,6 @@ <h2>Node Expressions</h2>
25912591
<ul>
25922592
<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>
25932593
<li>At <a href="#targetNode"><code>sh:targetNode</code></a> to dynamically compute the targets of a shape.</li>
2594-
<li>At <a href="#NodeByExpressionConstraintComponent"><code>sh:nodeByExpression</code></a> to validate nodes against a dynamically computed set of node shapes.</li>
2595-
<li>At <a href="#ExpressionConstraintComponent"><code>sh:expression</code></a> to validate nodes against a condition.</li>
25962594
<li>At <a href="#deactivated"><code>sh:deactivated</code></a> to deactivate certain shapes under specific conditions.</li>
25972595
</ul>
25982596
<p>
@@ -6812,238 +6810,6 @@ <h4>sh:reifierShape, sh:reificationRequired</h4>
68126810
</aside>
68136811
</section>
68146812

6815-
<section id="NodeByExpressionConstraintComponent">
6816-
<h4>sh:nodeByExpression</h4>
6817-
<p>
6818-
<code>sh:nodeByExpression</code> specifies the condition that each <a>value node</a> conforms to the
6819-
<a>node shapes</a> produced by a <a>node expression</a>.
6820-
The evaluation of these node expressions is repeated for all <a>value nodes</a> of the <a>shape</a>
6821-
as the <a>focus node</a>.
6822-
</p>
6823-
<p>
6824-
<span class="component-class">Constraint Component IRI</span>: <code>sh:NodeByExpressionConstraintComponent</code>
6825-
</p>
6826-
6827-
<div class="parameters">Parameters:</div>
6828-
<table class="term-table">
6829-
<tr>
6830-
<th>Property</th>
6831-
<th>Summary and Syntax Rules</th>
6832-
</tr>
6833-
<tr>
6834-
<td><code>sh:nodeByExpression</code></td>
6835-
<td>
6836-
The <a>node shapes</a> that all value nodes need to conform to.
6837-
<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>
6838-
</td>
6839-
</tr>
6840-
</table>
6841-
<div class="def def-text">
6842-
<div class="def-header">TEXTUAL DEFINITION</div>
6843-
<div class="def-text-body" data-validator="NodeByExpression">
6844-
Let <code>$expr</code> be a <a>value</a> of <code>sh:nodeByExpression</code>.
6845-
For each <a>value node</a> <code>v</code>: perform a <a>conformance check</a> of
6846-
<code>v</code> against each <a>output node</a> of <code>evalExpr(expr,
6847-
<a>data graph</a>, v, {})</code> <code>s</code>. A <a>failure</a>
6848-
MUST be produced if the <a>conformance check</a> of <code>v</code> against
6849-
<code>s</code> produces a <a>failure</a>. Otherwise, if <code>v</code> does
6850-
not <a>conform</a> to <code>s</code>, there is a <a>validation result</a>
6851-
with <code>v</code> as <code>sh:value</code> and a <a>deep copy</a> of
6852-
<code>s</code> as <code>sh:sourceConstraint</code>.
6853-
</div>
6854-
</div>
6855-
<p><em>The remainder of this section is informative.</em></p>
6856-
<p>
6857-
<code>sh:nodeByExpression</code> functions similarly to <code>sh:node</code>, but instead of referencing a fixed <a>node shape</a>,
6858-
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.
6859-
</p>
6860-
<p>
6861-
There are three key differences between <code>sh:nodeByExpression</code> and <a href="#NodeConstraintComponent"><code>sh:node</code></a>:
6862-
<ol>
6863-
<li>
6864-
<code>sh:nodeByExpression</code> references a <a>node expression</a> instead of a fixed <a>node shape</a> as <code>sh:node</code> does.
6865-
</li>
6866-
<li>
6867-
<code>sh:nodeByExpression</code> cannot reference a <a>node shape</a> that is a <a>blank node</a> as a value like <code>sh:node</code> can,
6868-
as a <a>blank node</a> would be interpreted as a <a>node expression</a>.
6869-
</li>
6870-
<li>
6871-
<a>Results</a> generated by <code>sh:nodeByExpression</code> additionally include a value for `sh:sourceConstraint`.
6872-
</li>
6873-
6874-
</ol>
6875-
</p>
6876-
<p>
6877-
Note that <code>sh:node</code> and <code>sh:nodeByExpression</code> exhibit the same behavior when given a <a>value</a> that is an <a>IRI</a> of a <a>node shape</a>.
6878-
In this case, <code>sh:node</code> directly validates against the specified <a>node shape</a>, whereas <code>sh:nodeByExpression</code> interprets the <a>IRI</a>
6879-
as an <a>IRI expression</a> that evaluates to a set containing the same <a>node shape</a>.
6880-
</p>
6881-
<p>
6882-
In the following example, all values of the property <code>ex:address</code> must fulfill the
6883-
constraints expressed by the <a>shape</a> <code>ex:AddressShape</code>.
6884-
</p>
6885-
<aside class="example">
6886-
<div class="shapes-graph">
6887-
<div class="turtle">
6888-
ex:AddressShape
6889-
a sh:NodeShape ;
6890-
sh:property [
6891-
sh:path ex:postalCode ;
6892-
sh:datatype xsd:string ;
6893-
sh:maxCount 1 ;
6894-
] .
6895-
6896-
ex:PersonShape
6897-
a sh:NodeShape ;
6898-
sh:targetClass ex:Person ;
6899-
sh:property [ # _:b1
6900-
sh:path ex:address ;
6901-
sh:minCount 1 ;
6902-
sh:nodeByExpression ex:AddressShape ;
6903-
] .
6904-
</div>
6905-
<div class="jsonld">
6906-
<pre class="jsonld">{
6907-
"@graph": [
6908-
{
6909-
"@id": "ex:AddressShape",
6910-
"@type": "sh:NodeShape",
6911-
"sh:property": {
6912-
"sh:datatype": {
6913-
"@id": "xsd:string"
6914-
},
6915-
"sh:maxCount": {
6916-
"@type": "xsd:integer",
6917-
"@value": "1"
6918-
},
6919-
"sh:path": {
6920-
"@id": "ex:postalCode"
6921-
}
6922-
}
6923-
},
6924-
{
6925-
"@id": "ex:PersonShape",
6926-
"@type": "sh:NodeShape",
6927-
"sh:property": {
6928-
"sh:minCount": {
6929-
"@type": "xsd:integer",
6930-
"@value": "1"
6931-
},
6932-
"sh:nodeByExpression": {
6933-
"@id": "ex:AddressShape"
6934-
},
6935-
"sh:path": {
6936-
"@id": "ex:address"
6937-
}
6938-
},
6939-
"sh:targetClass": {
6940-
"@id": "ex:Person"
6941-
}
6942-
}
6943-
]
6944-
}</pre>
6945-
</div>
6946-
</div>
6947-
<div class="data-graph">
6948-
<div class="turtle">
6949-
ex:Bob a ex:Person ;
6950-
ex:address ex:BobsAddress .
6951-
6952-
ex:BobsAddress
6953-
ex:postalCode "1234" .
6954-
6955-
<span class="focus-node-error">ex:Reto</span> a ex:Person ;
6956-
ex:address ex:RetosAddress .
6957-
6958-
ex:RetosAddress
6959-
ex:postalCode 5678 .
6960-
</div>
6961-
<div class="jsonld">
6962-
<pre class="jsonld">{
6963-
"@graph": [
6964-
{
6965-
"@id": "ex:Bob",
6966-
"@type": "ex:Person",
6967-
"ex:address": {
6968-
"@id": "ex:BobsAddress"
6969-
}
6970-
},
6971-
{
6972-
"@id": "ex:BobsAddress",
6973-
"ex:postalCode": "1234"
6974-
},
6975-
{
6976-
"@id": "ex:Reto",
6977-
"@type": "ex:Person",
6978-
"ex:address": {
6979-
"@id": "ex:RetosAddress"
6980-
}
6981-
},
6982-
{
6983-
"@id": "ex:RetosAddress",
6984-
"ex:postalCode": {
6985-
"@type": "xsd:integer",
6986-
"@value": "5678"
6987-
}
6988-
}
6989-
]
6990-
}</pre>
6991-
</div>
6992-
</div>
6993-
<div class="results-graph">
6994-
<div class="turtle">
6995-
[ a sh:ValidationReport ;
6996-
sh:conforms false ;
6997-
sh:result [
6998-
a sh:ValidationResult ;
6999-
sh:resultSeverity sh:Violation ;
7000-
sh:focusNode ex:Reto ;
7001-
sh:resultPath ex:address ;
7002-
sh:value ex:RetosAddress ;
7003-
sh:resultMessage "Value does not conform to shape ex:AddressShape." ;
7004-
sh:sourceConstraint ex:AddressShape ;
7005-
sh:sourceConstraintComponent sh:NodeByExpressionConstraintComponent ;
7006-
sh:sourceShape _:b1 ;
7007-
]
7008-
] .
7009-
</div>
7010-
<div class="jsonld">
7011-
<pre class="jsonld">{
7012-
"@type": "sh:ValidationReport",
7013-
"sh:conforms": {
7014-
"@type": "xsd:boolean",
7015-
"@value": "false"
7016-
},
7017-
"sh:result": {
7018-
"@type": "sh:ValidationResult",
7019-
"sh:focusNode": {
7020-
"@id": "ex:Reto"
7021-
},
7022-
"sh:resultMessage": "Value does not conform to shape ex:AddressShape.",
7023-
"sh:resultPath": {
7024-
"@id": "ex:address"
7025-
},
7026-
"sh:resultSeverity": {
7027-
"@id": "sh:Violation"
7028-
},
7029-
"sh:sourceConstraint": {
7030-
"@id": "ex:AddressShape"
7031-
},
7032-
"sh:sourceConstraintComponent": {
7033-
"@id": "sh:NodeByExpressionConstraintComponent"
7034-
},
7035-
"sh:sourceShape": {
7036-
"@id": "_:b66_b1"
7037-
},
7038-
"sh:value": {
7039-
"@id": "ex:RetosAddress"
7040-
}
7041-
}
7042-
}</pre>
7043-
</div>
7044-
</div>
7045-
</aside>
7046-
</section>
70476813
</section>
70486814

70496815
<section id="core-components-others">
@@ -7413,53 +7179,6 @@ <h4>sh:in</h4>
74137179
</div>
74147180
</aside>
74157181
</section>
7416-
7417-
<section id="ExpressionConstraintComponent">
7418-
<h4>sh:expression</h4>
7419-
<p>
7420-
Based on <a>node expressions</a>, this section introduces a <a>constraint component</a> called
7421-
<dfn data-lt="expression constraint">expression constraints</dfn>.
7422-
Expression constraints can be used in any <a>shape</a> to declare the condition that the
7423-
<a>node expression</a> specified via <code>sh:expression</code> has <code>true</code> as its only output node.
7424-
The evaluation of these node expressions is repeated for all <a>value nodes</a> of the <a>shape</a>
7425-
as the <a>focus node</a>.
7426-
</p>
7427-
<p>
7428-
<span class="component-class">Constraint Component IRI</span>: <code>sh:ExpressionConstraintComponent</code>
7429-
</p>
7430-
7431-
<div class="parameters">Parameters:</div>
7432-
<table class="term-table">
7433-
<thead><tr>
7434-
<th>Property</th>
7435-
<th>Summary and Syntax Rules</th>
7436-
</tr>
7437-
</thead>
7438-
<tbody>
7439-
<tr>
7440-
<td><code>sh:expression</code></td>
7441-
<td>
7442-
The <a>node expression</a> that must return <code>true</code>.
7443-
<span data-syntax-rule="expression-scope">The <a>values</a> of <code>sh:expression</code> at a
7444-
<a>shape</a> must be well-formed <a>node expressions</a>.</span>
7445-
</td>
7446-
</tr>
7447-
</tbody></table>
7448-
<div class="def def-text">
7449-
<div class="def-header">TEXTUAL DEFINITION</div>
7450-
<div class="def-text-body" data-validator="Expression">
7451-
Let <code>$expr</code> be a <a>value</a> of <code>sh:expression</code>.
7452-
For each <a>value node</a> <code>v</code>
7453-
where <code>evalExpr(expr, <a>data graph</a>, v, {})</code>
7454-
does not return the list consisting of exactly <code>true</code> as its <a>output nodes</a>,
7455-
there is a <a>validation result</a> that has <code>v</code> as its <code>sh:value</code>
7456-
and a <a>deep copy</a> of <code>$expr</code> in the results graph as its <code>sh:sourceConstraint</code>.
7457-
If the <code>$expr</code> has <a>values</a> for <code>sh:message</code> in the <a>shapes graph</a>,
7458-
then these <a>values</a> become the (only) values for <code>sh:resultMessage</code> in the
7459-
<a>validation result</a>.
7460-
</div>
7461-
</div>
7462-
</section>
74637182
</section>
74647183
</section>
74657184

@@ -7963,8 +7682,6 @@ <h2>Changes between SHACL 1.0 Core and SHACL 1.2 Core</h2>
79637682
<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>
79647683
<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>
79657684
<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>
7966-
<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>
7967-
<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>
79687685
<li>Added new <a href="#core-components-list">List constraint components</a>, see <a href="https://github.com/w3c/data-shapes/issues/391">Issue 391</a> and <a href="https://github.com/w3c/data-shapes/issues/414">Issue 414</a></li>
79697686
<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>
79707687
<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>

0 commit comments

Comments
 (0)