1. Introduction
The library translates SHACL Node Shapes to SPARQL Queries in the form of CONSTRUCT and DELETE.
2. Getting started
2.1. Installation
The library is written in TypeScript and distributed as an NPM package:
npm i --save @hydrofoil/shape-to-query
2.2. Basic usage
import type { GraphPointer} from 'clownface' import { constructQuery} from '@hydrofoil/shape-to-query' let shape: GraphPointer const queryString= constructQuery( shape). build()
2.3. About examples below
All the examples shown in this documentation are based on a toy dataset tbbt-ld which contains resources
describing characters from the TV series The Big Bang Theory. To look nicer, the localhost
URLs have been replaced with
fictitious a tbbt.tv
domain.
3. SHACL Constraints
Issue epic on GitHub [Issue #42]
3.1. Targets
Targets are used to match specific focus nodes of a given Node Shape. The most common, and natural way is to define a target of the root shape. However, targets declared in nested shapes, such as when using § 3.2.4 Logical Constraint Components or § 3.2.5.1 sh:node, can also be used to narrow down the query results.
Note: Multiple target types are combined with UNION
3.1.1. Node targets (sh:targetNode
)
Note: SHACL spec: Shapes Constraint Language (SHACL) § targetNode
Whether there is one or multiple target nodes, a variable is used for the root focus node and the target nodes are provided as inline data using VALUES clause.
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetNode tbbt : sheldon-cooper , tbbt : penny ; sh : property [ sh : path schema : name ; ] ; ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : name ?resource2 . } WHERE { VALUES ?resource1 { <https://tbbt.tv/sheldon-cooper> <https://tbbt.tv/penny> } ?resource1 schema : name ?resource2 . }
3.1.2. Class-based Targets (sh:targetClass
)
Note: SHACL spec: Shapes Constraint Language (SHACL) § targetClass
Single target class is directly matched with the focus node
schema:Person
PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path schema : name ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 schema : name ?resource2 . } WHERE { ?resource1 rdf : type schema : Person ; schema : name ?resource2 . }
Multiple target classes are rendered as VALUES
schema:Person
and foaf:Person
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person , foaf : Person ; sh : property [ sh : path schema : name ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> PREFIX foaf : <http://xmlns.com/foaf/0.1/> CONSTRUCT { ?resource1 rdf : type ?resource2 . ?resource1 schema : name ?resource3 . } WHERE { ?resource1 rdf : type ?resource2 . VALUES ?resource2 { schema : Person foaf : Person } ?resource1 schema : name ?resource3 . }
3.1.3. Subjects-of targets (sh:targetSubjectsOf
)
Note: SHACL spec: Shapes Constraint Language (SHACL) § targetSubjectsOf
Targets resources which are the subject of a given predicate
PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetSubjectsOf schema : parent ; sh : property [ sh : path schema : name ; ] ; ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : parent ?resource2 . ?resource1 schema : name ?resource3 . } WHERE { ?resource1 schema : parent ?resource2 ; schema : name ?resource3 . }
3.1.4. Subjects-of targets (sh:targetObjectsOf
)
Note: SHACL spec: Shapes Constraint Language (SHACL) § targetObjectsOf
Targets resources which are the object of a given predicate
PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetObjectsOf schema : children ; sh : property [ sh : path schema : name ; ] ; ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource2 schema : children ?resource1 . ?resource1 schema : name ?resource3 . } WHERE { ?resource2 schema : children ?resource1 . ?resource1 schema : name ?resource3 . }
3.2. Core Constraint Components
3.2.1. Value Type Constraint Components
3.2.1.1. sh:class
Note: SHACL spec: Shapes Constraint Language (SHACL) § ClassConstraintComponent
PREFIX ch: <https://schema.ld.admin.ch/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass ch : Canton ; sh : property [ sh : path schema : containsPlace ; sh : class ch : Municipality ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type <https://schema.ld.admin.ch/Canton> . ?resource1 schema : containsPlace ?resource2 . } WHERE { ?resource1 rdf : type <https://schema.ld.admin.ch/Canton> ; schema : containsPlace ?resource2 . ?resource2 rdf : type <https://schema.ld.admin.ch/Municipality> . }
PREFIX ch: <https://schema.ld.admin.ch/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass ch : Canton ; sh : property [ sh : path schema : containsPlace ; sh : node [ sh : class ch : Municipality ; sh : property [ sh : path schema : name ; sh : hasValue "Schwytz" ; ] ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type <https://schema.ld.admin.ch/Canton> . ?resource1 schema : containsPlace ?resource2 . ?resource2 schema : name ?resource3 . } WHERE { { SELECT ?resource1 ?resource2 WHERE { ?resource1 rdf : type <https://schema.ld.admin.ch/Canton> ; schema : containsPlace ?resource2 . { ?resource2 schema : name ?resource3 . VALUES ?resource3 { "Schwytz" } ?resource6 rdf : type <https://schema.ld.admin.ch/Municipality> . } } } UNION { SELECT ?resource2 ?resource3 WHERE { ?resource1 rdf : type <https://schema.ld.admin.ch/Canton> ; schema : containsPlace ?resource2 . ?resource2 schema : name ?resource3 . { ?resource2 schema : name ?resource3 . VALUES ?resource3 { "Schwytz" } ?resource6 rdf : type <https://schema.ld.admin.ch/Municipality> . } } } }
Note: Similar can be achieved using sh:targetClass
but it is more natural to use sh:class
when nesting shapes with sh:node
3.2.1.2. sh:datatype
Note: SHACL spec: Shapes Constraint Language (SHACL) § DatatypeConstraintComponent
PREFIX ch: <https://schema.ld.admin.ch/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> [ a sh : NodeShape ; sh : targetClass ch : Municipality ; sh : property [ sh : path schema : name ; sh : datatype xsd : string ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> PREFIX xsd : <http://www.w3.org/2001/XMLSchema#> CONSTRUCT { ?resource1 rdf : type <https://schema.ld.admin.ch/Municipality> . ?resource1 schema : name ?resource2 . } WHERE { ?resource1 rdf : type <https://schema.ld.admin.ch/Municipality> ; schema : name ?resource2 . FILTER (( DATATYPE ( ?resource2 )) = xsd : string ) }
3.2.1.3. sh:nodeKind
sh:nodeKind
to restrict focus node and property nodes
PREFIX ch: <https://schema.ld.admin.ch/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass ch : Canton ; sh : nodeKind sh : IRI ; sh : property [ sh : path schema : containsPlace ; sh : nodeKind sh : BlankNode ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type <https://schema.ld.admin.ch/Canton> . ?resource1 schema : containsPlace ?resource2 . } WHERE { ?resource1 rdf : type <https://schema.ld.admin.ch/Canton> ; schema : containsPlace ?resource2 . FILTER ( ISBLANK ( ?resource2 )) FILTER ( ISIRI ( ?resource1 )) }
3.2.2. Value Range Constraint Components
3.2.2.1. sh:minExclusive
Note: SHACL spec: Shapes Constraint Language (SHACL) § MinExclusiveConstraintComponent
PREFIX ch: <https://schema.ld.admin.ch/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> [ a sh : NodeShape ; sh : targetClass ch : Municipality ; sh : property [ sh : path schema : identifier ; sh : minExclusive 250 ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type <https://schema.ld.admin.ch/Municipality> . ?resource1 schema : identifier ?resource2 . } WHERE { ?resource1 rdf : type <https://schema.ld.admin.ch/Municipality> ; schema : identifier ?resource2 . FILTER ( ?resource2 > 250 ) }
3.2.2.2. sh:minInclusive
Note: SHACL spec: Shapes Constraint Language (SHACL) § MinInclusiveConstraintComponent
PREFIX ch: <https://schema.ld.admin.ch/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> [ a sh : NodeShape ; sh : targetClass ch : Municipality ; sh : property [ sh : path schema : identifier ; sh : minInclusive 250 ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type <https://schema.ld.admin.ch/Municipality> . ?resource1 schema : identifier ?resource2 . } WHERE { ?resource1 rdf : type <https://schema.ld.admin.ch/Municipality> ; schema : identifier ?resource2 . FILTER ( ?resource2 >= 250 ) }
3.2.2.3. sh:maxExclusive
Note: SHACL spec: Shapes Constraint Language (SHACL) § MaxExclusiveConstraintComponent
PREFIX ch: <https://schema.ld.admin.ch/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> [ a sh : NodeShape ; sh : targetClass ch : Municipality ; sh : property [ sh : path schema : identifier ; sh : maxExclusive 250 ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type <https://schema.ld.admin.ch/Municipality> . ?resource1 schema : identifier ?resource2 . } WHERE { ?resource1 rdf : type <https://schema.ld.admin.ch/Municipality> ; schema : identifier ?resource2 . FILTER ( ?resource2 < 250 ) }
3.2.2.4. sh:maxInclusive
Note: SHACL spec: Shapes Constraint Language (SHACL) § MaxInclusiveConstraintComponent
PREFIX ch: <https://schema.ld.admin.ch/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> [ a sh : NodeShape ; sh : targetClass ch : Municipality ; sh : property [ sh : path schema : identifier ; sh : maxInclusive 250 ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type <https://schema.ld.admin.ch/Municipality> . ?resource1 schema : identifier ?resource2 . } WHERE { ?resource1 rdf : type <https://schema.ld.admin.ch/Municipality> ; schema : identifier ?resource2 . FILTER ( ?resource2 <= 250 ) }
3.2.3. String-based Constraint Components
3.2.3.1. sh:pattern
Note: SHACL spec: Shapes Constraint Language (SHACL) § PatternConstraintComponent
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : property [ sh : path schema : givenName ], [ sh : path schema : familyName ; sh : pattern "^[bc]" ; sh : flags "i" ; ] ; ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : givenName ?resource2 . ?resource1 schema : familyName ?resource3 . } WHERE { OPTIONAL { ?resource1 schema : givenName ?resource2 . } ?resource1 schema : familyName ?resource3 . FILTER ( REGEX ( ?resource3 , "^[bc]" , "i" )) }
3.2.3.2. sh:languageIn
Note: SHACL spec: Shapes Constraint Language (SHACL) § LanguageInConstraintComponent
PREFIX ex: <http://example.org/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX sparql: <http://datashapes.org/sparql#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path schema : jobTitle ; sh : languageIn ( "de" "en" ) ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 schema : jobTitle ?resource2 . } WHERE { ?resource1 rdf : type schema : Person ; schema : jobTitle ?resource2 . FILTER ( LANG ( ?resource2 ) IN ( "de" , "en" )) }
3.2.4. Logical Constraint Components
The elements of a sh:or
list are shapes and thus, they can be used both to define alternative paths to construct in the constructed graph,
or add filters to filter out according to the shapes' constraints.
3.2.4.1. sh:and
Note: SHACL spec: Shapes Constraint Language (SHACL) § AndConstraintComponent
Combines all paths and constraints from the list of shapes.
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : and ( [ sh : property [ sh : path schema : knows ; sh : hasValue tbbt : sheldon-cooper ; ] ] [ sh : property [ sh : path schema : jobTitle ; sh : hasValue "microbiologist" ; ] ] ) ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : knows ?resource2 . ?resource1 schema : jobTitle ?resource3 . } WHERE { ?resource1 schema : knows ?resource2 ; schema : jobTitle ?resource3 . VALUES ?resource2 { <https://tbbt.tv/sheldon-cooper> } VALUES ?resource3 { "microbiologist" } }
3.2.4.2. sh:or
Note: SHACL spec: Shapes Constraint Language (SHACL) § OrConstraintComponent
schema:givenName
and schema:familyName
but only of those resources which have either schema:parent
or schema:children
properties
PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : or ( [ sh : property [ sh : path schema : parent ] ] [ sh : property [ sh : path schema : children ] ] ) ; sh : property [ sh : path schema : givenName ], [ sh : path schema : familyName ] ; ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : givenName ?resource2 . ?resource1 schema : familyName ?resource3 . ?resource1 schema : parent ?resource4 . ?resource1 schema : children ?resource5 . } WHERE { { ?resource1 schema : givenName ?resource2 . } UNION { ?resource1 schema : familyName ?resource3 . } { ?resource1 schema : parent ?resource4 . } UNION { ?resource1 schema : children ?resource5 . } }
Add example of sh:or
used in sh:property
when more useful constraints are implemented
3.2.5. Shape-based Constraint Components
3.2.5.1. sh:node
When added to a shape, sh:node
allows to restrict a given value node to another shape.
The is most commonly use case is describing deep graph structures (as an alternative to complex SHACL Property Paths).
schema:knows
property
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : property [ sh : path schema : givenName ], [ sh : path schema : knows ; sh : node [ sh : property [ sh : path schema : givenName ] ] ; ] ; ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : givenName ?resource2 . ?resource1 schema : knows ?resource3 . ?resource3 schema : givenName ?resource4 . } WHERE { { SELECT ?resource1 ?resource2 ?resource3 WHERE { { ?resource1 schema : givenName ?resource2 . } UNION { ?resource1 schema : knows ?resource3 . } } } UNION { SELECT ?resource3 ?resource4 WHERE { ?resource1 schema : knows ?resource3 . ?resource3 schema : givenName ?resource4 . } } }
By reusing a shape, it is also possible to apply it to multiple subgraphs.
schema:parent
and schema:children
using the same PersonShape
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : node <PersonShape> ; sh : property [ sh : path schema : parent ; sh : node <PersonShape> ; ] , [ sh : path schema : children ; sh : node <PersonShape> ; ] ; ] . <PersonShape> sh : property [ sh : path schema : givenName ; ], [ sh : path schema : familyName ; ] ; .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : parent ?resource2 . ?resource1 schema : children ?resource6 . ?resource2 schema : givenName ?resource3 . ?resource2 schema : familyName ?resource4 . ?resource6 schema : givenName ?resource7 . ?resource6 schema : familyName ?resource8 . } WHERE { { SELECT ?resource1 ?resource2 ?resource6 WHERE { { ?resource1 schema : parent ?resource2 . } UNION { ?resource1 schema : children ?resource6 . } } } UNION { SELECT ?resource2 ?resource3 ?resource4 WHERE { ?resource1 schema : parent ?resource2 . { ?resource2 schema : givenName ?resource3 . } UNION { ?resource2 schema : familyName ?resource4 . } } } UNION { SELECT ?resource6 ?resource7 ?resource8 WHERE { ?resource1 schema : children ?resource6 . { ?resource6 schema : givenName ?resource7 . } UNION { ?resource6 schema : familyName ?resource8 . } } } }
Support recursive shapes using sh:node
[Issue #99]
3.2.6. Other Constraint Components
3.2.6.1. sh:hasValue
Note: SHACL spec: Shapes Constraint Language (SHACL) § HasValueConstraintComponent
Filters nodes whose property has the exact set of objects
schema:givenName
and schema:familyName
but only of those resources who know both Sheldon Cooper and Stuart Bloom
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : property [ sh : path schema : givenName ], [ sh : path schema : familyName ] , [ sh : path schema : knows ; sh : hasValue tbbt : sheldon-cooper , tbbt : stuart-bloom ; ] ; ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : givenName ?resource2 . ?resource1 schema : familyName ?resource3 . ?resource1 schema : knows ?resource4 . } WHERE { { ?resource1 schema : givenName ?resource2 . } UNION { ?resource1 schema : familyName ?resource3 . } ?resource1 schema : knows ?resource4 . FILTER ( EXISTS { ?resource1 schema : knows <https://tbbt.tv/sheldon-cooper> , <https://tbbt.tv/stuart-bloom> . }) }
sh:hasValue
is not currently supported as property of the root node shape and will be ignored in such case
3.2.6.2. sh:in
Note: SHACL spec: Shapes Constraint Language (SHACL) § InConstraintComponent
Similar to § 3.2.6.1 sh:hasValue but filters focus nodes whose property has values from the given set and no others.
schema:givenName
and schema:familyName
but only of those resources who know Sheldon Cooper or Stuart Bloom
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : property [ sh : path schema : givenName ], [ sh : path schema : familyName ], [ sh : path schema : knows ; sh : in ( tbbt : sheldon-cooper tbbt : stuart-bloom ) ; ] ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : givenName ?resource2 . ?resource1 schema : familyName ?resource3 . ?resource1 schema : knows ?resource4 . } WHERE { { ?resource1 schema : givenName ?resource2 . } UNION { ?resource1 schema : familyName ?resource3 . } ?resource1 schema : knows ?resource4 . FILTER ( ?resource4 IN ( <https://tbbt.tv/sheldon-cooper> , <https://tbbt.tv/stuart-bloom> )) }
sh:in
is not currently supported as property of the root node shape and will be ignored in such case
4. SHACL Advanced Features
This section uses the currently published SHACL Advanced Features spec as well as parts of the Community Group Draft. The implementation may become outdated in time or deviate from the spec to accommodate for the specifics of generating queries.
Issue epic on GitHub [Issue #19]
4.1. Node expressions
The core of the support for node expressions is the new sh:values
predicate, which allows the query generator to provide values for the predicate. Rather than following the sh:path
to find the match the RDF terms, the node expressions are define the objects of the property. Different kinds of node expressions can be used to generate subselects or computed properties.
Note: Because the result must be a triple patterns where the node expression’s output is the subject or object, only Predicate Path and Inverse Path can be used with sh:values
.
Multiple objects of sh:values
should form a UNION
[Issue #20]
4.1.1. Focus Node Expression
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § node-expressions-focus
The object of the property at sh:path
is the current focus node
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetNode tbbt : sheldon-cooper ; sh : property [ sh : path schema : knows ; sh : values sh : this ; ] ; ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : knows ?resource2 . } WHERE { VALUES ?resource1 { <https://tbbt.tv/sheldon-cooper> } BIND ( ?resource1 AS ?resource2 ) }
Note: For a pragmatic use of Focus Node Expression, see § 5.1.1 Node Expression Target.
4.1.2. Constant Term Expression
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § node-expressions-constant
The objects of sh:values
become directly asserted as the objects of the property.
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetNode tbbt : sheldon-cooper ; sh : property [ sh : path schema : givenName ; sh : values "Sheldon" ; ], [ sh : path schema : familyName ; sh : values "Cooper" ; ] ; ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : givenName ?resource2 . ?resource1 schema : familyName ?resource3 . } WHERE { VALUES ?resource1 { <https://tbbt.tv/sheldon-cooper> } { BIND ( "Sheldon" AS ?resource2 ) } UNION { BIND ( "Cooper" AS ?resource3 ) } }
4.1.3. Filter Shape Expressions
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § node-expressions-filter-shape
Filter shapes restricts the selected values to only those conforming to the shape set to sh:filterShape
property.
The expression requires the presence of exactly on value of sh:filterShape
property, value of which must be SHACL Shape.
It will be used to filter the values of said property to only those conforming to that shape.
PREFIX ex: <http://example.org/> PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path schema : knows ; sh : values [ sh : filterShape [ sh : property [ sh : path ( schema : address schema : addressRegion ) ; sh : hasValue "CA" ; ] ; ] ; ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 schema : knows ?resource2 . } WHERE { ?resource1 rdf : type schema : Person ; ( schema : address / schema : addressRegion ) ?resource3 . VALUES ?resource3 { "CA" } }
Note: For a practical use of Filter Shape Expression using a § 4.1.1 Focus Node Expression (without sh:nodes
), see § 5.1.1 Node Expression Target.
Additionally, sh:nodes
property can be used to select different set of values nodes for that property.
PREFIX ex: <http://example.org/> PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path ex : motherName ; sh : values [ sh : path schema : givenName ; sh : nodes [ sh : nodes [ sh : path schema : parent ] ; sh : filterShape [ sh : property [ sh : path schema : gender ; sh : hasValue schema : Female ; ] ; ] ; ] ; ] ; ], [ sh : path ex : fatherName ; sh : values [ sh : path schema : givenName ; sh : nodes [ sh : nodes [ sh : path schema : parent ] ; sh : filterShape [ sh : property [ sh : path schema : gender ; sh : hasValue schema : Male ; ] ; ] ; ] ; ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 <http://example.org/motherName> ?resource2 . ?resource1 <http://example.org/fatherName> ?resource6 . } WHERE { ?resource1 rdf : type schema : Person . { ?resource1 schema : parent ?resource3 . ?resource3 schema : gender ?resource5 . VALUES ?resource5 { schema : Female } ?resource3 schema : givenName ?resource2 . } UNION { ?resource1 schema : parent ?resource7 . ?resource7 schema : gender ?resource9 . VALUES ?resource9 { schema : Male } ?resource7 schema : givenName ?resource6 . } }
4.1.4. Function Expressions
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § node-expressions-function
Contrary to the name, function expressions are used to represent not only function calls but also other kinds of expressions:
-
logical and mathematical operations,
-
unary operators,
-
(NOT) IN
, -
built-in functions, such as
IRI
,REGEX
orCONCAT
, -
custom functions identified by any arbitrary URI.
NOTE: Read Conceptual Guides § additive-expressions to learn more about how shape-to-query handles mathematical operations.
NOTE: Read How-Tos § custom-functions to learn how to add register custom functions with shape-to-query.
ex:drivingExperienceYears
property as the difference between the current year and the year
when that person had their driving license issued
PREFIX schema: <http://schema.org/> PREFIX sparql: <http://datashapes.org/sparql#> PREFIX ex: <http://example.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path ex : drivingExperienceYears ; sh : values [ sparql : subtract ( [ sparql : year ( [ sparql : now () ] )] [ sparql : year ( [ sh : path ( ex : drivingLicense ex : issueDate ) ] )] ) ; ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 <http://example.org/drivingExperienceYears> ?resource2 . } WHERE { ?resource1 rdf : type schema : Person ; ( <http://example.org/drivingLicense> / <http://example.org/issueDate> ) ?resource3 . BIND (( YEAR ( NOW ())) - ( YEAR ( ?resource3 )) AS ?resource2 ) }
4.1.5. Path Expressions
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § node-expressions-path
Path expression is the simplest possible expression which select focus node objects at a specified path.
PREFIX ex: <http://example.org/> PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path ex : parentNames ; sh : values [ sh : path ( schema : parent schema : givenName ) ; ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 <http://example.org/parentNames> ?resource2 . } WHERE { ?resource1 rdf : type schema : Person ; ( schema : parent / schema : givenName ) ?resource2 . }
Optionally, a path expression can have one value of sh:nodes
property which defines the set of subjects for the path.
PREFIX ex: <http://example.org/> PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path ex : familyFriend ; sh : values [ sh : nodes [ sh : path [ sh : alternativePath ( schema : parent schema : spouse ) ; ] ; ] ; sh : path schema : knows ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 <http://example.org/familyFriend> ?resource2 . } WHERE { ?resource1 rdf : type schema : Person ; ( schema : parent |schema : spouse ) ?resource3 . ?resource3 schema : knows ?resource2 . }
4.1.6. Distinct Expressions
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § distinct
PREFIX ex: <http://example.org/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Organization ; sh : property [ sh : path ex : contact ; sh : values [ sh : distinct [ sh : path [ sh : alternativePath ( ex : customer ex : client ) ] ] ; ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Organization . ?resource1 <http://example.org/contact> ?resource2 . } WHERE { ?resource1 rdf : type schema : Organization . { SELECT DISTINCT ?resource1 ?resource2 WHERE { ?resource1 ( <http://example.org/customer> |<http://example.org/client> ) ?resource2 ; rdf : type schema : Organization . } } }
4.1.7. Count Expressions
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § count
PREFIX ex: <http://example.org/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Periodical ; sh : property [ sh : path ex : numberOfArticles ; sh : values [ sh : count [ sh : path schema : publication ] ; ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Periodical . ?resource1 <http://example.org/numberOfArticles> ?resource2 . } WHERE { ?resource1 rdf : type schema : Periodical . { SELECT ( COUNT ( ?resource3 ) AS ?resource2 ) WHERE { ?resource1 schema : publication ?resource3 ; rdf : type schema : Periodical . } } }
4.1.8. OrderBy Expressions
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § orderBy
Use sh:orderBy
to sort a set of focus nodes by a property from the specific path
PREFIX ex: <http://example.org/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : property [ sh : path ex : latestArticles ; sh : values [ sh : limit 10 ; sh : nodes [ sh : nodes [ sh : path schema : publication ] ; sh : orderBy [ sh : path schema : datePublished ] ; sh : desc true ; ] ; ] ; ] ; ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 <http://example.org/latestArticles> ?resource2 . } WHERE { { SELECT ?resource1 ?resource2 WHERE { ?resource1 schema : publication ?resource2 . OPTIONAL { ?resource2 schema : datePublished ?resource3 . } } ORDER BY DESC ( ?resource3 ) LIMIT 10 } }
Note: sh:desc
is optional and defaults to false
4.1.9. Limit Expressions
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § limit
Returns the first N nodes from the inner node expression
schema:parent
property
PREFIX schema: <http://schema.org/> PREFIX ex: <http://example.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path ex : oneParent ; sh : values [ sh : limit 1 ; sh : nodes [ sh : path schema : parent ] ; ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 <http://example.org/oneParent> ?resource2 . } WHERE { ?resource1 rdf : type schema : Person . { SELECT ?resource1 ?resource2 WHERE { ?resource1 schema : parent ?resource2 ; rdf : type schema : Person . } LIMIT 1 } }
Note: sh:limit
makes most sense when combined with sh:orderBy
or sh:select
4.1.10. Offset Expressions
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § offset
Skips a number of nodes from the inner node expression
schema:parent
property
PREFIX schema: <http://schema.org/> PREFIX ex: <http://example.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path ex : oneParent ; sh : values [ sh : offset 1 ; sh : nodes [ sh : path schema : parent ] ; ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 <http://example.org/oneParent> ?resource2 . } WHERE { ?resource1 rdf : type schema : Person . { SELECT ?resource1 ?resource2 WHERE { ?resource1 schema : parent ?resource2 ; rdf : type schema : Person . } OFFSET 1 } }
Note: sh:offset
makes most sense when combined with sh:limit
and sh:orderBy
or sh:select
4.2. Expression Constraints
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § ExpressionConstraintComponent
Constrains focus nodes by evaluating § 4.1 Node expressions.
PREFIX ex: <http://example.org/> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX sparql: <http://datashapes.org/sparql#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path schema : jobTitle ; ] ; sh : expression [ sparql : contains ( [ sh : path schema : jobTitle ] "physicist" ) ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 schema : jobTitle ?resource2 . } WHERE { ?resource1 rdf : type schema : Person ; schema : jobTitle ?resource2 , ?resource4 . FILTER ( CONTAINS ( ?resource4 , "physicist" )) }
4.3. SHACL Rules
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § rules
SHACL Rules provide a way insert computed data (triples) into the data graph.
Any rule with sh:deactivated true
will be ignored.
4.3.1. Triple Rules
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § TripleRule
Triple rules are a generalised way to assert new statements in the data graph. They require the subject
, predicate
and object
being provided as § 4.1 Node expressions.
relatedTo
triples for all resources linked by the children
, parent
, or spouse
predicates
PREFIX sparql: <http://datashapes.org/sparql#> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : rule [ sh : subject [ sh : path [ sh : alternativePath ( schema : spouse schema : children schema : parent ) ] ] ; sh : predicate schema : relatedTo ; sh : object sh : this ; ] , [ sh : subject sh : this ; sh : predicate schema : relatedTo ; sh : object [ sh : path [ sh : alternativePath ( schema : spouse schema : children schema : parent ) ] ] ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource2 ?resource3 ?resource4 . ?resource5 ?resource6 ?resource7 . } WHERE { ?resource1 rdf : type schema : Person . { ?resource1 rdf : type schema : Person ; ( schema : spouse |schema : children |schema : parent ) ?resource2 . BIND ( schema : relatedTo AS ?resource3 ) BIND ( ?resource1 AS ?resource4 ) } UNION { ?resource1 rdf : type schema : Person . BIND ( ?resource1 AS ?resource5 ) BIND ( schema : relatedTo AS ?resource6 ) ?resource1 ( schema : spouse |schema : children |schema : parent ) ?resource7 . } }
Because any arbitrary node expressions can be used, the resulting triples can be unrelated to the focus nodes itself.
Person
, also return a new collection resource ex:JobTitles
which gathers all
values of their respective jobTitle
properties.
PREFIX hydra: <http://www.w3.org/ns/hydra/core#> PREFIX ex: <http://example.org/> PREFIX sparql: <http://datashapes.org/sparql#> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path schema : givenName ] , [ sh : path schema : familyName ] ; sh : rule [ sh : subject ex : JobTitles ; sh : predicate hydra : member ; sh : object [ sh : path schema : jobTitle ; ]; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> PREFIX hydra : <http://www.w3.org/ns/hydra/core#> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 schema : givenName ?resource2 . ?resource1 schema : familyName ?resource3 . ?resource4 ?resource5 ?resource6 . } WHERE { ?resource1 rdf : type schema : Person . { { ?resource1 schema : givenName ?resource2 . } UNION { ?resource1 schema : familyName ?resource3 . } } UNION { ?resource1 rdf : type schema : Person . BIND ( <http://example.org/JobTitles> AS ?resource4 ) BIND ( hydra : member AS ?resource5 ) ?resource1 schema : jobTitle ?resource6 . } }
Note: That is a major difference from § 4.3.2 Property Value Rules, which is equivalent of using sh:this
as subject.
4.3.2. Property Value Rules
Note: SHACL-AF spec: SHACL Advanced Features 1.1 (draft) § PropertyValueRule
Used throughout the § 4.1 Node expressions examples, the sh:values
is a specialised kind of triple rule
which binds computed values to triples with the current focus node subject and property being the value of sh:path
.
Note: An error will be thrown when the sh:path
is not an IRI
5. Extensions
The shape-to-query library introduces some additional constructs which handle specific scenarios unique to generated SPARQL queries which cannot be otherwise handled with terms defined in SHACL and SHACL-AF.
ALl extensions use the namespace https://hypermedia.app/shape-to-query#
. The preferred prefix is s2q:
.
5.1. Targets
5.1.1. Node Expression Target
Custom targets, which are instances of s2q:NodeExpressionTarget
ar called Node Expression Targets. They are used to define the focus nodes of a shape using Node Expressions.
Any of the simple expressions will generate SPARQL patterns directly in the query.
ex:prop
lists
PREFIX ex: <http://example.org/> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX s2q: <https://hypermedia.app/shape-to-query#> [ a sh : NodeShape ; sh : target [ a s2q : NodeExpressionTarget ; sh : expression [ sh : path ( ex : prop [ sh : zeroOrMorePath rdf : rest ] rdf : first ) ; ] ; ] ; sh : property [ sh : path schema : name ; ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : name ?resource4 . } WHERE { { SELECT ( ?resource3 AS ?resource1 ) WHERE { ?resource2 ( <http://example.org/prop> / ( rdf : rest * ) / rdf : first ) ?resource3 . } } ?resource1 schema : name ?resource4 . }
Node Expression Targets become especially useful when combined with § 4.1.9 Limit Expressions, § 4.1.10 Offset Expressions and § 4.1.8 OrderBy Expressions to paginate the results and only select a subset of candidate focus nodes, which cannot be achieved by other means of SHACL-AF. Such as in the example below, where the Node Expression generates a subselect.
ex:prop
lists
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema: <http://schema.org/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX s2q: <https://hypermedia.app/shape-to-query#> [ a sh : NodeShape ; sh : target [ a s2q : NodeExpressionTarget ; sh : expression [ # 3. Select 10 first results sh : limit 10 ; sh : nodes [ # 2. Order by position sh : orderBy [ sh : path schema : position ; ] ; sh : nodes [ # 1. Find all people named John sh : filterShape [ sh : property [ sh : path schema : name ; sh : pattern "John" ; ] ; sh : property [ sh : path rdf : type ; sh : hasValue schema : Person ; ] ; ] ; ] ; ] ] ; ] ; sh : property [ sh : path schema : name ; ] ; ] .
PREFIX schema : <http://schema.org/> PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> CONSTRUCT { ?resource1 schema : name ?resource7 . } WHERE { { SELECT ?resource2 ( ?resource2 AS ?resource1 ) WHERE { ?resource2 schema : name ?resource4 . FILTER ( REGEX ( ?resource4 , "John" )) ?resource2 rdf : type ?resource5 . VALUES ?resource5 { schema : Person } OPTIONAL { ?resource2 schema : position ?resource6 . } } ORDER BY ( ?resource6 ) LIMIT 10 } ?resource1 schema : name ?resource7 . }
5.2. Node Expressions
5.2.1. Optional Expression
An optional expression is a blank node which has a single object of the s2q:optional
property which is a well-formed Node Expression.
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX s2q: <https://hypermedia.app/shape-to-query#> PREFIX sparql: <http://datashapes.org/sparql#> [ a sh : NodeShape ; sh : property [ sh : path schema : givenName ], [ sh : path schema : familyName ] ; sh : expression [ sparql : or ( [ sparql : not ( [ sparql : bound ( _: addressLocation ) ] ) ] [ sparql : eq ( _: addressLocation "TX" ) ] ) ; ] ; ] . _: addressLocation s2q : optional [ sh : path ( schema : address schema : addressRegion ) ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 schema : givenName ?resource2 . ?resource1 schema : familyName ?resource3 . } WHERE { { ?resource1 schema : givenName ?resource2 . } UNION { ?resource1 schema : familyName ?resource3 . } OPTIONAL { ?resource1 ( schema : address / schema : addressRegion ) ?resource5 . } OPTIONAL { ?resource1 ( schema : address / schema : addressRegion ) ?resource5 . } FILTER (( ! ( BOUND ( ?resource5 ))) || ( ?resource5 = "TX" )) }
5.3. Custom rules
5.3.1. SPO rule
An SPO rule is a blank node with the RDF type s2q:SPORule
. It can optionally have the properties s2q:predicateFilter
and s2q:objectFilter
, value of which must be a well-formed Node Expression.
This rule can be used to mimic a behavior of DESCRIBE
queries which would return all direct properties of the given focus node, which is otherwise not possible with other SHACL constructs.
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX s2q: <https://hypermedia.app/shape-to-query#> PREFIX sparql: <http://datashapes.org/sparql#> [ a sh : NodeShape ; sh : targetNode tbbt : sheldon-cooper ; sh : rule [ a s2q : SPORule ; ] ] .
CONSTRUCT { ?resource1 ?resource2 ?resource3 . } WHERE { VALUES ?resource1 { <https://tbbt.tv/sheldon-cooper> } ?resource1 ?resource2 ?resource3 . }
Additionally, node expressions can be used to limit the predicates and objects. sh:this
in those expressions refers to the predicate and object itself and not the subject
schema:knows
property and values which are blank nodes
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX s2q: <https://hypermedia.app/shape-to-query#> PREFIX sparql: <http://datashapes.org/sparql#> [ a sh : NodeShape ; sh : targetNode tbbt : sheldon-cooper ; sh : rule [ a s2q : SPORule ; s2q : predicateFilter [ sparql : not ( [ sparql : eq ( sh : this schema : knows ) ] ) ; ] ; s2q : objectFilter [ sh : filterShape [ sh : nodeKind sh : IRIOrLiteral ; ] ; ] ; ] ] .
PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 ?resource2 ?resource3 . } WHERE { VALUES ?resource1 { <https://tbbt.tv/sheldon-cooper> } ?resource1 ?resource2 ?resource3 . FILTER ( ! ( ?resource2 = schema : knows )) FILTER (( ISIRI ( ?resource3 )) || ( ISLITERAL ( ?resource3 ))) }
Note: In many cases, nested node shapes with expressions and constraints are a more fitting way to represent such filters.
Expanding on the example above, sh:filterShape
can be used to further restrict the objects in an SPO pattern by their respective properties
schema:knows
property but only where that other person is a physicist.
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX s2q: <https://hypermedia.app/shape-to-query#> PREFIX sparql: <http://datashapes.org/sparql#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : rule [ a s2q : SPORule ; s2q : predicateFilter [ sparql : eq ( sh : this schema : knows ) ; ] ; s2q : objectFilter [ sh : filterShape [ sh : property [ sh : path schema : jobTitle ; sh : pattern "physicist" ; ] ; ] ; ] ; ] ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 ?resource2 ?resource3 . } WHERE { ?resource1 rdf : type schema : Person ; ?resource2 ?resource3 . FILTER ( ?resource2 = schema : knows ) ?resource3 schema : jobTitle ?resource4 . FILTER ( REGEX ( ?resource4 , "physicist" )) }
Finally, SPORule
can also be used inside sh:node
expression to select the values of any nested focus node
PREFIX schema: <http://schema.org/> PREFIX tbbt: <https://tbbt.tv/> PREFIX sh: <http://www.w3.org/ns/shacl#> PREFIX s2q: <https://hypermedia.app/shape-to-query#> PREFIX sparql: <http://datashapes.org/sparql#> [ a sh : NodeShape ; sh : targetClass schema : Person ; sh : property [ sh : path schema : address ; sh : node [ sh : rule [ a s2q : SPORule ; ] ; ] ] ; ] .
PREFIX rdf : <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX schema : <http://schema.org/> CONSTRUCT { ?resource1 rdf : type schema : Person . ?resource1 schema : address ?resource2 . ?resource2 ?resource3 ?resource4 . } WHERE { { SELECT ?resource1 ?resource2 WHERE { ?resource1 rdf : type schema : Person ; schema : address ?resource2 . } } UNION { SELECT ?resource2 ?resource3 ?resource4 WHERE { ?resource1 rdf : type schema : Person ; schema : address ?resource2 . ?resource2 ?resource3 ?resource4 . } } }