Skip to content

sh:SPARQLTarget not working? #51

@rorlic

Description

@rorlic

I assume that the shacl playground using the shacl-engine is configured to allow the use of sh:SPARQLTarget as documented here?

If so, it incorrectly gives no validation violations for my use case while the ITB shacl validator works as expected.
If not, it unfortunately also does not work for me in a local JavaScript project that is configured to use the SPARQL validations.

import rdf from '@zazuko/env-node';
import Validator from 'shacl-engine/Validator.js'
import { validations as sparqlValidations } from 'shacl-engine/sparql.js'

export async function createValidator(files: string[]) {
  const shapes = rdf.dataset();
  for (const file of files) {
    await shapes.import(rdf.fromFile(`./src/${file}`));
  }

  const validator = new Validator(shapes, { factory: rdf, validations: sparqlValidations });
  return validator;
}

In the shapes graph I define a base class and a derived class. The base class allows for a predicate which is optional at the base class level and required for the derived class. To validate this I created a node shape which targets all instances of the derived class by using a sparql query, passing in the necessary prefixes. The node shape has a property shape that verifies that the predicate appears exactly once:

@prefix ex:   <http://example.org/> .
@prefix sh:   <http://www.w3.org/ns/shacl#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .

ex:BaseClass a rdfs:Class ; 
  rdfs:label "A base class"@en.
  
ex:something a rdf:Property ;
  rdfs:label "Some property"@en ;
  rdfs:domain ex:BaseClass ;
  rdfs:range xsd:string .
  
ex:DerivedClass a rdfs:Class; 
  rdfs:subClassOf ex:BaseClass; 
  rdfs:label "A derived class"@en .
  
ex:Ontology a owl:Ontology ;
  sh:declare [
    sh:prefix "ex" ;
    sh:namespace "http://example.org/"^^xsd:anyURI
  ], [
    sh:prefix "rdf" ;
    sh:namespace "http://www.w3.org/1999/02/22-rdf-syntax-ns#"^^xsd:anyURI
  ], [
    sh:prefix "rdfs" ;
    sh:namespace "http://www.w3.org/2000/01/rdf-schema#"^^xsd:anyURI
  ] .

ex:DerivedShape a sh:NodeShape ;
  sh:target [
    a sh:SPARQLTarget ;
    sh:prefixes ex:Ontology ;
    sh:select """
        SELECT ?this 
        WHERE { 
          ?this rdf:type/rdfs:subClassOf ex:BaseClass .
        }
      """
  ] ;
  sh:property ex:SomethingRequiredShape .

ex:SomethingRequiredShape a sh:PropertyShape ;
  sh:path ex:something;
  sh:minCount 1;
  sh:maxCount 1;
  sh:name "Some property";
  sh:description "Some property which is optional for base instances, but required for derived instances";
  sh:message "A derived instance MUST have exactly one ex:something predicate" .

For the following data shape I expect that the report is non-conforming with a violation at focus nodes ex:InvalidDerivedInstance2 and ex:InvalidDerivedInstance3.

@prefix ex: <http://example.org/> .

ex:ValidBaseInstance1 a ex:BaseClass .
ex:ValidDerivedInstance1 a ex:DerivedClass ; ex:something "something".

ex:InvalidDerivedInstance2 a ex:DerivedClass .
ex:InvalidDerivedInstance3 a ex:DerivedClass ; ex:something "something", "not allowed" .

The ITB validator gives the expected result (2 violations), while the shacl-engine returns a conforming report.

PREFIX dash:    <http://datashapes.org/dash#>
PREFIX ex:      <http://example.org/>
PREFIX graphql: <http://datashapes.org/graphql#>
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 swa:     <http://topbraid.org/swa#>
PREFIX tosh:    <http://topbraid.org/tosh#>
PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>

[ rdf:type     sh:ValidationReport;
  sh:conforms  false;
  sh:result    [ rdf:type                      sh:ValidationResult;
                 sh:focusNode                  ex:InvalidDerivedInstance2;
                 sh:resultMessage              "A derived instance MUST have exactly one ex:something predicate";
                 sh:resultPath                 ex:something;
                 sh:resultSeverity             sh:Violation;
                 sh:sourceConstraintComponent  sh:MinCountConstraintComponent;
                 sh:sourceShape                ex:SomethingRequiredShape
               ];
  sh:result    [ rdf:type                      sh:ValidationResult;
                 sh:focusNode                  ex:InvalidDerivedInstance3;
                 sh:resultMessage              "A derived instance MUST have exactly one ex:something predicate";
                 sh:resultPath                 ex:something;
                 sh:resultSeverity             sh:Violation;
                 sh:sourceConstraintComponent  sh:MaxCountConstraintComponent;
                 sh:sourceShape                ex:SomethingRequiredShape
               ]
] .

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions