Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions shacl12-core/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2398,7 +2398,7 @@ <h3>Node Expressions</h3>
</div>
<div class="def" id="node-expression-evaluation">
<div class="def-header">EVALUATION OF NODE EXPRESSIONS</div>
The <dfn>evaluation</dfn> of a node expression is defined as a function <code>eval(expr, activeGraph, scope) -> outputNodes</code>
The <dfn>evaluation</dfn> of a node expression is defined as a function <code>evalExpr(expr, activeGraph, scope) -> outputNodes</code>
where
<ul>
<li><code>expr</code> is a <a>node expression</a> that is the <a>subject</a> of <a>triples</a> where the <a>predicates</a> are the <a>node expression parameters</a>,
Expand Down Expand Up @@ -2479,7 +2479,7 @@ <h4>IRI Expressions</h4>
The <a>output nodes</a> of an <a>IRI expression</a> are the list consisting of exactly the <a>node expression</a> itself:
<br/>
<br/>
<code>eval(expr, activeGraph, scope) -> [expr]</code>
<code>evalExpr(expr, activeGraph, scope) -> [expr]</code>
</p>
</div>
</section>
Expand All @@ -2498,7 +2498,7 @@ <h4>Literal Expressions</h4>
The <a>output nodes</a> of a <a>literal expression</a> are the list consisting of exactly the <a>node expression</a> itself:
<br/>
<br/>
<code>eval(expr, activeGraph, scope) -> [expr]</code>
<code>evalExpr(expr, activeGraph, scope) -> [expr]</code>
</p>
</div>
</section>
Expand Down Expand Up @@ -2962,12 +2962,12 @@ <h4>Value Nodes of Property Shapes</h4>
</li>
<li>
If <code>e</code> is the <a>value</a> of <code>sh:values</code> at the <a>property shape</a>,
then add the <a>output nodes</a> of <code>eval(e, <a>data graph</a>, scope)</code> where <code>scope</code>
then add the <a>output nodes</a> of <code>evalExpr(e, <a>data graph</a>, scope)</code> where <code>scope</code>
contains the <a>focus node</a> as the value of the variable <code>focusNode</code>.
</li>
<li>
If the set is still empty and <code>d</code> is the <a>value</a> of <code>sh:defaultValue</code> at the <a>property shape</a>,
then add the <a>output nodes</a> of <code>eval(d, <a>data graph</a>, scope)</code> where <code>scope</code>
then add the <a>output nodes</a> of <code>evalExpr(d, <a>data graph</a>, scope)</code> where <code>scope</code>
contains the <a>focus node</a> as the value of the variable <code>focusNode</code>.
</li>
</ol>
Expand Down
77 changes: 75 additions & 2 deletions shacl12-sparql/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1223,15 +1223,15 @@ <h3>Select Expressions</h3>
<span data-syntax-rule="SelectExpression-query-valid">Using the <a href="#sparql-prefixes">prefix handling rules</a>, the value of <code>sh:select</code> is a valid SPARQL 1.2 SELECT query.</span>
<span data-syntax-rule="SelectExpression-query-output-nodes">The SPARQL query derived from the value of <code>sh:select</code> <a data-cite="sparql12-query/#selectproject">projects</a> exactly one variable in the SELECT clause.</span>
</p>
<div class="def" id="LiteralExpression-evaluation">
<div class="def" id="SelectExpression-evaluation">
<div class="def-header">EVALUATION OF SELECT EXPRESSIONS</div>
<p>
The <a>output nodes</a> of a <a>select expression</a> are the list <code>resultNodes</code> consisting of exactly the bindings of the (only)
variable that is projected from the SELECT clause.
If present in the <a>scope</a>, the value of the scope variable <code>focusNode</code> MUST be <a>pre-bound</a> as the value of the SPARQL variable <code>this</code>.
<br/>
<br/>
<code>eval(expr, activeGraph, scope) -> resultNodes</code>
<code>evalExpr(expr, activeGraph, scope) -> resultNodes</code>
</p>
</div>
<p><em>The remainder of this section is informative.</em></p>
Expand Down Expand Up @@ -1315,6 +1315,78 @@ <h3>Select Expressions</h3>
</div>
</aside>
</section>

<section id="EvalExpression">
<h3>Eval Expressions</h3>
<p>
A <a>node expression</a> that has a <a>value</a> for <code>sh:eval</code> is called an <dfn>eval expression</dfn> with the <a>function name</a>
<code>sh:EvalExpression</code>.
</p>
<p class="syntax">
<span data-syntax-rule="EvalExpression-syntax-eval">A node in an RDF graph is a <a>well-formed</a> <a>eval expression</a> if it is a <a>blank node</a>
that is the <a>subject</a> of exactly one <a>triple</a> with <code>sh:eval</code> as <a>predicate</a> and a <a>literal</a> as <a>object</a>
with <a>datatype</a> <code>xsd:string</code>.</span>
<span data-syntax-rule="EvalExpression-syntax-prefixes">A <a>well-formed</a> <a>eval expression</a> can have at most one <a>value</a> for the property
<code>sh:prefixes</code> and this value is a <a>IRI</a> or a <a>blank node</a>.</span><br/><br/>
<span data-syntax-rule="EvalExpression-template">Let <code>$EVAL$</code> be the <a>value</a> of <code>sh:eval</code> and <code>$PREFIXES$</code>
be the SPARQL prefixes block resulting from the <a href="#sparql-prefixes">prefix handling rules</a> using the value of <code>sh:prefixes</code>,
then <code>select</code> is defined as the string where <code>$EVAL$</code> and <code>$PREFIXES$</code> are inserted as into <br/><br/><code>$PREFIXES$ SELECT ($EVAL$ AS ?result) WHERE {}</code><br/><br/></span>
<span data-syntax-rule="EvalExpression-query-valid"><code>select</code> is a valid SPARQL 1.2 SELECT query.</span>
</p>
<div class="def" id="EvalExpression-evaluation">
<div class="def-header">EVALUATION OF EVAL EXPRESSIONS</div>
<p>
The <a>output nodes</a> of an <a>eval expression</a> are the list <code>resultNodes</code> consisting of exactly the bindings of the (only)
variable that is projected from the SELECT clause of the <code>select</code> query as defined <a href="#syntax-rule-EvalExpression-template">above</a>.
If present in the <a>scope</a>, the value of the scope variable <code>focusNode</code> MUST be <a>pre-bound</a> as the value of the SPARQL variable <code>this</code>.
<br/>
<br/>
<code>evalExpr(expr, activeGraph, scope) -> resultNodes</code>
</p>
</div>
<p><em>The remainder of this section is informative.</em></p>
<aside class="example" title="A dynamically computed property using an eval expression">
<p>
Here is an example use of an <a>eval expression</a>, computing the values of a property shape for the property
"uri length" as the length of the IRI of the focus node.
</p>
<div class="shapes-graph">
<div class="turtle">
ex:Resource-uriLength
a sh:PropertyShape ;
sh:name "uri length" ;
sh:path ex:uriLength ;
sh:values <b>[
sh:eval "STRLEN(STR($this))" ;
]</b> ;
sh:datatype xsd:integer .
</div>
</div>
<p>
When applied to a focus node with URI <code>http://example.org/ns#Test</code> the result will be <code>26</code>.
This produces the same results as this variation:
</p>
<div class="shapes-graph">
<div class="turtle">
ex:Resource-uriLength
a sh:PropertyShape ;
sh:name "uri length" ;
sh:path ex:uriLength ;
sh:values <b>[
sh:select """
SELECT (STRLEN(STR($this)) AS ?result)
WHERE {
}
""" ;
]</b> ;
sh:datatype xsd:integer .
</div>
</div>
<p>
Note that the query is executed with the current <a>focus node</a> <a>pre-bound</a> to the variable <code>this</code>.
</p>
</aside>
</section>
</section>

<div style="padding-top: 30px">
Expand Down Expand Up @@ -1651,6 +1723,7 @@ <h2>Revision History</h2>
<h2>Changes between SHACL 1.0 SPARQL and SHACL 1.2 SPARQL Extensions</h2>
<ul>
<li>Added the <a>node expression function</a> <a href="#SelectExpression"><code>sh:SelectExpression</code></a>, see <a href="https://github.com/w3c/data-shapes/issues/288">Issue 288</a></li>
<li>Added the <a>node expression function</a> <a href="#EvalExpression"><code>sh:EvalExpression</code></a>, see <a href="https://github.com/w3c/data-shapes/issues/315">Issue 315</a></li>
</ul>
</section>

Expand Down
2 changes: 1 addition & 1 deletion shacl12-test-suite/tests/sparql/property/manifest.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<>
a mf:Manifest ;
rdfs:label "Tests converted from http://datashapes.org/sh/tests/tests/sparql/property" ;
mf:include <property-eval-001.ttl> ;
mf:include <property-select-001.ttl> ;
mf:include <sparql-001.ttl> ;
.
57 changes: 57 additions & 0 deletions shacl12-test-suite/tests/sparql/property/property-eval-001.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@prefix dash: <http://datashapes.org/dash#> .
@prefix ex: <http://example.org/ns#> .
@prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix sht: <http://www.w3.org/ns/shacl-test#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:Resource-uriLength
a sh:PropertyShape ;
sh:targetNode ex:Invalid ; # The URI of this has 29 chars
sh:targetNode ex:Valid ; # The URI of this has 27 chars
sh:name "URI length" ;
sh:path ex:uriLength ;
sh:values [
sh:eval "STRLEN(STR($this))" ;
sh:prefixes <http://example.org/ns> ;
] ;
sh:datatype xsd:integer ;
sh:hasValue 27 .

<http://example.org/ns>
a owl:Ontology ;
sh:declare [
sh:prefix "ex" ;
sh:namespace "http://example.org/ns#"^^xsd:anyURI ;
] .

<>
rdf:type mf:Manifest ;
mf:entries (
<property-eval-001>
) ;
.
<property-eval-001>
rdf:type sht:Validate ;
rdfs:label "Test of a sh:property with a sh:eval expression 001" ;
mf:action [
sht:dataGraph <> ;
sht:shapesGraph <> ;
] ;
mf:result [
rdf:type sh:ValidationReport ;
sh:conforms "false"^^xsd:boolean ;
sh:result [
rdf:type sh:ValidationResult ;
sh:focusNode ex:Invalid ;
sh:resultPath ex:uriLength ;
sh:resultSeverity sh:Violation ;
sh:sourceConstraintComponent sh:HasValueConstraintComponent ;
sh:sourceShape ex:Resource-uriLength ;
] ;
] ;
mf:status sht:approved ;
.
31 changes: 30 additions & 1 deletion shacl12-vocabularies/shacl.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# - Added support for sh:singleLine (see https://github.com/w3c/data-shapes/issues/177)
# - Deleted any terms related to SHACL-JS (see https://github.com/w3c/data-shapes/issues/264)
# - Added sh:NodeExpression and related infrastructure
# - Added sh:SelectExpression and its parameters
# - Added sh:SelectExpression, sh:EvalExpression and their parameters

@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
Expand Down Expand Up @@ -1356,13 +1356,42 @@ sh:SelectExpression-select
sh:name "select"@en ;
sh:description "The SELECT query that is executed during evaluation of this node expression. The output nodes are the bindings of the first result variable."@en ;
sh:keyParameter true ;
sh:datatype xsd:string ;
rdfs:isDefinedBy sh: .

sh:SelectExpression-prefixes
a sh:Parameter ;
sh:path sh:prefixes ;
sh:name "prefixes"@en ;
sh:description "The prefixes that shall be applied before parsing the associated SPARQL query. The object should define those prefixes using sh:declare."@en ;
sh:nodeKind sh:BlankNodeOrIRI ;
rdfs:isDefinedBy sh: .

sh:EvalExpression
a rdfs:Class ;
rdfs:label "Eval expression"@en ;
rdfs:comment "The class of node expressions based on SPARQL expressions (sh:eval)."@en ;
rdfs:subClassOf sh:NodeExpression ;
rdfs:subClassOf sh:SPARQLExecutable ;
sh:parameter sh:EvalExpression-eval ;
sh:parameter sh:EvalExpression-prefixes ;
rdfs:isDefinedBy sh: .

sh:EvalExpression-eval
a sh:Parameter ;
sh:path sh:eval ;
sh:name "eval"@en ;
sh:description "The SPARQL expression that is executed during evaluation of this node expression."@en ;
sh:keyParameter true ;
sh:datatype xsd:string ;
rdfs:isDefinedBy sh: .

sh:EvalExpression-prefixes
a sh:Parameter ;
sh:path sh:prefixes ;
sh:name "prefixes"@en ;
sh:description "The prefixes that shall be applied before parsing the SPARQL query that gets derived from the sh:eval expression. The object should define those prefixes using sh:declare."@en ;
sh:nodeKind sh:BlankNodeOrIRI ;
rdfs:isDefinedBy sh: .


Expand Down