This document defines the SHACL Shapes Constraint Language, a language for validating RDF graphs against a set of conditions. These conditions are provided as shapes and other constructs expressed in the form of an RDF graph. RDF graphs that are used in this manner are called "shapes graphs" in SHACL and the RDF graphs that are validated against a shapes graph are called "data graphs". As SHACL shape graphs are used to validate that data graphs satisfy a set of conditions they can also be viewed as a description of the data graphs that do satisfy these conditions. Such descriptions may be used for a variety of purposes beside validation, including user interface building, code generation and data integration.
The detailed list of changes and their diffs can be found in the Git repository.
$shapesGraph
is optional (ISSUE-47)sh:QCC
(ISSUE-92)sh:partition
. (ISSUE-92)sh:XorConstraint
as resolved, renamed sh:Error
to sh:Violation
sh:class
, editorial changes, renamed sh:ClosedShape to sh:Closed, added sh:sourceTemplateThe introduction includes a Terminology section.
The sections 2 - 4 cover the SHACL Core language and may be read independently from the later sections.
The sections 5 onwards are about the additional features that SHACL Full has in addition to the Core language. These advanced features include SPARQL-based constraints, constraint components, targets and functions.
The examples in this document use Turtle [[!turtle]]. The reader should be familiar with basic RDF concepts [[!rdf11-concepts]] such as triples and, for the advanced concepts of SHACL, with SPARQL [[!sparql11-overview]].
This document specifies SHACL (Shapes Constraint Language), a language for describing and validating RDF graphs. This section introduces SHACL with an overview of the key terminology and an example to illustrate basic concepts.
Throughout this document, the following terminology is used.
p
for a node n
in an RDF graph are the
objects of the triples in the graph that have n
as subject and p
as predicate.
A property path is a possible route in a graph between two graph nodes.
SHACL supports a subset of the property path syntax from SPARQL 1.1,
including inverse paths and sequences.
The values of a property path path
for a given node s
are the distinct bindings produced by a SPARQL processor for the variable o
from a
TriplesBlock
of the form s path ?o
.
rdf:nil
, or has exactly one value for the property rdf:first
and exactly one value for the property rdf:rest
that is also an RDF list.
rdf:nil
cannot have any value for either rdf:first
or rdf:rest
.
The values of the path rdf:rest*/rdf:first
starting from a given list node
are called the members of the list.
Sub
in an RDF graph is a SHACL subclass of another node Super
in the graph if there is a sequence of triples in the graph each with predicate rdfs:subClassOf
such that the subject of the first triple is Sub
,
the object of the last triple is Super
, and the object of each triple except the last is the subject of the next.
If Sub
is a SHACL subclass of Super
in an RDF graph then Super
is a SHACL superclass of Sub
in the graph.
sh:shape
as predicate have sh:Shape
as expected type and
there does not need to be a triple with the object node as the subject, rdf:type
as predicate and sh:Shape
as object in the shapes graph.
sh:MinCountConstraintComponent
defines the parameter sh:minCount
to represent the restriction
that the focus node has at least a minimum number of values for a particular property.
Validating a node against a constraint involves validating the node against each of the components for which the constraint has parameter values for.
Within this document, the following namespace prefix bindings are used:
Prefix | Namespace |
---|---|
rdf: |
http://www.w3.org/1999/02/22-rdf-syntax-ns# |
rdfs: |
http://www.w3.org/2000/01/rdf-schema# |
sh: |
http://www.w3.org/ns/shacl# |
xsd: |
http://www.w3.org/2001/XMLSchema# |
ex: |
http://example.com/ns# |
Note that the URI of the graph defining the SHACL vocabulary itself is equivalent to
the namespace above, i.e. it includes the #
.
References to the SHACL vocabulary, e.g. via owl:imports
SHOULD include the #
.
Throughout the document, color-coded boxes containing RDF graphs in Turtle will appear. These fragments of Turtle documents use the prefix bindings given above.
# This box represents an input shapes graph
# Triples that can be omitted are marked as grey e.g.
<s> <p> <o> .
# This box represents an input data graph. # When highlighting is used in the examples: # Elements highlighted in blue are focus nodes ex:Bob a ex:Person . # Elements highlighted in red are focus nodes that fail validation ex:Alice a ex:Person .
In examples, the results of validation are summarized in a table associating node/shape pairs with a pass or fail and an informal explanation for failure:
shape | node | valid | reason |
---|---|---|---|
<Shape1> | <node1> | yes | |
<Shape1> | <node2> | no | no ex:state supplied. |
RDF output from validation is expressed in Turtle:
[ a sh:ValidationResult ; sh:sourceConstraintComponent sh:RegexConstraintComponent ; sh:sourceShape ex:PersonShape ; sh:focusNode ex:Alice ; sh:path ex:ssn ; sh:value "987-65-432A" ; sh:severity sh:Violation ; ] .
SHACL Definitions appear in blue boxes:
# This box contains SPARQL or textual definitions.
TODO: needs more work.
This specification describes conformance criteria for:
TODO: link to test cases.
The following example data graph contains nine total nodes, out of which three nodes are SHACL instances of the class ex:Person
.
ex:Alice a ex:Person ; ex:child ex:Calvin ; ex:ssn "987-65-432A" . ex:Bob a ex:Person ; ex:child ex:Calvin ; ex:ssn "123-45-6789" ; ex:ssn "124-35-6789" . ex:Calvin a ex:Person ; ex:school ex:TrinityAnglicanSchool . ex:Danielle a ex:Person ; ex:ssn "123-45-6789" .
SHACL can be used to define the following example constraints:
ex:Person
may have at most one value for the property ex:ssn
,
and this value must be a literal with the datatype xsd:string
that matches
a specified regular expression.
ex:Person
may have unlimited values for the property ex:child
,
and these values must be IRIs and they must be SHACL instances of ex:Person
.
ex:child
in the inverse direction.
A SHACL instance of ex:Person
may have at most 2 parents, i.e. may be the object of at most two triples
where the predicate is ex:child
.
ex:Person
may not have values for any other property apart from
ex:ssn
, ex:child
and rdf:type
.
The constraints above can be represented using the following shapes graph:
ex:PersonShape a sh:Shape ; sh:targetClass ex:Person ; # Applies to all persons sh:property [ sh:predicate ex:ssn ; # Validates the values of the ex:ssn property sh:maxCount 1 ; sh:datatype xsd:string ; sh:pattern "^\\d{3}-\\d{2}-\\d{4}$" ; ] ; sh:property [ sh:predicate ex:child ; sh:class ex:Person ; sh:nodeKind sh:IRI ; ] ; sh:property [ rdfs:comment "A person's parents are represented via ex:child used in the inverse direction." ; sh:path [ sh:inversePath ex:child ] ; sh:name "parent" ; sh:maxCount 2 ; ] ; sh:closed true ; sh:ignoredProperties ( rdf:type ) .
We can use the shape definition above to illustrate some of the key terminology used by SHACL.
The shape defines three property constraints with the property sh:property
,
one of which uses a path expression.
The shape itself is also a constraint on the focus nodes using the parameters sh:closed
and sh:ignoredProperties
.
Validation is performed on focus nodes; the results are summarized here:
shape | focus node | valid | reason |
---|---|---|---|
ex:PersonShape | <Alice> | no | ex:ssn "987-65-432A" does not match pattern. |
ex:PersonShape | <Bob> | no | cardinality of ex:state exceeds 1. |
ex:PersonShape | <Calvin> | no | unexpected ex:school in closed shape. |
ex:PersonShape | <Danielle> | yes |
Some of the property constraints specify parameters from multiple constraint components in order to
restrict multiple aspects of the property values.
For example, in the property constraint for ex:ssn
, parameters from three constraint components are used.
The parameters of these constraint components are sh:datatype
, sh:pattern
and sh:maxCount
.
For each focus node the property values of ex:ssn
will be validated against all three components.
The constraint on the inverse property values of sh:child
uses only one constraint component identified by the sh:maxCount
parameter.
Note that this constraint uses the non-validating property sh:name
to suggest a human-readable name for the property when used in the inverse direction.
SHACL validation based on the provided data graph and shapes graph would produce the following validation results. See the section Validation Report for details on the format.
[ a sh:ValidationResult ; sh:sourceConstraintComponent sh:RegexConstraintComponent ; sh:sourceShape ex:PersonShape ; sh:focusNode ex:Alice ; sh:path ex:ssn ; sh:value "987-65-432A" ; sh:severity sh:Violation ; ] . [ a sh:ValidationResult ; sh:sourceConstraintComponent sh:MaxCountConstraintComponent ; sh:sourceShape ex:PersonShape ; sh:focusNode ex:Bob ; sh:path ex:ssn ; sh:severity sh:Violation ; ] . [ a sh:ValidationResult ; sh:sourceConstraintComponent sh:ClosedConstraintComponent ; sh:sourceShape ex:PersonShape ; sh:focusNode ex:Calvin ; sh:path ex:school ; sh:value ex:TrinityAnglicanSchool ; sh:severity sh:Violation ; ] .
The first validation result is produced because ex:Alice
has a value for ex:ssn
that does not match the regular expression specified by the property sh:regex
.
The second validation result is produced because ex:Bob
has more than the permitted number of values
for the property ex:ssn
as specified by the sh:maxCount
of 1.
The third validation result is produced because the shape ex:PersonShape
has the the property sh:closed
set to true
but ex:Calvin
uses the property ex:school
which is neither one of the predicates from any of the
property constraints of the shape, nor one of the properties listed using sh:ignoredProperties
.
SHACL uses the RDF and RDFS vocabularies, but full RDFS inferencing is not required.
However, SHACL processors MUST identify SHACL instances of a class both in the data graph and the shapes graph without modifying either graph during the validation process.
Furthermore, SHACL processors may operate on RDF graphs that include entailments - either pre-computed before being submitted to a SHACL processor or performed on the fly as part of SHACL processing.
To support processing of entailments, SHACL includes the property sh:entailment
to indicate what inferencing is required by a given shapes graph.
SHACL implementations may, but are not required to, support entailment regimes.
This specification uses parts of SPARQL 1.1 in the normative definition of the semantics of the SHACL Core constraints and targets. However, SPARQL is not required for the implementation of the SHACL Core language.
SPARQL variables using the $
marker represent external bindings that must be pre-bound or, in the case of $PATH
, substituted in the SPARQL query before execution.
In some places, the specification assumes that the provided SPARQL engines are preserving the identity of blank nodes, so that repeated invocations of queries consistently identify and communicate the same blank nodes.
The definition of some constraints requires or is simplified through access to the shapes graph during query execution.
SHACL Full processors MAY pre-bind the variable shapesGraph
to provide access to the shapes graph.
Access to the shapes graph is not a requirement for supporting the SHACL Core language.
The variable shapesGraph
can also be used in SPARQL-based constraints and SPARQL-based constraint components.
However, such constraints may not be interoperable across different SHACL Full processors or not applicable to remote RDF datasets.
SHACL additionally introduces mechanisms to define constraints, targets, derived values and new functions in SPARQL. Implementations that cover only the SHACL Core features are not required to implement these mechanisms.
A shape can be a node in a shapes graph that is
a SHACL instance of sh:Shape
;
or it can be a node so that the expected type of the node is sh:Shape
,
or a node that has a value for a target property such as sh:targetClass
in the shapes graph.
A shape provides a set of zero or more targets, filters, constraints and parameters of constraint components that specify how a set of nodes from the data graph are validated against the shape. Shapes can also provide non-validating information, such as labels and comments.
A node in the data graph that is validated against a shape is called a focus node.
The set of focus nodes for a shape may be identified as follows:
sh:shape
) or
logical constraint components (i.e. sh:or
),In this document, target properties are indicated by the target-can-be-skipped class indicating that they are not necessary for a validation function which accepts node and shape parameters.
A target provides one way to specify potential focus nodes for a shape.
SHACL Core includes four kinds of targets: node targets, class-based targets, subjects-of targets, and objects-of targets. The SHACL Full language additionally defines an advanced general target mechanism based on SPARQL.
Not all target nodes become focus nodes. When a shape includes filters, filters can remove nodes specified by targets.
When multiple targets are provided in a shape, the target of a shape is the union of all nodes produced by these individual targets. Nodes specified by targets are not required to exist in the data graph.
Targets MUST be ignored when a shape is used in a validation process as a value of parameters of
shape-based constraint components (i.e. sh:shape
),
logical constraint components (i.e. sh:or
), or
filter shapes (sh:filterShape
).
A node target is defined with the sh:targetNode
predicate.
Each value of sh:targetNode
can be an IRI or a literal.
Each value of a node target defines a node to validate in the data graph.
With the example data below, only ex:Alice
is the target of the provided shape:
ex:PersonShape a sh:Shape ; sh:targetNode ex:Alice .
ex:Alice a ex:Person .
ex:Bob a ex:Person .
The following SPARQL query specifies the semantics of node targets.
The variable targetNode
is assumed to be pre-bound to the given value of sh:targetNode
.
All bindings of the variable this
from the solution become target nodes.
SELECT DISTINCT ?this # ?this is the focus node WHERE { BIND ($targetNode AS ?this) # $targetnote is pre-bound to ex:Alice }
A class target is defined with the sh:targetClass
predicate.
Each value of sh:targetClass
must be an IRI.
For every value c
of a class target, all SHACL instances of c
in the data graph are validated
against the subject of the sh:targetClass
triple.
ex:PersonShape a sh:Shape ; sh:targetClass ex:Person .
ex:Alice a ex:Person . ex:Bob a ex:Person . ex:NewYork a ex:Place .
In this example, only ex:Alice
and ex:Bob
are focus nodes.
Note that, according to the SHACL instance definition, all the rdfs:subClassOf
declarations needed to walk the class hierarchy must exist in the data graph.
However, the ex:Person a rdfs:Class
triple is not required to exist in either graphs.
In the following example, the selected target node is only ex:Who
.
ex:Doctor rdfs:subClassOf ex:Person .
ex:Who a ex:Doctor .
ex:House a ex:Nephrologist .
The following SPARQL query specifies the semantics of class targets.
The variable targetClass
is assumed to be pre-bound to the given value of sh:targetClass
.
All bindings of the variable this
from the solution become target nodes.
SELECT DISTINCT ?this # ?this is the focus node WHERE { ?this rdf:type/rdfs:subClassOf* $targetClass . # $targetClass is pre-bound to ex:Person }
When, in the shapes graph, a shape is a SHACL instance of both sh:Shape
and rdfs:Class
then the shape is a class target of itself.
ex:Person a rdfs:Class, sh:Shape .
ex:Alice a ex:Person .
ex:NewYork a ex:Place .
In this example, only ex:Alice
is a focus node, because it is a SHACL instance of
ex:Person
which is both a class and a shape in the shapes graph.
A subjects-of target is defined with the predicate sh:targetSubjectsOf
,
the values of which must be IRIs.
For every value p
of such a target, the validated nodes are defined as
the set of subjects in the data graph that appear in a triple with p
as a predicate.
ex:TargetSubjectsOfExampleShape a sh:Shape ; sh:targetSubjectsOf ex:knows .
ex:Alice ex:knows ex:Bob .
ex:Bob ex:livesIn ex:NewYork .
In the example above, only ex:Alice
is validated against the given shape,
because it is the subject of a triple that has ex:knows
as its predicate.
The following SPARQL query specifies the semantics of subjects-of targets.
The variable targetSubjectsOf
is assumed to be pre-bound to the given value of sh:targetSubjectsOf
.
All bindings of the variable this
from the solution become target nodes.
SELECT DISTINCT ?this # ?this is the focus node WHERE { ?this $targetSubjectsOf ?any . # $targetSubjectsOf is pre-boundto ex:knows }
An objects-of target is defined with the predicate sh:targetObjectsOf
,
the values of which must be IRIs.
For every value p
of such a target, the validated nodes are defined as
the set of objects in the data graph that appear in a triple with p
as a predicate.
ex:TargetObjectsOfExampleShape a sh:Shape ; sh:targetObjectsOf ex:knows .
ex:Alice ex:knows ex:Bob .
ex:Bob ex:livesIn ex:NewYork .
In the example above, only ex:Bob
is validated against the given shape,
because it is the object of a triple that has ex:knows
as its predicate.
The following SPARQL query specifies the semantics of objects-of targets.
The variable targetObjectsOf
is assumed to be pre-bound to the given value of sh:targetObjectsOf
.
All bindings of the variable this
from the solution become target nodes.
SELECT DISTINCT ?this # ?this is the focus node WHERE { ?any $targetObjectsOf ?this . # $targetObjectsOf is pre-bound to ex:knows }
A filter is a shape in the shapes graph
that further refines which nodes in the data graph are validated against a constraint or all the constraints of a shape.
A filter is specified as an object in a triple with sh:filterShape
as the predicate.
The subjects of these triples can be constraints or shapes.
Only those nodes that successfully validate against all the filters of a constraint or a shape become focus nodes for the constraint or the constraints of the shape.
Note that during the validation against filter shapes, the targets of these filters are ignored.
The following example states that the sh:minCount
constraint on ex:email
is filtered to include only SHACL instances of ex:Person
that are ex:member
s of ex:W3c
.
ex:ExampleFilteredShape a sh:Shape ; sh:targetClass ex:Person ; sh:filterShape [ a sh:Shape ; # Optional triple sh:property [ sh:predicate ex:member ; sh:hasValue ex:W3c ; ] ] ; sh:property [ sh:predicate ex:email ; sh:minCount 1 ; ] .
ex:Alice ex:member ex:W3c ; ex:email <mailto:alice@example.org> . ex:John ex:member ex:W3c . ex:Bob ex:member ex:Acme .
shape | focus node | valid | reason |
---|---|---|---|
ex:ExampleFilteredShape | <Alice> | yes | |
ex:ExampleFilteredShape | <John> | no | cardinality of ex:email less than 1. |
ex:ExampleFilteredShape | <Bob> | yes |
[ a sh:ValidationResult ; sh:severity sh:Violation ; sh:focusNode ex:John ; sh:path ex:email ; sh:message "sh:minCount for ex:email is '1'." ; sh:sourceConstraintComponent sh:MinCountConstraintComponent ; sh:sourceShape ex:ExampleFilteredShape ; ] .
The following example shows a sh:filterShape
that is defined for a specific property constraint, instead of the whole shape.
In this scenario, the sh:minCount
constraint is only applied to every person that is also a member of ex:W3c
.
ex:FilteredExampleShape
a sh:Shape ;
sh:targetClass ex:Person ;
sh:property [
sh:predicate ex:email ;
sh:minCount 1 ;
sh:filterShape [
sh:property [
sh:predicate ex:member ;
sh:hasValue ex:W3c ;
]
] ;
] .
The SHACL Core language defines two types of constraints:
a) constraints about a particular property or path and its values for the focus node (property constraints) and
b) constraints about the focus node itself (focus node constraints).
In addition to those, SHACL Full can be used to define
SPARQL-based constraints or
SPARQL-based constraint components.
SHACL constraints are defined within shapes as specified by each constraint type.
sh:Constraint
is the SHACL superclass of all SHACL constraint types.
Constraints may contain
non-validating properties (such as sh:description
) and
parameters of constraint components (e.g. sh:minCount
).
Constraint components declare one or more parameter properties and validation instructions
(such as those implemented as SPARQL queries) that can be used to perform the validation for the given focus node and parameter values.
The list of predefined constraint components in SHACL Core is described in section 4.
Property constraints specify conditions that must be met with respect to nodes that can be reached from the
focus node either by directly following a given property (specified using sh:predicate
) or a given property path (specified using sh:path
).
Property constraints are defined in a shape with the property sh:property
.
Each value of sh:property
must be an IRI or a blank node
that is the subject of precisely one triple with
either predicate sh:predicate
or sh:path
.
The values of sh:predicate
must be IRIs.
The values of sh:path
must be well-formed property paths following the SHACL property path syntax rules.
The following example illustrates the two syntax variations of property constraints.
ex:ExampleShapeWithPropertyConstraints a sh:Shape ; sh:property [ sh:predicate ex:email ; sh:name "e-mail" ; sh:description "We need at least one email value" ; sh:minCount 1 ; ] ; sh:property [ sh:path (ex:knows ex:email) ; sh:name "Friend's e-mail" ; sh:description "We need at least one email for everyone you know" ; sh:minCount 1 ; ] .
sh:PropertyConstraint
is the class of property constraints.
The objects of triples with sh:property
as predicate have sh:PropertyConstraint
as expected type.
Focus node constraints specify conditions that must be met by the focus node itself.
Since focus node constraints operate directly on the input focus nodes they impose some limitations in comparison to property constraints.
In particular, constraint parameters that operate on value sets, such as sh:hasValue
and sh:equals
, are not applicable to focus node constraints.
The class sh:Shape
is defined as rdfs:subClassOf sh:Constraint
.
Every shape is also a focus node constraint.
ex:ExampleShapeWithFocusNodeConstraint
a sh:Shape ;
sh:targetClass ex:Person ;
sh:stem "https://www.w3.org/People/" .
Some constraint components declare only a single parameter.
For example sh:ClassConstraintComponent
has the single parameter sh:class
.
These parameters may be used multiple times in the same constraint node.
The interpretation of such declarations is conjunction, i.e. all constraints apply.
In the following example this technique is used to restrict the values of ex:customer
to be SHACL instances of both
ex:Customer
and ex:Person
.
ex:InvoiceShape a sh:Shape ; sh:property [ sh:predicate ex:customer ; sh:class ex:Customer ; sh:class ex:Person ; ] .
Some constraint components such as sh:PatternConstaintComponent
declare more than one parameter.
Constraints are not allowed to have more than one value for any of the parameters of such components.
SHACL includes an RDF vocabulary to represent property paths that is equivalent to a subset of SPARQL 1.1 property paths.
In particular, SHACL supports the following SPARQL 1.1 property path constructs:
PredicatePath
, InversePath
, SequencePath
, AlternativePath
,
ZeroOrMorePath
, OneOrMorePath
and ZeroOrOnePath
.
A valid SHACL property path p
is an IRI or a blank node that can be
correctly traversed recursively using the following rules.
p sh:inversePath elt
then the path becomes an InversePath
element of elt
and elt
must be a valid SHACL property path.
Corresponding rules apply for
sh:zeroOrMorePath
(ZeroOrMorePath
),
sh:zeroOrOnePath
(ZeroOrOnePath
) and
sh:oneOrMorePath
(OneOrMorePath
).
p rdf:first elt
,
the path must be an RDF list with a at least two members.
Each member must be valid SHACL property path that is converted into a sequence of either SequencePath
or AlternativePath
elements.
p sh:alternativePath elt
,
the value of path must be an RDF list with a at least two members.
All members must be valid SHACL property paths that become a series of AlternativePath
elements.
p
is an IRI then it is turned into a PredicatePath
with value p
.
A SHACL property path is invalid if:
p
is a blank node that is not handled by any of the above rules.p
with a predicate different from:
sh:inversePath
, sh:alternativePath
, sh:zeroOrMorePath
,
sh:zeroOrOnePath
, sh:oneOrMorePath
or rdf:first
.p
as a subject.The following example illustrates some valid SHACL property paths, together with their SPARQL 1.1 equivalents.
# ex:parent [] sh:path ex:parent . # ^ex:parent [] sh:path [ sh:inversePath ex:parent ] . # ex:parent/ex:firstName [] sh:path ( ex:parent ex:firstName ) . # rdf:type/rdfs:subClassOf* [] sh:path ( rdf:type [ sh:zeroOrMorePath rdfs:subClassOf ] ) . # ex:father|ex:mother [] sh:path [ sh:alternativePath ( ex:father ex:mother ) ] .
sh:predicate
is a convention for declaring a simple predicate path of length one.
In almost all cases, sh:path
can be used in place of sh:predicate
without changing the semantics of the property constraint.
There are exceptions in cases when the value is a valid SHACL property path.
ex:ShapeWithIdenticalPath a sh:Shape ; sh:property [ sh:predicate ex:mother . ] sh:property [ sh:path ex:mother . ] . ex:ShapeWithDifferentPath a sh:Shape ; sh:property [ sh:predicate ex:parent . ] sh:property [ sh:path ex:parent . ] . ex:parent sh:alternativePath ( ex:father ex:mother ) .
In the above example, both property constraints of ex:ShapeWithIdenticalPath
declare an identical path to ex:mother
.
The property constraints in ex:ShapeWithDifferentPath
denote different paths.
The property constraint with sh:predicate
denotes ex:parent
while the property constraint with sh:path
denotes the property path (ex:father|ex:mother)
.
Constraints may specify a value for the property sh:severity
in the shapes graph.
The values of this property must be IRIs.
SHACL includes the three pre-defined IRIs to represent severities listed in the table below.
These are defined in the SHACL vocabulary as SHACL instances of sh:Severity
.
Severity | Description |
---|---|
sh:Info |
A non-critical constraint violation indicating an informative message. |
sh:Warning |
A non-critical constraint violation indicating a warning. |
sh:Violation |
A constraint violation that should be fixed. |
The specific values of sh:severity
have no impact on the validation,
but MAY be used by user interface tools to categorize validation results.
The values of sh:severity
are used by SHACL processors to populate the sh:severity
field of
validation results, see section on severity in validation results.
For every constraint, sh:Violation
is the default if sh:severity
is unspecified.
The following example illustrates this.
ex:MyShape
a sh:Shape ;
sh:targetNode ex:MyInstance ;
sh:property [
# Violations of sh:minCount and sh:datatype are produced as warnings
sh:predicate ex:myProperty ;
sh:minCount 1 ;
sh:datatype xsd:string ;
sh:severity sh:Warning ;
] ;
sh:property [
# The default severity here is sh:Violation
sh:predicate ex:myProperty ;
sh:maxLength 10 ;
sh:message "Too many characters"@en ;
sh:message "Zu viele Zeichen"@de ;
] .
ex:MyInstance ex:myProperty "http://toomanycharacters"^^xsd:anyURI .
shape | focus node | valid | reason |
---|---|---|---|
ex:MyShape | ex:MyInstance | no | length of ex:myProperty exceeds maxLength 10. |
[ a sh:ValidationResult ; sh:focusNode ex:MyInstance ; sh:path ex:myProperty ; sh:severity sh:Warning ; sh:sourceConstraintComponent sh:DatatypeConstraintComponent ; sh:sourceShape ex:MyShape ; sh:value "http://toomanycharacters"^^xsd:anyURI ; ] . [ a sh:ValidationResult ; sh:focusNode ex:MyInstance ; sh:message "Too many characters"@en ; sh:message "Zu viele Zeichen"@de ; sh:path ex:myProperty ; sh:severity sh:Violation ; sh:sourceConstraintComponent sh:MaxLengthConstraintComponent ; sh:sourceShape ex:MyShape ; sh:value "http://toomanycharacters"^^xsd:anyURI ; ] .
Constraints may have values for the property sh:message
, and
these values must be xsd:string
literals or literals with a language tag.
If a constraint has at least one value for sh:message
in the shapes graph, then
all validation results produced as a result of the constraint will have exactly these messages
as their value of sh:message
, i.e. the values will be copied from the shapes graph
into the results graph.
A constraint SHOULD NOT have more than one value for sh:message
with the same language tag.
The example from the previous section uses this mechanism to supply the second validation result
with two messages.
See the section on sh:message
in the validation results
on further details on how the values of sh:message
are populated.
The definition for validating a data graph against a shapes graph as well as a node from the data graph against a shape from the shapes graph is provided below:
rdf:type
triples or an expected type that would also make them property constraints.
After validation, SHACL processors MUST return a validation report containing all validation results.
For simpler validation scenarios, SHACL processors SHOULD provide an additional validation interface that returns only
true
for valid or false
for invalid.
Only SHACL implementations that can return all of the mandatory properties of the Validation Results Vocabulary are standards-compliant.
A validation may also result in a failure, which is reported by a SHACL processor to indicate that a request could not be handled. Failures are not represented as part of the validation report but through implementation-specific channels.
To validate a data graph against the shapes graph, a SHACL processor requires the shapes graph and the data graph as arguments for the validation process. Optionally, two additional arguments may be provided for validating a specific node from the data graph against a specific shape from the shapes graph.
SHACL can be used with RDF graphs that are obtained by any means, e.g. from the file system, HTTP requests, or RDF datasets. SHACL makes no assumptions about whether a graph contains triples that are entailed from the graph under any RDF entailment regime.
During validation, the data graph and the shapes graph MUST remain immutable, i.e. both graphs at the end of the validation must be identical to the graph at the beginning of validation. SHACL processors MUST NOT change the graphs that they use to construct the shapes graph or the data graph, even if these graphs are part of an RDF store that allows changes to its stored graphs. SHACL processors MAY store the graphs that they create, such as a graph containing validation results, and this operation MAY change existing graphs in an RDF store, but not any of the graphs that were used to construct the shapes graph or the data graph. SHACL processing is thus idempotent.
The shapes graph is an RDF graph that contains shape definitions that a data graph can be tested against.
Shapes graphs can be reusable validation modules that can be cross-referenced with the predicate owl:imports
.
As a pre-validation step, SHACL processors SHOULD extend the originally provided shapes graph by transitively following and importing all referenced shapes graphs
through the owl:imports
predicate.
The resulting graph forms the input shapes graph for validation and MUST NOT be further modified during the validation process.
In addition to shape definitions, the shapes graph may contain additional information for the SHACL processor such as entailment directives.
A recursive shape is a shape whose constraints refer to the shape directly or transitively via the parameters of
shape-based constraint components (e.g. sh:shape
),
logical constraint components (e.g. sh:or
) or
filter shapes (sh:filterShape
).
The handling of recursive shapes is not defined in SHACL and is left to SHACL processor implementations.
The data graph is an RDF graph that a SHACL processor can validate. SHACL processors treats it as a general RDF graph and makes no assumption about its nature. For example, it can be an in-memory graph or a named graph from an RDF dataset or a SPARQL endpoint.
The data graph is expected to include all the ontology axioms related to the data and especially all the rdfs:subClassOf
triples in order for SHACL to correctly identify class targets and validate Core SHACL constraints.
A data graph can include triples used to suggest one or more graphs to a SHACL processor with the predicate sh:shapesGraph
.
Every value of this property is an IRI representing a graph that should be included into the shapes graph used to validate the data graph.
In the following example, a SHACL processor may use the union of ex:graph-shapes1
and ex:graph-shapes2
graphs (and their owl:imports
) as the shapes graph when validating the given graph.
<http://example.com/myDataGraph> sh:shapesGraph ex:graph-shapes1 ; sh:shapesGraph ex:graph-shapes2 .
SHACL provides a way for schema (i.e. ontology or vocabulary) creators to suggest a set of shapes graphs for validating data graphs that uses that schema.
These suggestions MAY be taken into account by users for specifying a shapes graph in order to validate a data graph.
The suggestions are instantiated in the schema documents
where every value for the property sh:shapesGraph
denotes a suggested shapes graph.
When the schema is identified by a schema IRI or a version IRI,
this IRI SHOULD be the subject of these triples.
The validation report is the result of the validation process and includes a set of zero or more validation results. The properties of the SHACL Validation Results Vocabulary are defined in this section. This vocabulary defines the RDF properties to represent structural information that may provide guidance on how to identify or fix a violation.
The validation results produced by a SHACL processor MUST be the product of validation of the data graph only. Some SHACL processors MAY also report errors in the shapes graph, but those errors MUST NOT be included in the data validation results.
The following graph represents an example of a validation result.
Note that the specific value of sh:message
is not mandated by SHACL and considered implementation-specific.
ex:ExampleConstraintViolation a sh:ValidationResult ; sh:severity sh:Violation ; sh:focusNode ex:Bob ; sh:path ex:age ; sh:value "twenty two" ; sh:message "ex:age expects a literal of datatype xsd:integer." ; sh:sourceConstraintComponent sh:DatatypeConstraintComponent ; sh:sourceShape ex:PersonShape .
Validation results must be SHACL instances of the class sh:ValidationResult
.
Its SHACL superclass, sh:AbstractResult
, defines the properties described in the remaining sub-sections of this section.
SHACL implementations may use other SHACL subclasses of sh:AbstractResult
, for example
to report successfully completed constraint checks or accumulated results.
The properties sh:focusNode
and sh:severity
are the only properties that are mandatory for all validation results.
The property sh:sourceConstraintComponent
is mandatory for validation results produced by violations of constraint components.
Validation results must have a single value for the property sh:focusNode
to point to a
node that has caused the result.
This is the focus node that was validated when the validation result was produced.
Validation results may have a value for the property sh:path
pointing at a well-formed property path starting with the given sh:focusNode
.
For results produced by a property constraint, this path is always identical to either the sh:predicate
or sh:path
of the constraint.
Validation results may include, as a value of the property sh:value
,
a specific node that has caused the result.
The values of sh:value
are populated by a SHACL processor based on the rules
outlined in the section on Core Constraint Components.
In most of these cases, the values of sh:value
are the value nodes that have violated a constraint.
For SPARQL-based constraints, the values of sh:value
are derived using a Mapping of SPARQL Result Variables.
Validation results may link to the IRI of the constraint that has caused
the result, specified via the property sh:sourceConstraint
,
and at the IRI of the shape defining the constraint, via sh:sourceShape
.
For validation results produced as a result of a constraint component,
the property sh:sourceConstraintComponent
must have as its object value the IRI of the constraint component that caused the result.
For example, results produced due to a violation of a constraint based on a value of sh:minCount
would have the value sh:MinCountConstraintComponent
.
The property sh:detail
may link a (parent) result with one or more other
(child) results that provide further details about the cause of the (parent) result.
Depending on the capabilities of the SHACL processor, this may include violations of
nested constraints that have been evaluated via sh:shape
.
Validation results may have values for the property sh:message
to communicate
additional textual details to humans.
While sh:message
may have multiple values, there SHOULD not be two values with the same language tag.
These values are produced by a validation engine based on the values of sh:message
of the constraints
in the shapes graph, see Defining Messages for a Constraint.
In cases where a constraint does not define any values of sh:message
in the shapes graph the
following policy applies:
sh:message
.
Each validation result must have exactly one value for the property sh:severity
, and this value must be a IRI.
The values are derived from the shapes graph as described in the section Declaring the Severity of a Constraint.
This section defines the built-in SHACL Core constraint components that MUST be supported by all SHACL Core processors.
Each constraint component is identified by an IRI that is referenced in the validation results via sh:sourceConstraintComponent
.
The choice of constraint components that are defined by the SHACL Core was made based on
the requirements collected by the [[shacl-ucr]] document.
Special attention was paid to the balance between trying to cover as many common use cases as possible
and keeping the size of the Core language manageable.
Not all use cases (such as describing constraints on members of an rdf:List
) can be expressed by the Core language alone.
Instead, SHACL Full provides an extension mechanism, described in the second part of this specification.
It is expected that additional reusable libraries of constraint components will be maintained by third parties.
All constraint components can be used both in property constraints and focus node constraints. However, some components may always result in violations in a particular constraint type. For example, sh:closed does not make sense in property constraints or sh:hasValue in focus node constraints.
The textual description of each component refers to the concept of value nodes which is defined as follows, including rules for the creation of validation results:
sh:predicate
the value nodes are the objects of the triples that have the focus node as subject and the sh:predicate
value as predicate.
Each produced validation result must have the focus node as its sh:focusNode
,
the sh:predicate
as its sh:path
and, if applicable, the respective violating value node as its sh:value
.
sh:path
the value nodes is the set of nodes in the data graph
that can be reached from the focus node with the provided SHACL property path.
Each produced validation result must have the focus node as its sh:focusNode
,
and, if applicable, the respective violating value node as its sh:value
.
The value of sh:path
of each validation result must point to a SHACL property path that represents an equivalent path like the one provided in the constraint.
The SPARQL definitions in this section represent potential validators.
Many constraint components are written as SPARQL ASK queries.
These queries are interpreted against each value node, bound to the variable value
.
If an ASK query does not evaluate to true
for a value node, a validation result is produced based on the rules outlined in
the section on ASK-based validators.
Constraint components that are described using a SELECT query are interpreted based on the rules outlined in
the section on SELECT-based validators.
In particular, for property constraints, the variable PATH
is substituted with a path expression
based on the values of either sh:predicate
or sh:path
in the constraint.
All SPARQL queries also assume the variable bindings and result variable mapping rules detailed in the
section on SPARQL-based Constraints.
The variable this
represents the currently validated focus node.
Based on the parameter IRIs on the tables, pre-bound variables are defined using the parameter names.
The constraint components in this section have in common that they define restrictions on the type of the nodes. Note that it is possible to represent multiple value type options using sh:or.
The property sh:class
can be used to verify that each value node is a SHACL instance of a given type.
Constraint Component IRI: sh:ClassConstraintComponent
Property | Summary |
---|---|
sh:class |
Type of all value nodes |
sh:class
must be IRIs.
A validation result must be produced for each value node
that is either a literal, or a non-literal that is not a SHACL instance of the given class in the data graph.
ASK { $value rdf:type/rdfs:subClassOf* $class . }
ex:ClassExampleShape
a sh:Shape ;
sh:targetNode ex:Bob, ex:Alice, ex:Carol ;
sh:property [
sh:predicate ex:knows ;
sh:class ex:Person ;
] .
ex:Alice a ex:Person . ex:Bob ex:knows ex:Alice . ex:Carol ex:knows ex:Bob .
shape | focus node | valid | reason |
---|---|---|---|
ex:ClassExampleShape | ex:Alice | yes | |
ex:ClassExampleShape | ex:Bob | no | expected to be in class ex:Person . |
ex:ClassExampleShape | ex:Carol | no | expected to be in class ex:Person . |
The property sh:datatype
can be used to restrict the datatype of all value nodes.
Constraint Component IRI: sh:DatatypeConstraintComponent
Property | Summary |
---|---|
sh:datatype |
Datatype of all value nodes (e.g., xsd:integer ) |
sh:datatype
must be the IRIs of datatypes, such as xsd:string
.
A validation result must be produced for each value node
that is not a literal, or is a literal with a mismatching datatype.
A literal matches a datatype if the literal's datatype has the same IRI
and, for the datatypes supported by SPARQL 1.1, is not an ill-typed literal.
ex:DatatypeExampleShape
a sh:Shape ;
sh:targetNode ex:Alice, ex:Bob, ex:Carol ;
sh:property [
sh:predicate ex:age ;
sh:datatype xsd:integer ;
] .
ex:Alice ex:age "23"^^xsd:integer . ex:Bob ex:age "twenty two" . ex:Carol ex:age "23"^^xsd:int .
shape | focus node | valid | reason |
---|---|---|---|
ex:DatatypeExampleShape | ex:Alice | yes | |
ex:DatatypeExampleShape | ex:Bob | no | ex:age has type xsd:string. |
ex:DatatypeExampleShape | ex:Carol | no | ex:age has type xsd:int. |
The property sh:nodeKind
is used to restrict the RDF node kind of each value node.
Constraint Component IRI: sh:NodeKindConstraintComponent
Property | Summary |
---|---|
sh:nodeKind |
Node kind (IRI, blank node, literal or combinations of these) of all value nodes |
sh:nodeKind
must be one of the following six instances of the class sh:NodeKind
:
sh:BlankNode
, sh:IRI
and sh:Literal
as well as the
following values that represent combinations of the former three, i.e. either-or:
sh:BlankNodeOrIRI
, sh:BlankNodeOrLiteral
and sh:IRIOrLiteral
.
A validation result must be produced for each value node
that does not match the given node kind.
ASK { FILTER ((isIRI($value) && $nodeKind IN ( sh:IRI, sh:BlankNodeOrIRI, sh:IRIOrLiteral ) ) || (isLiteral($value) && $nodeKind IN ( sh:Literal, sh:BlankNodeOrLiteral, sh:IRIOrLiteral ) ) || (isBlank($value) && $nodeKind IN ( sh:BlankNode, sh:BlankNodeOrIRI, sh:BlankNodeOrLiteral ) )) . }
ex:NodeKindExampleShape
a sh:Shape ;
sh:targetNode ex:Bob, ex:Alice ;
sh:property [
sh:predicate ex:knows ;
sh:nodeKind ex:IRI ;
] .
ex:Bob ex:knows ex:Alice .
ex:Alice ex:knows "Bob" .
shape | focus node | valid | reason |
---|---|---|---|
ex:NodeKindExampleShape | ex:Alice | no | ex:knows expected to be an RDF IRI. |
ex:NodeKindExampleShape | ex:Bob | yes |
The following constraint components represent restrictions on the number of values that the focus node may have for the given property or property path. SHACL has no default cardinality restrictions on properties. Focus node constraints have a cardinality always equal to 1 by design.
The property sh:minCount
restricts the minimum number of value nodes.
If the minimum cardinality value is 0 then this constraint is always satisfied and so may be omitted.
Constraint Component IRI: sh:MinCountConstraintComponent
Property | Summary |
---|---|
sh:minCount |
The minimum cardinality. |
sh:minCount
must be literals with datatype xsd:integer
.
A validation result must be produced if the number of
value nodes is less than the value of sh:minCount
.
SELECT $this WHERE { OPTIONAL { $this $PATH ?value . } } GROUP BY $this HAVING (COUNT(DISTINCT ?value) < $minCount)
ex:MinCountExampleShape
a sh:Shape ;
sh:targetNode ex:Alice, ex:Bob ;
sh:property [
sh:predicate ex:name ;
sh:minCount 1 ;
] .
ex:Alice ex:name "Alice" .
ex:Bob ex:givenName "Bob"@en .
shape | focus node | valid | reason |
---|---|---|---|
ex:MinCountExampleShape | ex:Alice | yes | |
ex:MinCountExampleShape | ex:Bob | no | expected 1 ex:name . |
The property sh:maxCount
restricts the maximum number of value nodes.
If this parameter is omitted then there is no limit on the number of triples.
Constraint Component IRI: sh:MaxCountConstraintComponent
Property | Summary |
---|---|
sh:maxCount |
The maximum cardinality. |
sh:maxCount
must be literals with datatype xsd:integer
.
A validation result must be produced if the number of
value nodes is greater than the value of sh:maxCount
.
SELECT $this WHERE { $this $PATH ?value . } GROUP BY $this HAVING (COUNT(DISTINCT ?value) > $maxCount)
ex:MaxCountExampleShape
a sh:Shape ;
sh:targetNode ex:Bob ;
sh:property [
sh:predicate ex:birthDate ;
sh:maxCount 1 ;
] .
ex:Alice ex:birthDate "May 5th 1990" .
ex:Bob ex:birthDate "May 5th 1990", "1990-05-05"^^xsd:date .
shape | focus node | valid | reason |
---|---|---|---|
ex:MaxCountExampleShape | ex:Alice | yes | |
ex:MaxCountExampleShape | ex:Bob | no | expected 1 ex:birthDate . |
The following constraint components represent range restrictions on nodes that are comparable
via operators such as <
, <=
, >
and >=
.
The properties from the following table restrict the range of value nodes.
The supported datatypes of these nodes are xsd:string
, xsd:boolean
, xsd:dateTime
and all numeric datatypes such as xsd:integer
.
Constraint Component IRIs: sh:MinExclusiveConstraintComponent
, sh:MinInclusiveConstraintComponent
, sh:MaxExclusiveConstraintComponent
, sh:MaxInclusiveConstraintComponent
Property | Summary | Definition |
---|---|---|
sh:minExclusive |
The minimum exclusive value | < |
sh:minInclusive |
The minimum inclusive value | <= |
sh:maxExclusive |
The maximum exclusive value | > |
sh:maxInclusive |
The maximum inclusive value | >= |
<
, <=
, >
and >=
.
A validation result must also be produced if the node cannot be compared to the specified range.
Note that if the comparison cannot be performed, for example when someone compares a string with an integer, then the SHACL processor will produce a validation result. This is different from, say, a plain SPARQL query, in which such failures would silently not lead to any results.
The following SPARQL definition covers sh:minExclusive
- the other variations can be derived by replacing the <
operator and the minExclusive
variable.
ASK { FILTER ($minExclusive < $value) }
ex:NumericRangeExampleShape
a sh:Shape ;
sh:targetNode ex:Bob, ex:Alice, ex:Ted ;
sh:property [
sh:predicate ex:age ;
sh:minInclusive 0 ;
sh:maxInclusive 150 ;
] .
ex:Bob ex:age 23 . ex:Alice ex:age 220 . ex:Ted ex:age "twenty one" .
shape | focus node | valid | reason |
---|---|---|---|
ex:NumericRangeExampleShape | ex:Bob | yes | |
ex:NumericRangeExampleShape | ex:Alice | no | expected ex:age to have max value 150. |
ex:NumericRangeExampleShape | ex:Ted | no | expected ex:age to be numeric. |
The constraint components in this section have in common that they are representing restrictions on the string representation of certain nodes.
The property sh:minLength
restricts the string length of value nodes.
This can be applied to any literals and IRIs, but not to blank nodes.
Constraint Component IRI: sh:MinLengthConstraintComponent
Property | Summary |
---|---|
sh:minLength |
The minimum length. If the value is 0 then there is no restriction on the string length but this constraint is still violated if the node is a blank node. |
sh:minLength
must be literals with datatype xsd:integer
.
A validation result must be produced for each value node
where the length of its string representation (as defined by the SPARQL str function)
is less than the specified minimum length, or if the node is a blank node.
ASK { FILTER (STRLEN(str($value)) >= $minLength) . }
The property sh:maxLength
restricts the string length of value nodes
This can be applied to any literals and IRIs, but not to blank nodes.
Constraint Component IRI: sh:MaxLengthConstraintComponent
Property | Summary |
---|---|
sh:maxLength |
The maximum length. If this constraint is omitted then there is no restriction on the string length and no requirement that the node is a literal or IRI. |
sh:maxLength
must be literals with datatype xsd:integer
.
A validation result must be produced for each value node
where the length of its string representation (as defined by the SPARQL str function)
is greater than the specified maximum length, or if the node is a blank node.
ASK { FILTER (STRLEN(str($value)) <= $maxLength) . }
ex:PasswordExampleShape
a sh:Shape ;
sh:targetNode ex:Bob, ex:Alice ;
sh:property [
sh:predicate ex:password ;
sh:minLength 8 ;
sh:maxLength 10 ;
] .
ex:Bob ex:password "123456789" .
ex:Alice ex:password "1234567890ABC" .
shape | focus node | valid | reason |
---|---|---|---|
ex:PasswordExampleShape | ex:Bob | yes | |
ex:PasswordExampleShape | ex:Alice | no | ex:password more than 10 characters. |
The property sh:pattern
can be used to verify that every value nodes matches a given regular expression.
Constraint Component IRI: sh:PatternConstraintComponent
Property | Summary |
---|---|
sh:pattern |
Regular expression that all value nodes must match |
sh:flags |
An optional string of flags, interpreted as in SPARQL 1.1 REGEX |
sh:pattern
must be literals with datatype xsd:string
that are
valid pattern arguments for the SPARQL REGEX function.
A validation result must be produced for each value node that is a blank node or
where the string representation (as defined by the SPARQL str function)
does not match the given regular expression (as defined by the SPARQL REGEX function).
If sh:flags
is present then this must be a literal with datatype xsd:string
that is interpreted according to the third argument of the SPARQL REGEX function.
ASK { FILTER (!isBlank($value) && IF(bound($flags), regex(str($value), $pattern, $flags), regex(str($value), $pattern))) }
ex:PatternExampleShape
a sh:Shape ;
sh:targetNode ex:Bob, ex:Alice, ex:Carol ;
sh:property [
sh:predicate ex:bCode ;
sh:pattern "^B" ; # starts with 'B'
sh:flags "i" ; # Ignore case
] .
ex:Bob ex:bCode "b101" .
ex:Alice ex:bCode "B102" .
ex:Carol ex:bCode "C103" .
shape | focus node | valid | reason |
---|---|---|---|
ex:PatternExampleShape | ex:Bob | yes | |
ex:PatternExampleShape | ex:Alice | yes | |
ex:PatternExampleShape | ex:Carol | no | ex:bCode does not match pattern. |
The property sh:stem
can be used to verify that every value node in an IRIs and the IRI starts with a given string value.
Constraint Component IRI: sh:StemConstraintComponent
Property | Summary |
---|---|
sh:stem |
String value that an IRI must start with |
sh:stem
must be literals with datatype xsd:string
.
A validation result must be produced for each value node
that is not an IRI or the string representation of the IRI does not start with the given string.
ASK { FILTER (isIRI($value) && STRSTARTS(str($value), $stem)) }
ex:StemExampleShape
a sh:Shape ;
sh:targetNode ex:Bob, ex:Alice, ex:Carol ;
sh:property [
sh:predicate ex:w3cHomepage ;
sh:stem "https://www.w3.org/People/" ;
] .
ex:Alice ex:w3cHomepage <https://www.w3.org/People/Alice> . ex:Bob ex:w3cHomepage <https://example.com/People/Bob> . ex:Carol ex:w3cHomepage "https://w3.org/People/Carol" .
shape | focus node | valid | reason |
---|---|---|---|
ex:StemExampleShape | ex:Alice | yes | |
ex:StemExampleShape | ex:Bob | no | ex:w3cHomepage does not match stem. |
ex:StemExampleShape | ex:Carol | no | ex:w3cHomepage is not an IRI. |
The property sh:languageIn
can be used to enumerate language tags that all value nodes must have.
Constraint Component IRI: sh:LanguageInConstraintComponent
Property | Summary |
---|---|
sh:languageIn |
An RDF list of language ranges |
sh:languageIn
must be RDF lists.
The members of these lists must be literals with datatype xsd:string
.
A validation result must be produced for each value node
that is either not a literal or that does not have a language tag
matching any of the provided language ranges following the filtering schema defined by
the SPARQL langMatches function.
ASK { BIND (lang($value) AS ?valueLang) . FILTER (bound(?valueLang) && EXISTS { GRAPH $shapesGraph { $languageIn (rdf:rest*)/rdf:first ?lang . FILTER (langMatches(?valueLang, ?lang)) } } ) }
The following example shape states that all values of ex:prefLabel
must be either in English or Māori.
ex:NewZealandLanguagesShape
a sh:Shape ;
sh:targetNode ex:Mountain, ex:Berg ;
sh:property [
sh:predicate ex:prefLabel ;
sh:languageIn ( "en" "mi" ) ;
] .
From the example instances, ex:Berg
will lead to constraint violations for all
of its labels.
ex:Mountain
ex:prefLabel "Mountain"@en ;
ex:prefLabel "Hill"@en-NZ ;
ex:prefLabel "Maunga"@mi .
ex:Berg
ex:prefLabel "Berg" ;
ex:prefLabel "Berg"@de ;
ex:prefLabel ex:BergLabel .
shape | focus node | valid | reason |
---|---|---|---|
ex:NewZealandLanguagesShape | ex:Mountain | yes | |
ex:NewZealandLanguagesShape | ex:Berg | no | "Berg" does not have a language tag. @de does not match language choice. ex:BergLabel is not a literal. |
The property sh:uniqueLang
can be set to true
to specify that no pair of value nodes may use the same language tag.
The values of sh:uniqueLang
must be xsd:boolean
s.
Constraint Component IRI: sh:UniqueLangConstraintComponent
Property | Summary |
---|---|
sh:uniqueLang |
true to activate this constraint |
sh:uniqueLang
must be literals with datatype xsd:boolean
.
If sh:uniqueLang
is set to true
then a validation result must be produced for each non-empty language tag that is
used by at least two value nodes.
SELECT DISTINCT $this ?lang WHERE { { FILTER ($uniqueLang) . } $this $PATH ?value . BIND (lang(?value) AS ?lang) . FILTER (bound(?lang) && ?lang != "") . FILTER EXISTS { $this $PATH ?otherValue . FILTER (?otherValue != ?value && ?lang = lang(?otherValue)) . } }
ex:UniqueLangExampleShape
a sh:Shape ;
sh:targetNode ex:Alice, ex:Bob ;
sh:property [
sh:predicate ex:label ;
sh:uniqueLang true ;
] .
ex:Alice
ex:label "Alice" ;
ex:label "Alice"@en ;
ex:label "Alice"@fr .
ex:Bob
ex:label "Bob"@en ;
ex:label "Bobby"@en .
shape | focus node | valid | reason |
---|---|---|---|
ex:UniqueLangExampleShape | ex:Alice | yes | |
ex:UniqueLangExampleShape | ex:Bob | no | multiple ex:label s with same language tag. |
The constraint components in this section restrict the sets of value nodes in relation to other properties. Value nodes of focus node constraints are always defined as a set of size 1 and may produce unexpected results when used with constraint components of this category.
sh:equals
can be used to verify that the set of value nodes is equal to the set of nodes that have the focus node as subject and the value of sh:equals
as predicate.
Constraint Component IRI: sh:EqualsConstraintComponent
Property | Summary |
---|---|
sh:equals |
Property to compare with |
sh:equals
must be IRIs.
A validation result must be produced
for each value node that does not exist as value at the focus node of the property specified using sh:equals
and
for each value of the property specified using sh:equals
that does not exist as value node.
SELECT DISTINCT $this ?value WHERE { { $this $PATH ?value . MINUS { $this $equals ?value . } } UNION { $this $equals ?value . MINUS { $this $PATH ?value . } } }
The following example illustrates the use of sh:equals
in a shape to verify
that certain nodes must have the same set of values for ex:firstName
and ex:givenName
.
ex:EqualExampleShape
a sh:Shape ;
sh:targetNode ex:Bob ;
sh:property [
sh:predicate ex:firstName ;
sh:equals ex:givenName ;
] .
ex:Alice ex:firstName "Alice" ; ex:givenName "Alice" . ex:Bob ex:firstName "Bob" ; ex:givenName "Robert" .
shape | focus node | valid | reason |
---|---|---|---|
ex:EqualExampleShape | ex:Alice | yes | |
ex:EqualExampleShape | ex:Bob | no | ex:firstName does not match ex:givenName . |
sh:disjoint
can be used to verify that the set of value nodes is disjoint with the the set of nodes that have the focus node as subject and the value of sh:equals
as predicate.
Constraint Component IRI: sh:DisjointConstraintComponent
Property | Summary |
---|---|
sh:disjoint |
The property to compare the values with |
sh:disjoint
must be IRIs.
A validation result must be produced for each value node
that also exists as value of the property specified using sh:disjoint
at the given focus node.
SELECT DISTINCT $this ?value WHERE { $this $PATH ?value . $this $disjoint ?value . }
The following example illustrates the use of sh:disjoint
in a shape to verify
that certain nodes must not share any values for ex:prefLabel
and ex:altLabel
.
ex:DisjointExampleShape
a sh:Shape ;
sh:targetNode ex:USA, ex:Germany ;
sh:property [
sh:predicate ex:prefLabel ;
sh:disjoint ex:altLabel ;
] .
ex:USA
ex:prefLabel "USA" ;
ex:altLabel "United States" .
ex:Germany
ex:prefLabel "Germany" ;
ex:altLabel "Germany" .
shape | focus node | valid | reason |
---|---|---|---|
ex:DisjointExampleShape | ex:USA | yes | |
ex:DisjointExampleShape | ex:Germany | no | ex:prefLabel must not equal ex:altLabel . |
sh:lessThan
can be used to verify that every value node is smaller than all the nodes that have the focus node as subject and the value of sh:lessThan
as predicate.
Constraint Component IRI: sh:LessThanConstraintComponent
Property | Summary |
---|---|
sh:lessThan |
The property to compare the values with |
sh:lessThan
must be IRIs.
A validation result must be produced for each pair of value nodes and
the values of the property specified using sh:lessThan
at the given focus node, where
the first value is not less than the second value, based on SPARQL's <
operator.
A validation result must also be produced if the two values cannot be compared.
SELECT DISTINCT $this ?value WHERE { $this $PATH ?value . $this $lessThan ?otherValue . FILTER (!(?value < ?otherValue)) . }
TODO: Decide what should happen if values are not comparable, i.e. < fails, similar to minExclusive etc.
The following example illustrates the use of sh:lessThan
in a shape to verify
that all values of ex:startDate
must be "before" the values of ex:endDate
.
ex:LessThanExampleShape a sh:Shape ; sh:property [ sh:predicate ex:startDate ; sh:lessThan ex:endDate ; ] .
sh:lessThanOrEquals
can be used to verify that every value node is smaller than or equal to all the nodes that have the focus node as subject and the value of sh:lessThanOrEquals
as predicate.
Constraint Component IRI: sh:LessThanOrEqualsConstraintComponent
Property | Summary |
---|---|
sh:lessThanOrEquals |
The property to compare the values with |
sh:lessThanOrEquals
must be IRIs.
A validation result must be produced for each pair of value nodes and
the values of the property specified using sh:lessThanOrEquals
at the given focus node, where
the first value is not less than or equal to the second value, based on SPARQL's <=
operator.
A validation result must also be produced if the two values cannot be compared.
SELECT DISTINCT $this ?value WHERE { $this $PATH ?value . $this $lessThan ?otherValue . FILTER (!(?value <= ?otherValue)) . }
The constraint components in this section implement the common logical operators and, or and not.
SHACL supports a negation constraint component that can be used to verify that a value node does not validate against a shape. This is comparable to a logical "not" operator.
Constraint Component IRI: sh:NotConstraintComponent
Property | Summary |
---|---|
sh:not |
The shape to negate |
sh:not
must be IRIs or blank nodes.
The expected type of these nodes is sh:Shape
.
A validation result must be produced for each value node that produces no validation results for the shape given via sh:not
.
A failure must be reported if the validation of the shape produces a failure.
The following example illustrates the use of sh:not
in a shape to verify
that certain nodes cannot have any value of ex:property
.
ex:NotExampleShape
a sh:Shape ;
sh:targetNode ex:InvalidInstance1 ;
sh:not [
a sh:Shape ;
sh:property [
sh:predicate ex:property1 ;
sh:minCount 1 ;
] ;
] .
ex:InvalidInstance ex:property1 "Some value" .
ex:ValidInstance ex:property2 "Some value" .
shape | focus node | valid | reason |
---|---|---|---|
ex:NotExampleShape | ex:InvalidInstance | no | must not have a ex:property1 . |
ex:NotExampleShape | ex:ValidInstance | yes |
SHACL supports a conjunctive constraint component that can be used to test whether a value node validates against all provided shapes. This is comparable to a logical "and" operator.
Constraint Component IRI: sh:AndConstraintComponent
Property | Summary |
---|---|
sh:and |
RDF list of shapes to validate the value nodes against |
sh:and
must be RDF lists where the members must be IRIs or blank nodes.
The expected type of these members is sh:Shape
.
A validation result must be produced for each value node if the following condition is false:
The validation of the value node against all of the members of the RDF list that is the value of sh:and
produces a validation result for at least one member.
A failure must be produced if the validation of one of the members produces a failure.
Note that although sh:and
has an rdf:List
of shapes as its value,
the order of those shapes does not impact the validation results.
The following example illustrates the use of sh:and
in a shape to verify
that certain nodes have exactly one value of ex:property
.
This is achieved via the conjunction of a separate named shape (ex:SuperShape
) which defines
the minimum count, and a blank node shape that additionally defines the maximum count.
As shown here, sh:and
can be used to implement a specialization mechanism between shapes.
ex:SuperShape
a sh:Shape ;
sh:property [
sh:predicate ex:property ;
sh:minCount 1 ;
] .
ex:ExampleAndShape
a sh:Shape ;
sh:targetNode ex:ValidInstance, ex:InvalidInstance ;
sh:and (
ex:SuperShape
[
a sh:Shape ;
sh:property [
sh:predicate ex:property ;
sh:maxCount 1 ;
]
]
) .
ex:ValidInstance
ex:property "One" .
# Invalid: more than one property
ex:InvalidInstance
ex:property "One" ;
ex:property "Two" .
shape | focus node | valid | reason |
---|---|---|---|
ex:ExampleAndShape | ex:ValidInstance | yes | |
ex:ExampleAndShape | ex:InvalidInstance | no | must have only 1 ex:property . |
SHACL supports a high-level syntax for disjunctive constraints that can be used to test whether a value node validates against at least one out of several provided shapes. This is comparable to a logical "or" operator.
Constraint Component IRI: sh:OrConstraintComponent
Property | Summary |
---|---|
sh:or |
RDF list of shapes to validate the value nodes against |
sh:or
must be RDF lists where the members must be IRIs or blank nodes.
The expected type of these members is sh:Shape
.
A validation result must be produced for each value node if the following condition is false:
The validation of the value node against all of the members in the RDF list that is the value of sh:or
produces no validation results for at least one member.
A failure must be produced if the validation of one of the members produces a failure.
Note that although sh:or
has an rdf:List
of shapes as its value,
the order of those shapes does not impact the validation results.
The following example illustrates the use of sh:or
in a shape to verify
that certain nodes have at least one value of ex:firstName
or at least one value of ex:givenName
.
ex:OrConstraintExampleShape
a sh:Shape ;
sh:targetNode ex:Bob ;
sh:or (
[
sh:property [
sh:predicate ex:firstName ;
sh:minCount 1 ;
]
]
[
sh:property [
sh:predicate ex:givenName ;
sh:minCount 1 ;
]
]
) .
ex:Alice ex:givenName "Alice" .
ex:Bob ex:firstName "Robert" .
ex:Clair ex:name "Clair" .
shape | focus node | valid | reason |
---|---|---|---|
ex:OrConstraintExampleShape | ex:Alice | yes | |
ex:OrConstraintExampleShape | ex:Bob | yes | |
ex:OrConstraintExampleShape | ex:Clair | no | must have a ex:firstName or ex:givenName . |
The next example shows how sh:or
can be used in a property constraint to state that the values of
the given property ex:address
may be either literals with datatype xsd:string
or SHACL instances of the class ex:Address
.
ex:PersonAddressShape
a sh:Shape ;
sh:targetClass ex:Person ;
sh:property [
sh:predicate ex:address ;
sh:or (
[
sh:datatype xsd:string ;
]
[
sh:class ex:Address ;
]
)
] .
ex:Alice ex:address [ a ex:Address ;
ex:street "1-14-19" ;
ex:city "湘南台" ;
ex:country "日本" ] .
ex:Bob ex:address "123 Prinzengasse, Vaduz, Liechtenstein" .
ex:Claire ex:address [
ex:street "улитса Декабристов, 55" ;
ex:city "Санкт-Петербург" ;
ex:country "Руссиа" ] .
shape | focus node | valid | reason |
---|---|---|---|
ex:PersonAddressShape | ex:Alice | yes | |
ex:PersonAddressShape | ex:Bob | yes | |
ex:PersonAddressShape | ex:Clair | no | ex:address must be a string or an ex:Address. |
The constraint components in this section can be used to represent complex restrictions based on applying shape definitions on value nodes.
sh:shape
can be used verify that all value nodes validate against the given shape.
Constraint Component IRI: sh:ShapeConstraintComponent
Property | Summary |
---|---|
sh:shape |
All value nodes must validate against the given shape |
sh:shape
must be IRIs or blank nodes.
The expected type of these values is sh:Shape
.
A validation result must be produced for each value node
where validating the value node against the shape specified by sh:shape
produces any validation results.
A failure must be produced if the validation of any value node has produced a failure.
In the following example, all values of the property ex:someProperty
will validate with no results for the shape
specified by a blank node that ensures that the property ex:nestedProperty
has at least one value.
ex:ShapeExampleShape a sh:Shape ; sh:property [ sh:predicate ex:someProperty ; sh:shape [ a sh:Shape ; # Optional sh:property [ sh:predicate ex:nestedProperty ; sh:minCount 1 ; ] ] ] .
ex:node1
ex:someProperty [
ex:nestedProperty 42 ;
] .
ex:node2
ex:someProperty [
ex:otherProperty 43 ;
] .
shape | focus node | valid | reason |
---|---|---|---|
ex:ShapeExampleShape | ex:node1 | yes | |
ex:ShapeExampleShape | ex:node2 | no | expected 1 ex:nestedProperty property. |
The property sh:qualifiedValueShape
can be used verify that a specified number of value nodes validate against the given shape.
For each sh:qualifiedValueShape
there must be either one sh:qualifiedMinCount
or one sh:qualifiedMaxCount
, or one of each, at the same subject.
Constraint Component IRI: sh:QualifiedValueShapeConstraintComponent
Property | Summary |
---|---|
sh:qualifiedValueShape |
A specified number of value nodes must validate against the given shape |
sh:qualifiedMinCount |
The minimum number of value nodes that can validate against the shape. If this constraint is omitted then there is no minimum number of values required. |
sh:qualifiedMaxCount |
The maximum number of value nodes that can validate against the shape. If this constraint is omitted then there is no maximum number of values required. |
sh:qualifiedValueShape
must be IRIs or blank nodes.
The expected type of these values is sh:Shape
.
The values of sh:qualifiedMinCount
must be literals with datatype xsd:integer
.
Let C
be the number of value nodes where
validating the node against the shape specified by sh:qualifiedValueShape
produces no validation results.
A failure must be produced if the validation of any of the value nodes produces a failure.
A validation result must be produced if C
is less than the specified sh:qualifiedMinCount
.
sh:qualifiedMaxCount
must be literals with datatype xsd:integer
.
Let C
be the number of value nodes where
validating the node against the shape specified by sh:qualifiedValueShape
produces no validation results.
A failure must be produced if the validation of any of the value nodes produces a failure.
A validation result must be produced if C
is greater than the specified sh:qualifiedMaxCount
.
In the following example, the property ex:parent
must have exactly two values,
and at least one of them needs to be female.
ex:QualifiedValueShapeExampleShape
a sh:Shape ;
sh:targetNode ex:QualifiedValueShapeExampleValidResource ;
sh:property [
sh:predicate ex:parent ;
sh:minCount 2 ;
sh:maxCount 2 ;
sh:qualifiedValueShape [
a sh:Shape ; # Optional
sh:property [
sh:predicate ex:gender ;
sh:hasValue ex:female ;
]
] ;
sh:qualifiedMinCount 1 ;
] .
ex:node1 ex:parent ex:John ; ex:parent ex:Jane . ex:John ex:gender ex:male . ex:Jane ex:gender ex:female . ex:node2 ex:parent ex:John . ex:node3 ex:parent ex:John ; ex:parent ex:June . ex:June ex:sex ex:male .
shape | focus node | valid | reason |
---|---|---|---|
ex:QualifiedValueShapeExampleShape | ex:node1 | yes | |
ex:QualifiedValueShapeExampleShape | ex:node2 | no | ex:parent fails min cardinality. |
ex:QualifiedValueShapeExampleShape | ex:node3 | no | object of ex:parent not valid. |
In some cases a given property may be multi-valued and it may be required that the set of values be partitioned into two or more subsets, each of which satisfies certain constraints.
For example, suppose that in the Library of Congress BIBFRAME (bf:
) Cultural Heritage vocabulary each person (bf:Person
) must be identified by
(bf:identifiedBy
) exactly one identifier from id.loc.gov
and may have another identifier
from viaf.org
. No other identifiers are allowed. Thus the set of all identifiers is partitioned into
two subsets, the first of which contains exactly one member and the second of which contains zero or one members.
The following example shows a snippet of some valid BIBFRAME data.
<bf_Person1> bf:identifiedBy <http://id.loc.gov/authorities/names/n80103961#RWO> ; bf:identifiedBy <https://viaf.org/viaf/268367832/#Knape,_Joachim> .
The following example shows a snippet of some invalid BIBFRAME data.
<bf_Person1> bf:identifiedBy <http://id.loc.gov/authorities/names/n80103961#RWO> ; bf:identifiedBy <https://viaf.org/viaf/268367832/#Knape,_Joachim> ; bf:identifiedBy "this is a mistake" . # should be an error
Qualified cardinality constraints provide a basis for expressing this type of partitioning requirement, but using them imposes a burden on the shapes author. In the BIBFRAME example the author would need to express the requirement that the set of all identifiers that are from neither id.loc.gov
nor viaf.org
is empty, i.e. it has a maximum cardinality of 0. Clearly, as more subsets of values are involved, the burden on the author increases.
The sh:partition
constraint makes it easier to express this type of requirement than it would be to use
multiple qualified cardinality constraints.
In effect, sh:partition
chains together a sequence of qualified cardinality constraints and removes the set of value nodes matched by each from further consideration. If every value node gets matched in this process, then
the sh:partition
constraint reports no violations. Otherwise, any value nodes remaining are reported as
violations of the constraint.
The BIBFRAME example constraint is expressed as follows.
ex:BibframeShape a sh:Shape ; sh:property [ sh:predicate bf:identifiedBy ; sh:partition ( [sh:minCount 1; sh:maxCount 1; sh:pattern "^http://id.loc.gov/"] [sh:maxCount 1; sh:pattern "^https://viaf.org/"] ) ] .
The value of the sh:partition
constraint parameter MUST be an RDF list that has zero or more members.
Each member of the list defines conditions on a subset of the value nodes and may contain the following parameters:
sh:minCount
. This defines the minimum cardinality of the corresponding subset.sh:maxCount
. This defines the maximum cardinality of the corresponding subset.sh:nodeKind
, sh:partition
,
sh:minExclusive
, etc.
The corresponding subset consists of those remaining nodes for which the boolean function is true
.
Note that a node that contains no parameters matches all nodes. Such a node is useful as the last member of the list where it acts as a default matching rule in the case where nodes that do not match any of the preceeding constraints are allowed.
Note also that a qualified cardinality constraint defined using sh:qualifiedValueShape
,
sh:qualifiedMinCount
, and sh:qualifiedMaxCount
is equivalent to a sh:partition
constraint that contains two nodes with the first one containing the corresponding parameters and the last one being the default matching rule that matches any set of nodes.
Each member of the list is used by the SHACL processor to match a subset of the value nodes. The SHACL processor matches as many nodes as possible and then compares the result with the specified minimum and maximum cardinalities if specified. This is referred to as a greedy matching algorithm. Greedy pattern matching is commonly used with textual regular expressions. Nodes that match are removed from further matching. Thus the set of all value nodes becomes partitioned by the matching algorithm. The following paragraphs define this algorithm more precisely.
Let D be a data graph and let F be a focus node in D. Let S be a shapes graph, let T be a shape in S,
and let C be a sh:partition
constraint in T.
Let N be the set of value nodes for C in D at F. Recall that N depends on how C is related to T.
sh:constraint
, C) is in S then N consists of just the node F.sh:property
, C) and (C, sh:predicate
, P) are in S
then N consists of all the nodes X such that (F, P, X) is in D.
Let the value of the sh:partition
parameter be the RDF list with members (Q1, ..., Qn).
The SHACL processor MUST perform the following steps to validate the constraint C at F.
Note that the order of nodes within the RDF list is significant. TODO: This currently violates our definition of rdf:List members. In general, if the members of the RDF list are reordered then different value node sets will be matched and different violation results will be reported.
This section enumerates Core constraint components that did not fit into the other categories.
The RDF data model offers a huge amount of flexibility.
Any node can in principle have values for any property.
However, in some cases it makes sense to restrict which properties can be applied to nodes.
The SHACL Core language includes a property called sh:closed
that can be assigned to
a shape via the property sh:constraint
to indicate that valid nodes must only have
values for those properties that have been explicitly declared via sh:property
.
Constraint Component IRI: sh:ClosedConstraintComponent
Property | Summary |
---|---|
sh:closed |
Set to true to close the shape |
sh:ignoredProperties |
Optional RDF list of properties that are also permitted in addition to those explicitly enumerated via sh:property |
sh:closed
must be literals with datatype xsd:boolean
.
If sh:closed
is true
then
a validation result must be produced for each triple that has the focus node as its
subject and a predicate that is not explicitly enumerated as a sh:predicate
in any of the sh:property
constraints at the surrounding shape.
If the parameter sh:ignoredProperties
is present then its values must be RDF lists
where all members are IRIs, and the properties enumerated in this RDF list are also permitted for the subject.
The produced validation result must have the predicate of the triple as its sh:path
,
and the object of the triple as its sh:value
.
SELECT $this (?predicate AS ?path) ?value WHERE { { FILTER ($closed) . } $this ?predicate ?value . FILTER (NOT EXISTS { GRAPH $shapesGraph { $currentShape sh:property/sh:predicate ?predicate . } } && (!bound($ignoredProperties) || NOT EXISTS { GRAPH $shapesGraph { $ignoredProperties rdf:rest*/rdf:first ?predicate . } })) }
The following example illustrates the use of sh:closed
in a shape to verify
that certain nodes only have values for ex:exampleProperty1
and ex:exampleProperty2
.
The "ignored" property rdf:type
would also be allowed.
ex:ClosedShapeExampleShape
a sh:Shape ;
sh:targetNode ex:Alice, ex:Bob ;
sh:closed true ;
sh:ignoredProperties (rdf:type) ;
sh:property [
sh:predicate ex:firstName ;
] ;
sh:property [
sh:predicate ex:lastName ;
] .
ex:Alice
ex:firstName "Alice" .
ex:Bob
ex:firstName "Bob" ;
ex:middleInitial "J" .
shape | focus node | valid | reason |
---|---|---|---|
ex:ClosedShapeExampleShape | ex:Alice | yes | |
ex:ClosedShapeExampleShape | ex:Bob | no | unexpected ex:middleInitial property. |
The property sh:hasValue
can be used to verify that one of the value nodes is a given RDF node.
Constraint Component IRI: sh:HasValueConstraintComponent
Property | Summary |
---|---|
sh:hasValue |
A specific required value |
sh:hasValue
is not among the value nodes.
SELECT $this WHERE { FILTER NOT EXISTS { $this $PATH $hasValue } }
ex:StanfordGraduate
a sh:Shape ;
sh:targetNode ex:Alice ;
sh:property [
sh:predicate ex:alumnusOf ;
sh:hasValue ex:Stanford ;
] .
ex:Alice
ex:alumnusOf ex:Stanford .
ex:Bob
ex:alumnusOf ex:Harvard ;
ex:alumnusOf ex:Stanford .
ex:Claire
ex:alumnusOf ex:Harvard .
shape | focus node | valid | reason |
---|---|---|---|
ex:StanfordGraduate | ex:Alice | yes | |
ex:StanfordGraduate | ex:Bob | yes | |
ex:StanfordGraduate | ex:Claire | no | expected 1 ex:alumnusOf ex:Stanford. |
The property sh:in
exclusively enumerates the permitted value nodes.
For example when specified as part of a property constraint, then each value of the given property must be a member of the specified RDF list.
Constraint Component IRI: sh:InConstraintComponent
Property | Summary |
---|---|
sh:in |
RDF list that has the allowed values as members |
sh:in
must be RDF lists.
The members of those RDF lists must be literals or IRIs.
A validation result must be produced for every value node
that is not a member of the given RDF list.
Matching of literals needs to be exact, e.g. "04"^^xsd:byte
does not match "4"^^xsd:integer
.
ASK { GRAPH $shapesGraph { $in (rdf:rest*)/rdf:first $value . } }
ex:InExampleShape
a sh:Shape ;
sh:targetNode ex:RainbowPony ;
sh:property [
sh:predicate ex:color ;
sh:in ( ex:Pink ex:Purple ) ;
] .
ex:pony1 ex:color ex:Pink . ex:pony2 ex:color ex:Blue . ex:pony3 ex:color ex:Pink, ex:Blue .
shape | focus node | valid | reason |
---|---|---|---|
ex:InExampleShape | ex:pony1 | yes | |
ex:InExampleShape | ex:pony2 | no | unrecognized ex:color ex:Blue. |
ex:InExampleShape | ex:pony3 | no | unrecognized ex:color ex:Blue. |
While the previous sections introduced properties that represent validation conditions, this section covers properties that are ignored by SHACL processors. The use of these properties is entirely optional and not subject to formal interpretation contracts. They may be used for purposes such as form building or predictable printing of RDF files.
Property constraints may have one or more values for sh:name
to provide human-readable labels for the property in the target where it appears.
If present, tools SHOULD prefer those locally defined labels over globally defined labels at the rdf:Property
itself.
For example, if a form displays a node that is in the target of a given shape, and the shape defines a sh:property
constraint with an sh:name
, then the tool SHOULD use the provided name.
Similarly, property constraints may have an sh:description
to provide a description of the property in the given context.
Both sh:name
and sh:description
may have multiple values, but SHOULD only have one value per language tag.
Property constraints may have one value for the property sh:order
to indicate the relative order of the property constraint for purposes such as form building.
The values of sh:order
must be decimals.
sh:order
is not used for validation purposes.
If present, the recommended use of sh:order
is to sort the property constraints in an ascending order, for example so that
properties with smaller order are placed above (or to the left) of properties with larger order.
Property constraints may link to an SHACL instance of the class sh:PropertyGroup
using the property sh:group
to indicate that
the constraint belongs to a group of related property constraints.
Each group may have additional triples that serve application purposes, such as an rdfs:label
for form building.
Groups may also have an sh:order
property to indicate the relative ordering of groups within the same form.
Property constraints may have a single value for sh:defaultValue
.
The default value does not have fixed semantics in SHACL, but MAY be used by user interface tools to pre-populate input widgets.
The value type of the sh:defaultValue
SHOULD align with the specified sh:datatype
or sh:class
of the same constraint.
The following example illustrates the use of these various features together.
ex:PersonFormShape a sh:Shape ; sh:property [ sh:predicate ex:firstName ; sh:name "first name" ; sh:description "The person's given name(s)" ; sh:order 0 ; sh:group ex:NameGroup ; ] ; sh:property [ sh:predicate ex:lastName ; sh:name "last name" ; sh:description "The person's last name" ; sh:order 1 ; sh:group ex:NameGroup ; ] ; sh:property [ sh:predicate ex:streetAddress ; sh:name "street address" ; sh:description "The street address including number" ; sh:order 11 ; sh:group ex:AddressGroup ; ] ; sh:property [ sh:predicate ex:locality ; sh:name "locality" ; sh:description "The suburb, city or town of the address" ; sh:order 12 ; sh:group ex:AddressGroup ; ] ; sh:property [ sh:predicate ex:postalCode ; sh:name "postal code" ; sh:name "zip code"@en-US ; sh:description "The postal code of the locality" ; sh:order 13 ; sh:group ex:AddressGroup ; ] . ex:NameGroup a sh:PropertyGroup ; sh:order 0 ; rdfs:label "Name" . ex:AddressGroup a sh:PropertyGroup ; sh:order 1 ; rdfs:label "Address" .
A form building application may use the information above to display information as follows:
first name: | John |
last name: | Doe |
street address: | 123 Silverado Ave |
locality: | Cupertino |
zip code: | 54321 |
Part 1 of this specification introduced features that are built into the Core of SHACL. The goal of this Core was to provide a high-level vocabulary for common use cases to describe shapes. However, SHACL also provides mechanisms to go beyond the Core vocabulary and represent constraints and targets with greater flexibility. These mechanisms, called SHACL Full, are described in the following sections.
SHACL Full supports two mechanisms to define constraints using SPARQL:
The following sub-sections are about the latter.
Shapes may have values for the property sh:sparql
, and these values must be IRIs or blank nodes.
The values of sh:sparql
have the expected type sh:SPARQLConstraint
which is an rdfs:subClassOf sh:Constraint
and is the class of all SPARQL-based constraints.
SPARQL-based constraints must have exactly one value for the property sh:select
and this value must be a literal with datatype xsd:string
.
As elaborated in the section on prefix handling rules, the value of sh:select
must be transformable into
a SPARQL 1.1 SELECT query.
The remainder of this section is not normative.
The following example illustrates the definition of a SPARQL-based constraint.
ex:ValidCountry a ex:Country ;
ex:germanLabel "Spanien"@de .
ex:InvalidCountry a ex:Country ;
ex:germanLabel "Spain"@en .
shape | focus node | valid | reason |
---|---|---|---|
ex:LanguageExampleShape | ex:ValidCountry | yes | |
ex:LanguageExampleShape | ex:InvalidCountry | no | expected ex:germanLabel with "@de". |
ex:LanguageExampleShape
a sh:Shape ;
sh:targetClass ex:Country ;
sh:sparql [
a sh:SPARQLConstraint ; # This triple is optional
sh:message "Values must be literals with German language tag." ;
sh:prefixes ex: ;
sh:select """
SELECT $this (ex:germanLabel AS ?path) ?value
WHERE {
$this ex:germanLabel ?value .
FILTER (!isLiteral(?value) || !langMatches(lang(?value), "de"))
}
""" ;
] .
The target of the shape above includes all SHACL instances of ex:Country
.
For those RDF nodes (represented by the variable this
), the SPARQL query walks through the values of ex:germanLabel
and verifies that they are literals with a German language code.
The validation results for the aforementioned data graph is shown below:
[ a sh:ValidationResult ; sh:severity sh:Violation ; sh:focusNode ex:InvalidCountry ; sh:path ex:germanLabel ; sh:value "Spain"@en ; sh:sourceShape ex:LanguageExampleShape ; ... ]
The SPARQL query returns result set solutions for all bindings of ?value
that violate the constraint.
A validation result is produced for each solution in that result set, following the mapping rules explained later:
Each validation result will have $this
as the sh:focusNode
,
ex:germanLabel
as sh:path
and the violating value as sh:value
.
A shapes graph may include declarations of namespace prefixes so that these prefixes can be used to abbreviate the SPARQL queries derived from the same shapes graph. The syntax of such prefix declarations is illustrated by the following example.
ex: a owl:Ontology ; owl:imports sh: ; sh:declare [ sh:prefix "ex" ; sh:namespace "http://example.com/ns#"^^xsd:anyURI ; ] ; sh:declare [ sh:prefix "schema" ; sh:namespace "http://schema.org/"^^xsd:anyURI ; ] .
The property sh:declare
is used to make individual prefix declarations.
The SHACL vocabulary defines the class sh:PrefixDeclaration
for the values of sh:declare
although no rdf:type
triple is required for them.
The values of sh:declare
must have exactly one value for the property sh:prefix
(literals of datatype xsd:string
)
and exactly one value for the property sh:namespace
(literals of datatype xsd:anyURI
).
Such a pair of values defines a single mapping of a prefix to a namespace.
The recommended subject for values of sh:declare
is the IRI of the graph defining the shapes that use the prefixes.
These IRIs are often declared as an instance of owl:Ontology
, but this is not required.
Prefix declarations can be used by SPARQL-based constraints and similar SPARQL-based features such as
the validators of constraint components,
derived values constraints,
target types and functions.
These nodes can use the property sh:prefixes
to define a set of prefix mappings.
(An example use of the sh:prefixes
property can be found in the
example above.)
The values of sh:prefixes
must be IRIs or blank nodes.
A SHACL processor collects a set of prefix mappings as the union of all
single prefix mappings that can be reached by the property path sh:prefixes/owl:imports*/sh:declare
starting at the SPARQL-based constraint.
If such a collection of prefix declarations contains multiple namespaces for the same sh:prefix
,
then the shapes graph is invalid.
A SHACL processor transforms the values of sh:select
(and similar properties such as sh:ask
)
into SPARQL by prepending PREFIX
declarations
for all namespace prefix mappings.
Each value of sh:prefix
is turned into the PNAME_NS
, while each value of sh:namespace
is turned
into the IRIREF
in the PREFIX
declaration.
For the example shapes graph above, a SHACL Full processor would produce lines such as PREFIX ex: <http://example.com/ns#>
.
The SHACL Full processor must produce a failure if the resulting SPARQL query string cannot be parsed into a valid SPARQL 1.1 query.
In the rest of this document, the sh:prefixes
statements may have been omitted for brevity.
The following table enumerates variables that have special meaning in SPARQL constraints. When SPARQL constraints are executed, the SHACL Full processor pre-binds values for these variables.
Variable | Interpretation |
---|---|
$this |
The focus node. |
$shapesGraph |
Can be used to query the shapes graph as in GRAPH $shapesGraph { ... } .
If the shapes graph is a named graph in the same dataset as the data graph then it is the IRI of the shapes graph in the dataset.
Not all SHACL Full processors need to support this variable.
Processors that do not support $shapesGraph MUST report a failure if they encounter a query that references this variable.
Use of GRAPH $shapesGraph { ... } should be handled with extreme caution.
It may result in constraints that are not interoperable across different SHACL Full processors and that may not run on remote RDF datasets.
|
$currentShape |
The current shape. Typically used in conjunction with $shapesGraph .
The same support policies as for $shapesGraph apply for this variable.
|
If one of the solutions of the result set produced by a SELECT query contains the binding true
for the variable failure
, then the SHACL Full processor must signal a failure.
Otherwise, each row of the result set produced by a SELECT query must be converted into one validation result node. The properties of those nodes are derived by the following rules, through a combination of result variables and the properties linked to the constraint itself. The production rules are meant to be executed from top to bottom, so that the first bound value will be used.
Property | Production Rules |
---|---|
sh:severity |
|
sh:focusNode |
|
sh:path |
|
sh:value |
|
sh:message |
|
sh:sourceConstraint |
|
sh:sourceShape |
|
It is possible to inject additional annotation properties into the validation result nodes created for each solution of the SELECT result sets.
Any such property needs to be declared via a value of sh:resultAnnotation
at the subject holding the sh:select
or sh:ask
triple.
The values of sh:resultAnnotation
must be IRIs or blank nodes with the following properties:
Property | Value type | Count | Description |
---|---|---|---|
sh:annotationProperty |
rdf:Property |
1 (mandatory) |
The annotation property that shall be set |
sh:annotationVarName |
xsd:string |
0..1 |
The name of the SPARQL variable to take the values from |
sh:annotationValue |
0..unlimited |
Constant nodes that shall be used as default values |
For each solution of a SELECT result set, a SHACL Full processor must walk through the declared result annotations. The mapping from result annotations to SPARQL variables uses the following rules:
sh:resultAnnotation
defines a sh:annotationVarName
then the SHACL Full processor must look for the variable named after the sh:annotationVarName
sh:annotationProperty
using the same local name mechanism as described earlier
If a variable name could be determined, then the SHACL Full processor must copy the bindings for the given variable into the constructed validation results for the current solution.
If the variable has no binding in the result set solution, then the value of sh:annotationValue
must be used, if present.
The values of sh:annotationProperty
must not be from the SHACL namespace, to avoid clashes with variables that are already produced by other means.
Here is a slightly complex example, illustrating the use of result annotations.
ex:ShapeWithPathViolationExample
a sh:Shape ;
sh:targetNode ex:ExampleRootResource ;
sh:sparql [
sh:resultAnnotation [
sh:annotationProperty ex:time ;
sh:annotationVarName "time"
] ;
sh:select """
SELECT $this (ex:property1 AS ?path) (?first AS ?value) ?message ?time
WHERE {
$this ex:property1 ?first .
?subject ex:property2 ?first .
FILTER isBlank(?value) .
BIND (CONCAT("The ", "message.") AS ?message) .
BIND (NOW() AS ?time) .
}
""" ;
] .
ex:ExampleRootResource ex:property1 ex:ExampleIntermediateResource . ex:ExampleValueResource ex:property2 ex:ExampleIntermediateResource .
shape | focus node | valid | reason |
---|---|---|---|
ex:ShapeWithPathViolationExample | ex:ExampleRootResource | yes | sh:sparql error. |
ex:ShapeWithPathViolationExample | ex:ExampleValueResource | no |
Which produces the following validation result nodes:
[ a sh:ValidationResult ; sh:severity sh:Violation ; sh:focusNode ex:ExampleRootResource ; sh:path ex:property1 ; sh:value ex:ExampleIntermediateResource ; sh:message "The message." ; sh:sourceConstraint [ the blank node of the sh:sparql above ] ; sh:sourceShape ex:ShapeWithPathViolationExample ; ex:time "2015-03-27T10:58:00"^^xsd:dateTime ; # Example ] .
SPARQL-based constraints as introduced in the previous section provide a lot of flexibility. However, SPARQL-based constraints may be hard to understand for some people or lead to repetition. Constraint components are a way to abstract the complexity of SPARQL and define high level reusable components similar to the Core constraint components. The definition of such constraint components can be represented in the SHACL RDF vocabulary and thus shared and reused.
sh:ConstraintComponent
is the SHACL class of all constraint components.
Each constraint component must define:
sh:class
, sh:stem
)
The following example demonstrates how SPARQL can be used to define new constraint components using the SHACL Full language.
The example implements sh:pattern
and sh:flags
using a SPARQL ASK query to validate that each value node matches a given regular expression.
Note that this is only an example implementation and should not be considered normative.
sh:PatternConstraintComponent a sh:ConstraintComponent ; sh:parameter [ sh:predicate sh:pattern ; sh:order 0 ; ] ; sh:parameter [ sh:predicate sh:flags ; sh:optional true ; sh:order 1 ; ] ; sh:validator shimpl:hasPattern . shimpl:hasPattern a sh:SPARQLAskValidator ; sh:message "Value does not match pattern {$pattern}" ; sh:ask "ASK { FILTER (!isBlank($value) && IF(bound($flags), regex(str($value), $pattern, $flags), regex(str($value), $pattern))) }" .
The following sections introduce the properties that constraint components may have. Some of these properties are independent of SPARQL-based execution and apply to constraint components based on other potential extension languages such as JavaScript too.
The parameters of a constraint component are declared via the property sh:parameter
.
The objects of triples with sh:parameter
as predicate have sh:Parameter
as expected type.
There is an open issue about the relationship between SPARQL variable name and sh:predicate. Possible revisions may require an additional property similar to sh:annotationVarName.
Each parameter must have exactly one value p
for the property sh:predicate
and the value must be an IRI.
The local name of an IRI is defined as the longest NCNAME
at the end of the IRI, not immediately preceded by the first colon in the IRI.
The parameter name is defined as the local name of the value of sh:predicate
.
To ensure that a correct mapping from parameters into SPARQL variables is possible, every parameter name:
this
, shapesGraph
, currentShape
, focusNode
, predicate
, path
or value
.
An sh:Parameter
may have its property sh:optional
set to true
to indicate that the parameter is not mandatory.
Every constraint component must have at least one non-optional parameter.
The class sh:Parameter
is defined as a SHACL subclass of sh:PropertyConstraint
,
and all properties that are applicable to property constraints may also be used for parameters.
This includes descriptive properties such as sh:name
and sh:description
but also constraint parameters such as sh:class
.
Some implementations MAY use these constraint parameters to prevent the execution of constraint components with invalid parameter values.
Every parameter name defines a pre-bound variable for the constraint component the parameter belongs to. This variable can be used in the SPARQL definition of the constraint component and a SHACL Full processor MUST pre-bind it to the parameter value.
The property sh:labelTemplate
can be used at any constraint component to suggest how they could be rendered to humans.
The values of sh:labelTemplate
must be strings (possibly with language tag) that can reference the values of the declared parameters using the syntax {?varName}
or {$varName}
,
where varName
is the name of the SPARQL variable that corresponds to the parameter.
At display time, these {...}
blocks SHOULD be substituted with the actual parameter values.
There may be multiple label templates for the same subject, assuming they do not have the same language tags.
For every supported context (i.e., property constraint or shape) the constraint component must declare a suitable validator. For a given constraint, a validator is selected from the constraint component using the following rules:
sh:shapeValidator
, if present.sh:propertyValidator
, if present.sh:validator
.
If no suitable validator can be found, a SHACL Full processor ignores the constraint. The SHACL WG is seeking practical feedback on what the default behavior should be, and whether we should report violations in those cases.
SHACL Full includes two types of validators, based on SPARQL SELECT (for sh:shapeValidator
and sh:propertyValidator
)
or SPARQL ASK queries (for sh:validator
).
Validators that are SHACL instances of sh:SPARQLSelectValidator
must point at exactly one string representation of a SPARQL SELECT query via the property sh:select
.
The value of sh:select
must be a valid SPARQL query using the aforementioned prefix handling rules.
This type of validator can be used as values of sh:shapeValidator
or sh:propertyValidator
.
The following example illustrates the definition of a constraint component based on a SPARQL SELECT query.
It is a generalized variation of the SPARQL-based example constraint from the section on SPARQL-based constraints.
That SPARQL query included two constants: the specific property ex:germanLabel
and the language tag de
.
Constraint components make it possible to generalize such scenarios, so that constants get pre-bound with parameters.
This allows the query logic to be reused in multiple places, without having to write any new SPARQL.
ex:LanguageConstraintComponentUsingSELECT a sh:ConstraintComponent ; rdfs:label "Language constraint component" ; sh:parameter [ sh:predicate ex:lang ; sh:datatype xsd:string ; sh:minLength 2 ; sh:name "language" ; sh:description "The language tag, e.g. \"de\"." ; ] ; sh:labelTemplate "Values must be literals with language \"{$lang}\"" ; sh:propertyValidator [ a sh:SPARQLSelectValidator ; sh:message "Values must be literals with language \"{?lang}\"" ; sh:select """ SELECT DISTINCT $this ?value WHERE { $this $PATH ?value . FILTER (!isLiteral(?value) || !langMatches(lang(?value), $lang)) } """ ] .
Once a constraint component has been defined, its parameters can be used as illustrated in the following example.
ex:LanguageExampleShape
a sh:Shape ;
sh:targetClass ex:Country ;
sh:property [
sh:predicate ex:germanLabel ;
ex:lang "de" ;
] ;
sh:property [
sh:predicate ex:englishLabel ;
ex:lang "en" ;
] .
The example shape above specifies that all values of ex:germanLabel
must carry the language tag de
while all values of ex:englishLabel
must have en
as their language.
These details are specified via two property constraints that provide values for the ex:lang
parameter required by the constraint component.
SELECT queries used in the context of property constraints must use a special variable named PATH
as a placeholder for the predicate or path
used by the constraint.
The only legal use of this variable is in the predicate position of a triple pattern.
A query that uses the variable PATH
in any other position is invalid.
Furthermore, any query that uses the variable this
as part of the Expression used in a SPARQL 1.1 Aggregate
is invalid.
A SHACL Full processor executes the provided SPARQL query on the data graph to produce validation results.
In the context of property constraints, the SHACL Full processor will first substitute all occurrences of the variable PATH
with the provided property path derived from the value of either sh:predicate
or sh:path
in the constraint.
The resulting SPARQL query is then evaluated with the same pre-bound variables
as outlined in the section for SPARQL-based Constraints ($this
etc).
Additionally, the value of each declared parameter of the constraint component needs to be pre-bound for
the variable derived by the local name of the parameter's sh:predicate
.
For example, if a non-optional parameter declares sh:predicate ex:lang
then the variable lang
needs to be pre-bound.
The result set of the SELECT query is turned into validation results using the same rules as outlined in the section for SPARQL-based Constraints.
In addition to the result properties listed in that section, the property sh:sourceConstraintComponent
MUST point at the
IRI of the constraint component that has been evaluated.
Furthermore, a SPARQL select validator may declare additional annotation properties via sh:resultAnnotation
.
Many constraint components are of the form in which all value nodes are tested individually against some boolean condition.
Writing SELECT queries for these becomes burdensome, especially if a constraint component can be used for both property constraints and shapes.
SHACL Full provides an alternative, more compact syntax for validators based on ASK queries.
This type of validators can be used as values of the property sh:validator
.
Validators that are SHACL instances of sh:SPARQLAskValidator
must point at exactly one string representation of a SPARQL ASK query via the property sh:ask
.
The value of sh:ask
must be a valid SPARQL query using the aforementioned prefix handling rules.
The ASK queries are expected to return true
if a given value node
(represented by the pre-bound variable value
) is valid.
Prior to evaluation, a SHACL Full processor transforms the provided ASK query into a SELECT query using the following templates.
The resulting SELECT query can then be evaluated using the same algorithm as for SELECT-based validators.
The processor drops the ASK keyword, any top-level dataset clauses and solution modifiers, leaving only the GroupGraphPattern
including the outermost {...}
pair.
This block then substitutes ...
in the template.
Template for sh:Shape
context:
SELECT $this ?value WHERE { BIND ($this AS ?value) . FILTER NOT EXISTS ... }
Template for sh:PropertyConstraint
context:
SELECT DISTINCT $this ?value WHERE { $this $PATH ?value . FILTER NOT EXISTS ... }
Note that the template above includes a DISTINCT
keyword because a SPARQL path expression may
return the same ?value
multiple times, yet each value node is only validated once.
Once the corresponding template has been applied, the resulting SELECT query will be evaluated using the same approach as outlined above. Actual SHACL implementations may of course use a different approach internally, as long as the results are equivalent to the described approach.
The following example defines a constraint component using an ASK query.
ex:LanguageConstraintComponentUsingASK a sh:ConstraintComponent ; rdfs:label "Language constraint component" ; sh:parameter [ sh:predicate ex:lang ; sh:datatype xsd:string ; sh:minLength 2 ; sh:name "language" ; sh:description "The language tag, e.g. \"de\"." ; ] ; sh:labelTemplate "Values must be literals with language \"{$lang}\"" ; sh:validator ex:hasLang . ex:hasLang a sh:SPARQLAskValidator ; sh:message "Values must be literals with language \"{$lang}\"" ; sh:ask """ ASK { FILTER (isLiteral($value) && langMatches(lang($value), $lang)) } """ .
Note that the validation condition implemented by an ASK query is "in the inverse direction" from its SELECT counterpart:
ASK queries return true
for valid value nodes, while SELECT queries return the invalid value nodes.
TODO: The TopBraid SHACL API uses such ASK constraint declarations to install new SPARQL functions. Time permitting we could standardize that too, so that people can reuse the same business logic in the queries.
A constraint component is triggered for every SHACL instance of a context that defines all non-optional parameters. TODO: This is unclear.
SHACL Full provides facilities to define custom targets.
Similar to constraints, targets may either be SPARQL-based targets or
SPARQL-based target types in a higher-level vocabulary.
All subjects of sh:target
triples must be IRIs.
SPARQL-based targets must be SHACL instances of sh:SPARQLTarget
, which is a SHACL subclass of sh:Target
.
The SPARQL queries linked to a target via sh:select
must be of the query form SELECT
.
The SELECT queries must project to the result variable this
.
The resulting target consists of all distinct bindings for the variable this
.
The SELECT queries must also be executable when converted to an ASK query and with a pre-bound value for ?this
.
The set of bindings for ?this
that return true
for such ASK queries must be identical to the set produced by the SELECT query.
This design makes sure that SHACL Full processors can validate whether a given shape applies to a given individual focus node.
The following example illustrates a well-formed SPARQL-based target that produces all persons born in the USA:
ex:USCitizenShape a sh:Shape ; sh:target [ a sh:SPARQLTarget ; sh:select """ SELECT ?this WHERE { ?this a ex:Person . ?this ex:bornIn ex:USA . } """ ; ] ; ...
The class sh:TargetType
can be used to define high-level vocabularies for targets.
Similar to constraint components, such targets take parameters that are interpreted when the target is evaluated.
The class sh:SPARQLTargetType
is an rdfs:subClassOf sh:TargetType
for target types that define a SPARQL SELECT query via the property sh:select
.
Similar to constraint components, the parameter values become pre-bound variables in such SPARQL queries.
The parameter values of such targets must not be blank nodes.
All parameters of target types are expected to have sh:maxCount 1
.
Similar to constraint components, target types may also have values for the property sh:labelTemplate
.
The following example defines a new SPARQL-based parameterizable target class that takes one parameter ex:country
that gets mapped into the variable country
in the corresponding SPARQL query to determine the resulting focus nodes.
ex:PeopleBornInCountryTarget a sh:SPARQLTargetType ; rdfs:subClassOf sh:Target ; sh:labelTemplate "All persons born in {$country}" ; sh:parameter [ sh:predicate ex:country ; sh:name "country" ; sh:description "The country that the focus nodes must be born in." ; sh:class ex:Country ; sh:minCount 1 ; sh:maxCount 1 ; sh:nodeKind sh:IRI ; ] ; sh:select """ SELECT ?this WHERE { ?this a ex:Person . ?this ex:bornIn $country . } """ . ex:USCitizenShape a sh:Shape ; sh:target [ a ex:BornInCountryTarget ; ex:country ex:USA ; ] ; ...
The set of target nodes produced by such a target type consists of all bindings of the variable this
in the result set,
when the SPARQL SELECT query has been executed with the pre-bound parameter values.
It is a common scenario that certain property values are derived from other values.
For example, the area of a rectangle must be the product of width and height, or an uncle of a person is a male sibling of a parent.
SHACL Full includes a constraint parameter sh:derivedValues
that can be used with property constraints to define such constraints.
Constraint Component IRI: sh:DerivedValuesConstraintComponent
Property | Summary |
---|---|
sh:derivedValues |
An object providing instructions on how to derive the values |
The values of sh:derivedValues
must be SHACL instances of a SHACL subclass of sh:ValuesDeriver
.
sh:SPARQLValuesDeriver
is the only SHACL subclass of sh:ValuesDeriver
defined by SHACL Full.
Each SHACL instance of sh:SPARQLValuesDeriver
must have exactly one value for the property sh:select
that can be used to produce the values that the property is expected to have.
The values of sh:select
must be SPARQL SELECT queries that project into the variable value
only.
These queries can access the current focus node via the variable this
and must produce bindings for the variable value
for all derived values.
sh:focusNode
,
the sh:predicate
or sh:path
as its sh:path
, and the missing or extra value as its sh:value
.
The following example illustrates the use of sh:derivedValues
to define a restriction
so that the value of the property ex:area
must be the product of the value of ex:width
and sh:height
.
ex:RectangleShape a sh:Shape ; sh:property [ sh:predicate ex:width ; sh:datatype xsd:integer ; sh:maxCount 1 ; ] ; sh:property [ sh:predicate ex:height ; sh:datatype xsd:integer ; sh:maxCount 1 ; ] ; sh:property [ sh:predicate ex:area ; sh:datatype xsd:integer ; sh:derivedValues [ a sh:SPARQLValuesDeriver ; sh:select """ SELECT ?value WHERE { $this ex:width ?width . $this ex:height ?height . BIND (?width * ?height AS ?value) . } """ ; ] ; ] .
SHACL functions define operations that produce an RDF node based on zero or more parameters and an input RDF graph (or dataset). Functions can be called within SPARQL queries to encapsulate complex logic of other SPARQL queries, or executable logic in other languages such as JavaScript. However, the general declaration mechanism for SHACL functions is independent from SPARQL and may also be exploited by other environments.
Functions that encapsulate a SPARQL query must be SHACL instances of sh:SPARQLFunction
, which is a SHACL subclass of the more general class sh:Function
.
Such functions must provide exactly one value for either sh:ask
or sh:select
, linking to a SPARQL query.
The following example illustrates the definition of a function based on a simple mathematical SPARQL query.
ex:exampleFunction a sh:SPARQLFunction ; rdfs:comment "Computes the sum of its two parameters ?op1 and ?op2." ; sh:parameter [ sh:predicate ex:op1 ; sh:datatype xsd:integer ; sh:description "The first operand" ; ] ; sh:parameter [ sh:predicate ex:op2 ; sh:datatype xsd:integer ; sh:description "The second operand" ; ] ; sh:returnType xsd:integer ; sh:select """ SELECT ($op1 + $op2 AS ?result) WHERE { } """ .
Using the declaration above, SPARQL engines with SHACL Full support can install a new SPARQL function based on the SPARQL 1.1 Extensible Value Testing mechanism.
Such engines are then able to handle expressions such as ex:exampleFunction(40, 2)
, producing 42
, as illustrated in the following SPARQL query.
SELECT ?subject WHERE { ?subject ex:myProperty ?value . FILTER (ex:exampleFunction(?value, 2) = 42) . }
The following sections introduce the properties that such functions may have.
The parameters of a function are linked to its sh:Function
via the property sh:parameter
.
The objects of triples with sh:parameter
as predicate have sh:Parameter
as expected type.
Each parameter must have exactly one value for the property sh:predicate
.
The values of sh:predicate
must be IRIs, and follow the following restrictions:
sh:Parameter
for the same function that has a sh:predicate
with the same local name
Parameters are ordered, corresponding to the notation of function calls in SPARQL such as
ex:exampleFunction(?param1, ?param2)
.
The ordering of function parameters is determined as follows:
sh:order
.sh:order
are placed after those that have.sh:order
are ordered by the local names of their declared sh:predicate
s.
Each parameter may have its property sh:optional
set to true
to indicate that the parameter is not mandatory.
A function may declare a single return type via sh:returnType
.
This information may serve for documentation purposes, only.
However, in some execution languages such as JavaScript, the declared sh:returnType
may inform
a processor how to cast a native value into an RDF term.
SHACL instances of sh:SPARQLFunction
must have exactly one value for either sh:ask
or sh:select
.
The values of this property must be strings that can be parsed into SPARQL queries of type ASK (for sh:ask
) or SELECT (for sh:select
).
SELECT queries must project exactly one result variable and SHOULD not use the SELECT *
syntax.
In the SPARQL query, the SPARQL processor needs to pre-bind variables based on the provided parameters of the function call.
For ASK queries, the function's return value is the result of the ASK query execution, i.e. true
or false
.
For SELECT queries, the function's return value is the binding of the (single) result variable of the first solution in the result set.
Since all other bindings will be ignored, such SELECT queries SHOULD only return a single result variable and at most one solution.
If the result variable is unbound, then the function generates a SPARQL error.
Some processors may ignore the specified SPARQL query and rely on an alternative (possibly native) implementation instead, as long as the functions return the same values as the specified SPARQL query. This can be used to optimize frequently needed functions. Some processors may even use the SPARQL query to rewrite other SPARQL queries via inlining techniques.
By default, SHACL does not assume any entailment regime [[!sparql11-entailment]] to be activated on the data graph.
However, the property sh:entailment
can be used in the shapes graph to instruct a SHACL processor to ensure that a given entailment is activated on the data graph.
The values of sh:entailment
must be IRIs, with common use cases covered by [[!sparql11-entailment]].
SHACL processors are not required to support any entailment regimes. If an entailment regime is provided in the shapes graph which is not supported by the SHACL processor, the validation must produce a failure.
The following definition of what pre-binding means has not been approved by the WG yet, and is work in progress. The WG is also awaiting input from the SPARQL Maintenance (EXISTS) Community Group.
Some features of the SPARQL-based extension mechanism of SHACL Full rely on the concept of pre-binding of variables. Although variations of this concept are supported by several existing SPARQL implementations, there is no formal definition of pre-binding in the SPARQL 1.1 specifications. The goal of this section is to illustrate the effect of pre-binding to users and implementers. Note however that the following definition is not meant to serve as recommendation for an actual implementation strategy.
Pre-binding a variable with a value means that the SPARQL processor needs to evaluate all occurrences of variables with that same name (including occurrences in inner targets and nested SELECT queries) so that they have the provided value. In other words, whenever a SPARQL processor evaluates a pre-bound variable, it must use the given value.
SHACL Full defines two forms of variable pre-binding:
The variable PATH
has a special treatment in SHACL property constraint components and must be processed before any other pre-bound variable.
SHACL Full processors must perform string substitution of every occurrence of the variable PATH
to the generated SPARQL property path before performing any pre-binding.
The variable predicate
is not a pre-bound variable in SHACL and will be treated as a normal SPARQL variable.
Should we disallow the variable predicate instead to avoid confusion?
Many people contributed to this specification, including members of the RDF Data Shapes Working Group. We especially thank the following:
Arnaud Le Hors (chair), Jim Amsden, Iovka Boneva, Karen Coyle, Richard Cyganiak, Michel Dumontier, Holger Knublauch, Dimitris Kontokostas, Jose Labra, Peter Patel-Schneider, Eric Prud'hommeaux, Arthur Ryman (who also served as a co-editor until Feb 2016), Harold Solbrig, Simon Steyskal, Ted Thibodeau