Worked example — minCount, datatype, nodeKind
A complete SHACL validation you can run in psql.
Setup: two graphs
sql
SELECT pgrdf.add_graph('http://example.org/data');
SELECT pgrdf.add_graph('http://example.org/shapes');Load data: Bob has no mailbox
sql
SELECT pgrdf.parse_turtle('
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix ex: <http://example.org/> .
ex:alice a foaf:Person ;
foaf:name "Alice" ;
foaf:mbox <mailto:alice@example.org> .
ex:bob a foaf:Person ;
foaf:name "Bob" .
', pgrdf.graph_id('http://example.org/data'));
-- → 5Load shapes
Every foaf:Person needs at least one foaf:name that is a string, and at least one foaf:mbox that is an IRI:
sql
SELECT pgrdf.parse_turtle('
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix ex: <http://example.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
ex:PersonShape a sh:NodeShape ;
sh:targetClass foaf:Person ;
sh:property [
sh:path foaf:name ;
sh:minCount 1 ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path foaf:mbox ;
sh:minCount 1 ;
sh:nodeKind sh:IRI ;
] .
', pgrdf.graph_id('http://example.org/shapes'));
-- → 10Validate
sql
SELECT jsonb_pretty(pgrdf.validate(pgrdf.graph_id('http://example.org/data'),
pgrdf.graph_id('http://example.org/shapes')));json
{
"mode": "native",
"results": [
{
"value": null,
"focusNode": "http://example.org/bob",
"resultPath": "http://xmlns.com/foaf/0.1/mbox",
"sourceShape": "_:e0426eab19040cf3a29413efb8e7cad7",
"resultMessage": "MinCount(1) not satisfied",
"resultSeverity": "sh:Violation",
"sourceConstraintComponent": "http://www.w3.org/ns/shacl#MinCountConstraintComponent"
}
],
"conforms": false,
"elapsed_ms": 1.423,
"data_triples": 5,
"data_graph_id": 5,
"shapes_triples": 10,
"shapes_graph_id": 6
}Alice conforms. Bob doesn't, exactly as the shape declares. value is null because the violation is a missing value. sourceShape is a blank-node label because the property shape is written inline as [ … ]; its label and the graph ids will differ on your machine.
Fix the data and re-validate
sql
SELECT pgrdf.parse_turtle('
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix ex: <http://example.org/> .
ex:bob foaf:mbox <mailto:bob@example.org> .
', pgrdf.graph_id('http://example.org/data'));
SELECT pgrdf.validate(pgrdf.graph_id('http://example.org/data'),
pgrdf.graph_id('http://example.org/shapes'));
-- {"mode": "native", "results": [], "conforms": true, "elapsed_ms": 0.717,
-- "data_triples": 6, "data_graph_id": 5, "shapes_triples": 10, "shapes_graph_id": 6}Next steps
- Report as data: query, store and gate on the report with SQL.
- SHACL Core components: the other constraints you can use.