1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
"""\
A cool test that combines a bunch of SHACL-AF features, including:
SHACL Functions (implemented as SPARQL functions)
SHACL Rules
Node Expressions
Expression Constraint
"""
from pyshacl import validate
from rdflib import Graph
shacl_file = '''\
# prefix: ex
@prefix ex: <http://datashapes.org/shasf/tests/expression/advanced.test.shacl#> .
@prefix exOnt: <http://datashapes.org/shasf/tests/expression/advanced.test.ont#> .
@prefix exData: <http://datashapes.org/shasf/tests/expression/advanced.test.data#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://datashapes.org/shasf/tests/expression/advanced.test.shacl>
rdf:type owl:Ontology ;
rdfs:label "Test of advanced features" ;
.
ex:concat
a sh:SPARQLFunction ;
rdfs:comment "Concatenates strings $op1 and $op2." ;
sh:parameter [
sh:path ex:op1 ;
sh:datatype xsd:string ;
sh:description "The first string" ;
] ;
sh:parameter [
sh:path ex:op2 ;
sh:datatype xsd:string ;
sh:description "The second string" ;
] ;
sh:returnType xsd:string ;
sh:select """
SELECT ?result
WHERE {
BIND(CONCAT(STR(?op1),STR(?op2)) AS ?result) .
}
""" .
ex:strlen
a sh:SPARQLFunction ;
rdfs:comment "Returns length of the given string." ;
sh:parameter [
sh:path ex:op1 ;
sh:datatype xsd:string ;
sh:description "The string" ;
] ;
sh:returnType xsd:integer ;
sh:select """
SELECT ?result
WHERE {
BIND(STRLEN(?op1) AS ?result) .
}
""" .
ex:lessThan
a sh:SPARQLFunction ;
rdfs:comment "Returns True if op1 < op2." ;
sh:parameter [
sh:path ex:op1 ;
sh:datatype xsd:integer ;
sh:description "The first int" ;
] ;
sh:parameter [
sh:path ex:op2 ;
sh:datatype xsd:integer ;
sh:description "The second int" ;
] ;
sh:returnType xsd:boolean ;
sh:select """
SELECT ?result
WHERE {
BIND(IF(?op1 < ?op2, true, false) AS ?result) .
}
""" .
ex:PersonExpressionShape
a sh:NodeShape ;
sh:targetClass exOnt:Person ;
sh:expression [
sh:message "Person's firstName and lastName together should be less than 35 chars long." ;
ex:lessThan (
[ ex:strlen (
[ ex:concat ( [ sh:path exOnt:firstName] [ sh:path exOnt:lastName ] ) ] )
]
35 );
] .
ex:PersonRuleShape
a sh:NodeShape ;
sh:targetClass exOnt:Administrator ;
sh:message "An administrator is a person too." ;
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate rdf:type ;
sh:object exOnt:Person ;
] .
'''
data_graph = '''
# prefix: ex
@prefix ex: <http://datashapes.org/shasf/tests/expression/advanced.test.data#> .
@prefix exOnt: <http://datashapes.org/shasf/tests/expression/advanced.test.ont#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
ex:Kate
rdf:type exOnt:Person ;
exOnt:firstName "Kate" ;
exOnt:lastName "Jones" ;
.
ex:Jenny
rdf:type exOnt:Administrator ;
exOnt:firstName "Jennifer" ;
exOnt:lastName "Wolfeschlegelsteinhausenbergerdorff" ;
.
'''
if __name__ == "__main__":
d = Graph().parse(data=data_graph, format="turtle")
s = Graph().parse(data=shacl_file, format="turtle")
conforms, report, message = validate(d, shacl_graph=s, advanced=True, debug=False)
print(message)
|