Patrick -
That split should work. It's because SPARQL does not allow variables in
paths.
?subject $listPredicate/rdf:rest*/rdf:first ?object
is bad syntax and seems to line up with the error message
5.3 Validation with SPARQL-based Constraints
"""
substitute the variable PATH where it appears in the predicate position
of a triple pattern
"""
and it says triple pattern which has only a variable or URI in the
predicate slot not a path.
So "?s $PATH ?o" but nothing more complex.
Andy
On 23/08/2021 22:06, Patrick Golden wrote:
My solution was to just break up the list-lookup part of the SPARQL
query into two elements:
$this $listPredicate ?listHead .
?listHead rdf:rest*/rdf:first ?missing .
Easy enough!
On 8/23/21 12:11 PM, Patrick Golden wrote:
Hello,
I'm trying to write a sh:ConstraintComponent that validates whether
two predicates have the same objects. One predicate has multiple
objects and the other has an object with an ordered RDF list of those
same nodes. In Turtle, a valid graph looks like:
@prefix ex: <http://example.org/> .
ex:Thing
ex:p1 ex:a, ex:b, ex:c ;
ex:p2 ( ex:a ex:b ex:c ) .
I can create a SPARQL constraint that expresses this:
:ListPredEqualityConstraint
a sh:SPARQLConstraint ;
sh:prefixes [
sh:declare
[
sh:prefix "ex" ;
sh:namespace "http://example.org/"^^xsd:anyURI
] ,
]
sh:select """
SELECT $this ?missing
WHERE {
{
$this ex:p2/rdf:rest*/rdf:first ?missing
MINUS
{ $this ex:p1 ?missing }
}
UNION
{
$this ex:p1 ?missing
MINUS
{ $this ex:p2/rdf:rest*/rdf:first ?missing }
}
}
""" .
I have multiple pairs of predicates to which this constraint can
apply, so I wanted to make a generic constraint component which can
take each of the two predicates as parameters. This is how I tried to
model that:
:ListMatchConstraintComponent
a sh:ConstraintComponent ;
sh:parameter [
sh:path ex:unorderedPredicate ;
] ;
sh:parameter [
sh:path ex:listPredicate ;
] ;
sh:nodeValidator [
a sh:SPARQLSelectValidator ;
sh:select """
SELECT $this ?missing
WHERE {
{
$this $listPredicate/rdf:rest*/rdf:first ?missing
MINUS
{ $this $unorderedPredicate ?missing }
}
UNION
{
$this $unorderedPredicate ?missing
MINUS
{ $this $listPredicate/rdf:rest*/rdf:first ?missing }
}
}
"""
] .
For each predicate pair constraint, I create a shape like this:
:P1P2ListMatchConstraint
a sh:NodeShape ;
:unorderedPredicate ex:p1 ;
:listPredicate ex:p2 .
However, when I run `shacl validate` for the graph against this shape,
I see the result:
$ shacl v -s shape.ttl -d graph.ttl
org.apache.jena.shacl.parser.ShaclParseException: Bad query:
Encountered " "/" "/ "" at line 8, column 27.
Was expecting one of:
<IRIref> ...
<PNAME_NS> ...
<PNAME_LN> ...
<BLANK_NODE_LABEL> ...
<VAR1> ...
<VAR2> ...
"true" ...
"false" ...
<INTEGER> ...
<DECIMAL> ...
<DOUBLE> ...
<INTEGER_POSITIVE> ...
<DECIMAL_POSITIVE> ...
<DOUBLE_POSITIVE> ...
<INTEGER_NEGATIVE> ...
<DECIMAL_NEGATIVE> ...
<DOUBLE_NEGATIVE> ...
<STRING_LITERAL1> ...
<STRING_LITERAL2> ...
<STRING_LITERAL_LONG1> ...
<STRING_LITERAL_LONG2> ...
"(" ...
<NIL> ...
"[" ...
<ANON> ...
"<<" ...
I am guessing that the values for the parameters in the constraint
($unorderedPredicate, $listPredicate) are not allowed to be in SPARQL
property paths (e.g. $this $listPredicate/rdf:rest*/rdf:first
?missing). Is that the case? Are there alternative ways to achieve
what I'm trying to do?
Thank you,
Patrick