zazuko / rdf-validate-shacl

Validate RDF data purely in JavaScript. An implementation of the W3C SHACL specification on top of the RDFJS stack.
MIT License
98 stars 13 forks source link

Validationreport sourceShape is a blank node #37

Closed GerwinBosch closed 3 years ago

GerwinBosch commented 3 years ago

When retrieving the sourceShape it returns a blank-node, it would be nice to get the IRI instead of the blank node label

import { runInContext } from "lodash";
import { Parser } from "n3";
const SHACLValidator = require("rdf-validate-shacl");

const dataTtl = `@prefix ex: <http://example.org/ns#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix schema: <http://schema.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:Bob
    a schema:Person ;
    schema:givenName "Robert" ;
    schema:familyName "Junior" ;
    schema:birthDate "1971-07-07"^^xsd:date ;
    schema:deathDate "1968-09-10"^^xsd:date ;
    schema:address ex:BobsAddress .
`;
const shapesTtl = `@prefix dash: <http://datashapes.org/dash#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix schema: <http://schema.org/> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

schema:PersonShape
    a sh:NodeShape ;
    sh:targetClass schema:Person ;
    sh:property [
        sh:path schema:givenName ;
        sh:datatype xsd:string ;
        sh:name "given name" ;
    ] ;
    sh:property [
        sh:path schema:birthDate ;
        sh:lessThan schema:deathDate ;
        sh:maxCount 1 ;
    ] ;
    sh:property [
        sh:path schema:gender ;
        sh:in ( "female" "male" ) ;
    ] ;
    sh:property [
        sh:path schema:address ;
        sh:node schema:AddressShape ;
    ] .
`;
const run = async () => {
  const parser = new Parser();
  const data = parser.parse(dataTtl);
  const shapes = parser.parse(shapesTtl);

  const validator = new SHACLValidator(shapes);

  const report = await validator.validate(data);

  for (const result of report.results) {
    console.log(result.sourceShape); // Returns a BlankNode
  }
};
run()
tpluscode commented 3 years ago

Just by looking at the snippet, isn't the blank node the id of a PropertyShape?

GerwinBosch commented 3 years ago

I'd expect it to have the schema:PersonShape term as the value instead of the blank node

martinmaillard commented 3 years ago

From my understanding of the SHACL spec, it would be wrong to point to the parent NodeShape instead of the PropertyShape that raised the invalid result. If you want a URI, the best way is to give a URI to your PropertyShape:

@prefix schema: <http://schema.org/> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix ex: <http://example.org/> .

schema:PersonShape
    a sh:NodeShape ;
    sh:targetClass schema:Person ;
    sh:property ex:givenNameShape ;
.

ex:givenNameShape a sh:PropertyShape ;
    sh:path schema:givenName ;
    sh:datatype xsd:string ;
    sh:name "given name" ;
.