diff --git a/shacl/index.html b/shacl/index.html index 32f505b5..cf12fbc1 100644 --- a/shacl/index.html +++ b/shacl/index.html @@ -866,6 +866,9 @@
+ TODO: Possibly use sh:inversePredicate
instead of sh:predicate
.
+
sh:path1
and sh:path2
describe a sequence path consisting of
two other paths. The values of these properties must be property IRIs or blank nodes
of the same recursive path structure. The path produces the concatenation of the two sub-paths.
+ The values of sh:path1
must either be IRIs or blank nodes with a value for sh:inverse
,
+ which means that only the second path segment may be another sequence path.
Blank nodes with sh:path1
and sh:path2
may have the optional type sh:SequencePath
.
@@ -1703,125 +1708,178 @@
- The SPARQL queries attached to a constraint via sh:sparql
must be of the query form CONSTRUCT
or SELECT
.
- CONSTRUCT
is the most flexible option, so the following section starts with describing how these are executed.
- The subsequent section describes how SELECT
queries can be transformed into equivalent CONSTRUCT
forms.
-
- There is ongoing discussion about whether the CONSTRUCT option below shall be supported, and whether an approach based on variable names only would be better.
+ The SPARQL queries attached to a constraint via sh:sparql
must be of the query form SELECT
.
- Constraints backed by a SPARQL CONSTRUCT
query are assumed to construct constraint violations.
- CONSTRUCT
queries consist of a graph template and a WHERE
clause.
- The output of a CONSTRUCT
query is a new RDF graph, and the triples from those RDF graphs need to be added to the result graph of the constraint validation operation.
-
- The following example illustrates how a CONSTRUCT
query is used to produce instances of sh:Error
for every instance of ex:ExampleClass
that has no rdfs:label
.
- Note that _:error
is a SPARQL syntax representing a new blank node for each row of the result set (WHERE
clause).
-
-sh:ExampleGlobalConstructConstraint - a sh:GlobalConstraint ; - sh:sparql """ - CONSTRUCT { - _:error a sh:Error . - _:error sh:root ?instance . - _:error sh:path rdfs:label . - _:error sh:message "Instances of ex:ExampleClass must have an rdfs:label" . - } - WHERE { - ?instance a ex:ExampleClass . - FILTER NOT EXISTS { ?instance rdfs:label ?anyLabel } . - } - """ . -}+
- The instances of sh:ConstraintViolation
produced by such queries are not modified further,
- except that the engine SHOULD add sh:source
triples that have each constraint violation
- instance as subject and the surrounding sh:Constraint
as its object.
+ The SPARQL variable ?this
has a special meaning in local constraints.
+ When SPARQL constraints are executed then the variable ?this
needs to be pre-bound to the focus node.
+ (Need a pointer to what "pre-binding" means in this context)
- SPARQL queries of the SELECT
form need to produce one constraint violation blank node for each row of the produced result set.
- The following example illustrates a constraint that flags warnings for all subjects that have a rdfs:label
with the language tag "de"
.
-
-ex:ExampleGlobalSelectConstraint - a sh:GlobalConstraint ; - sh:message "Deutsch is verboten" ; - sh:path rdfs:label ; - sh:severity sh:Warning ; - sh:sparql """ - SELECT (?subject AS ?root) (?object AS ?value) - WHERE { - ?subject rdfs:label ?object . - FILTER (lang(?object) = "de") . - } - """ .+
- For execution, the constraint above can be turned into the following CONSTRUCT
query.
-
-CONSTRUCT { - _:violation a sh:Warning . - _:violation sh:message "Deutsch is verboten" . - _:violation sh:path rdfs:label . - _:violation sh:root ?subject . - _:violation sh:value ?object . -} -WHERE { - ?subject rdfs:label ?object . - FILTER (lang(?object) = "de") . -}-
- The following naming conventions are used to map the result variables of a SELECT
into corresponding RDF properties:
+ Each row of the result set produced by a SELECT query must be converted into one constraint violation blank node.
+ The properties of those blank nodes are derived by the following rules, through a combination of result variables and by looking at properties attached to the constraint itself.
+ In the following table, the host resource is assumed to be the constraint or template that has the executed sh:sparql
query as one of its properties.
+ The production rules are meant to be executed from top to bottom, so that the first bound value will be used.
Result Variable | -Constraint Violation Property | +Property | +Production Rules |
---|---|---|---|
?severity |
rdf:type |
+
+
|
|
?message |
- sh:message |
+ sh:root |
+
+
|
?predicate |
- sh:predicate |
+ sh:path |
+
+
|
?root |
- sh:root |
+ sh:value |
+
+
|
?value |
- sh:value |
+ sh:message |
+
+
|
+
sh:source |
+
+
|
- If the surrounding subject node defines a sh:message
then the constructed blank nodes needs to have corresponding triples, unless the SELECT has corresponding result variables.
- Similarly, the values of sh:root
, sh:path
and sh:value
must be inserted (they cannot be blank nodes).
+ The following example illustrates a constraint that flags warnings for all subjects that have a rdfs:label
with the language tag "de"
.
+ex:ExampleGlobalSelectConstraint + a sh:GlobalConstraint ; + sh:message "Deutsch is verboten" ; + sh:path rdfs:label ; + sh:severity sh:Warning ; + sh:sparql """ + SELECT (?subject AS ?root) ?value + WHERE { + ?subject rdfs:label ?value . + FILTER (lang(?value) = "de") . + } + """ . + +ex:Resource1 + rdfs:label "Eins"@de ; + rdfs:label "Zwei"@de ; + rdfs:label "Trois"@fr .
- In local constraints the variable ?this
must be projected into ?root
unless the SELECT
clause already projects to ?root
.
- This means that the frequently needed pattern SELECT (?this AS ?root)
is redundant.
+ Output created by the example above would be:
+[ + a sh:Warning ; + sh:root ex:Resource1 ; + sh:path rdfs:label ; + sh:value "Eins"@de ; + sh:message "Deutsch is verboten" ; + sh:source ex:ExampleGlobalSelectConstraint ; +] . +[ + a sh:Warning ; + sh:root ex:Resource1 ; + sh:path rdfs:label ; + sh:value "Zwei"@de ; + sh:message "Deutsch is verboten" ; + sh:source ex:ExampleGlobalSelectConstraint ; +] .
- The SPARQL variable ?this
has a special meaning in local constraints.
- When SPARQL constraints are executed then the variable ?this
needs to be pre-bound to the focus node.
- (Need a pointer to what "pre-binding" means in this context)
+ Here is a more complex example, producing a path expression ex:property1/^ex:property2
.
+
+ex:LocalShapeWithPathViolationExample + a sh:Shape ; + sh:constraint [ + sh:sparql """ + SELECT ?value (ex:property1 AS ?predicate1) (ex:property2 AS ?inversePredicate2) ?message + WHERE { + ?this ex:property1 ?first . + ?value ex:property2 ?first . + FILTER isBlank(?value) . + BIND (CONCAT("The ", "message.") AS ?message) . + } + """ ; + ] . + +ex:ExampleRootResource + sh:nodeShape ex:LocalShapeWithPathViolationExample ; + ex:property1 ex:ExampleIntermediateResource . + +ex:ExampleValueResource + ex:property2 ex:ExampleIntermediateResource . ++
+ Which produces the following error:
++[ + a sh:Error ; + sh:root ex:ExampleRootResource ; + sh:path [ + sh:path1 ex:property1 ; + sh:path2 [ + sh:inverse ex:property2 + ] + ] ; + sh:value ex:ExampleValueResource ; + sh:message "The message." ; + sh:source [ the blank node of the sh:constraint above ] ; +] .