- From: Holger Knublauch <holger@topquadrant.com>
- Date: Thu, 5 May 2016 12:49:58 +1000
- To: "public-data-shapes-wg@w3.org" <public-data-shapes-wg@w3.org>
- Message-ID: <8bd16b2e-69d6-8cd2-ae2e-0d4c6adc3892@topquadrant.com>
Several WG members supported the idea of allowing constraints to be used
as values in places such as sh:or. I was asked to make some specific
suggestions on what would need to be changed in the spec, so that the
following syntax options would behave identically. (Both scenarios state
that the values of schema:address must be string literals or instances
of schema:Address):
a) Currently supported: sh:or can only be used with sh:NodeConstraints
and operands of sh:or must be shapes
ex:MyShape
a sh:Shape ;
sh:constraint [
sh:or (
[ a sh:Shape ;
sh:property [
sh:predicate schema:address ;
sh:datatype xsd:string ;
] ;
]
[ a sh:Shape ;
sh:property [
sh:predicate schema:address ;
sh:class schema:Address ;
] ;
]
)
]
which lacks on multiple fronts - it is too verbose and also forces
repetition of the predicate.
b) Proposed: generalize sh:or and values of sh:or may be constraints of
the same kind as the surrounding constraint.
ex:MyShape
a sh:Shape ;
sh:property [
sh:predicate schema:address ;
sh:or (
[ sh:datatype xsd:string ]
[ sh:class schema:Address ]
)
]
In this proposal, the members of the sh:or List may be
sh:PropertyConstraints if sh:or is used within a sh:PropertyConstraint.
Required changes (all incremental to current spec):
1) Generalize sh:hasShape from sh:hasShape(?node, ?shape, ?shapesGraph) to
sh:validateNode(?node, ?shapeOrConstraint, ?shapesGraph,
?defaultConstraintType, ?defaultPredicate)
The two arguments at the end are optional, and are used to complement
the provided ?shapeOrConstraint unless it is a sh:Shape. Legal values
for ?defaultConstraintType would be sh:PropertyConstraint,
sh:InversePropertyConstraint and sh:NodeConstraint. ?defaultPredicate is
only supported if ?defaultConstraintType is given and != sh:NodeConstraint.
The algorithm would be
a) if ?shapeOrConstraint rdf:type sh:Shape, then behave as currently
b) otherwise, assume ?defaultConstraintType (unless the node has an
rdf:type)
and assume ?defaultPredicate for sh:predicate.
c) report failure if the node has rdf:type that is neither sh:Shape nor
?defaultConstraintType.
While this function isn't pretty it's mostly used internally anyway and
may therefore be regarded as an implementation detail. The name
sh:validateNode is better than sh:hasShape because it may also return
unbound.
2) Generalize sh:or to also have contexts: sh:PropertyConstraint and
sh:InversePropertyConstraint
3) Add a sh:propertyValidator to sh:OrConstraint similar to what we have
as sh:nodeValidator, but with the sh:validateNode function:
SELECT $this ?failure ...
WHERE {
{
$this $predicate ?value .
}
{
SELECT (SUM(?s) AS ?count)
WHERE {
GRAPH $shapesGraph {
$or rdf:rest*/rdf:first ?shape .
}
BIND (sh:validateNode(?value, ?shape, $shapesGraph, sh:PropertyConstraint, $predicate) AS ?valid) .
BIND (IF(bound(?valid), IF(?valid, 1, 0), 'error') AS ?s) .
}
}
BIND (!bound(?count) AS ?failure) .
FILTER IF(?failure, true, ?count = 0) .
}
and similar for sh:inversePropertyValidator. The same approach would
work for sh:and and sh:not. I guess also for sh:valueShape if that's
desirable.
Regards,
Holger
Received on Thursday, 5 May 2016 02:50:31 UTC