SHACL validator (rdf-validate-shacl) problems - not validating


#1

Dear Forum

I am using “rdf-validate-shacl” and working in the browser.

I can’t seem to get any other result than conforms=true , irrespective of what I’m trying to validate.

I have bundled the following libraries:

var bundle = {
  formats: require('@rdfjs/formats-common'),
  SparqlStore: require('rdf-store-sparql'),
  N3Parser: require('@rdfjs/parser-n3'),
  JsonLdParser: require('@rdfjs/parser-jsonld'),
  rdfdm: require('@rdfjs/data-model'),
  SerializerJsonld: require('@rdfjs/serializer-jsonld'),
  SerializerNtriples: require('@rdfjs/serializer-ntriples'),
  turtleScribe: require('@graphy/content.ttl.scribe'),
  trigScribe: require('@graphy/content.trig.scribe'),
  xmlScribe: require('@graphy/content.xml.scribe'),
  rdfto3: require('@rdfjs/to-ntriples'),
  rdfdi: require('rdf-dataset-indexed'),
  rdf: require('rdf-ext'),
  RdfaParser: require('rdfa-streaming-parser'),
  RdfXmlParser: require('rdfxml-streaming-parser'),
  SHACLValidator: require('rdf-validate-shacl'),
  Readable: require('readable-stream'),
  filesaver: require('file-saver')}
module.exports = bundle

So I’m using rdfdi() as the way of creating my test datastore.

Below is some code - it’s a little messy because I’m still working out how to get the shacl validator to work.
Would the forum please cast your eye over it and letting me know if I’m doing anything wildly wrong.

Cheers

Peter

==============================================

var SHACLfiledata
var validator
debug=true
var outputSHACL
var inputSHACL

async function loadSHACLDataset (files) {
  var fileText = ''
  var file = files[0]
  if (!file) return;
  
  var reader = new FileReader()
  SHACLfiledata = new rdfdi();

  reader.onload = function() {
    fileText = reader.result
    alert(fileText)
  
    let inputSHACL = new Readable({
      read: () => {
        inputSHACL.push(fileText)
        inputSHACL.push(null)
      }
    });
    
    let outputSHACL = formats.parsers.import('text/turtle', inputSHACL)
    
    outputSHACL.on('data', quad => {
      SHACLfiledata.add(quad)
    });
  
    outputSHACL.on('end', () => {
    //
    });
}
  
  reader.readAsText(file)

  validator = new SHACLValidator(SHACLfiledata, {rdf})
  return validator

}


async function SHACLreport(data){
const report = await validator.validate(data)

// Check conformance: `true` or `false`
console.log(report.conforms)

for (const result of report.results) {
  // See https://www.w3.org/TR/shacl/#results-validation-result for details
  // about each property
  console.log(result.message)
  console.log(result.path)
  console.log(result.focusNode)
  console.log(result.severity)
  console.log(result.sourceConstraintComponent)
  console.log(result.sourceShape)
}

// Validation report as RDF dataset
console.log(report.dataset)
alert("report")
}

#2

Hi Pedro,

Can you post the data you’re trying to validate?


#3
@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 .

ex:BobsAddress
    schema:streetAddress "1600 Amphitheatre Pkway" ;
    schema:postalCode 9404 .

and

@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 ;
    ] .

schema:AddressShape
    a sh:NodeShape ;
    sh:closed true ;
    sh:property [
        sh:path schema:streetAddress ;
        sh:datatype xsd:string ;
    ] ;
    sh:property [
        sh:path schema:postalCode ;
        sh:or ( [ sh:datatype xsd:string ] [ sh:datatype xsd:integer ] ) ;
        sh:minInclusive 10000 ;
        sh:maxInclusive 99999 ;
    ] .

#4

I quickly looked at your code but it as a lot of issues and I don’t have time to do a debugging session right now (sorry :frowning: ).

I wrote the following sample code (running in node, so needs to be adapted slightly for the browser). I hope this helps:

const SHACLValidator = require('rdf-validate-shacl')
const fromFile = require('rdf-utils-fs/fromFile')
const RDF = require('rdf-ext')

async function loadDataset (path) {
  return new Promise((resolve, reject) => {
    const stream = fromFile(path)
    const dataset = RDF.dataset()

    stream.on('data', (quad) => { dataset.add(quad) })
    stream.on('end', () => resolve(dataset))
    stream.on('error', (error) => reject(error))
  })
}

async function main () {
  const shapes = await loadDataset('./shapes.ttl')
  const data = await loadDataset('./data.ttl')

  const validator = new SHACLValidator(shapes, { factory: RDF })
  const report = validator.validate(data)

  // Check conformance: `true` or `false`
  console.log(report.conforms)

  for (const result of report.results) {
    // See https://www.w3.org/TR/shacl/#results-validation-result for details
    // about each property
    console.log(result.message)
    console.log(result.path)
    console.log(result.focusNode)
    console.log(result.severity)
    console.log(result.sourceConstraintComponent)
    console.log(result.sourceShape)
  }
}

(async () => { await main() })()

I get the following output in the console:

false
[
  LiteralExt {
    value: 'Value is not < value of <http://schema.org/deathDate>',
    datatype: NamedNode { value: 'http://www.w3.org/2001/XMLSchema#string' },
    language: ''
  }
]
NamedNode { value: 'http://schema.org/birthDate' }
NamedNode { value: 'http://example.org/ns#Bob' }
NamedNodeExt { value: 'http://www.w3.org/ns/shacl#Violation' }
NamedNodeExt {
  value: 'http://www.w3.org/ns/shacl#LessThanConstraintComponent'
}
BlankNode { value: 'b2' }
[
  LiteralExt {
    value: 'Value does not have shape <http://schema.org/AddressShape>',
    datatype: NamedNode { value: 'http://www.w3.org/2001/XMLSchema#string' },
    language: ''
  }
]
NamedNode { value: 'http://schema.org/address' }
NamedNode { value: 'http://example.org/ns#Bob' }
NamedNodeExt { value: 'http://www.w3.org/ns/shacl#Violation' }
NamedNodeExt {
  value: 'http://www.w3.org/ns/shacl#NodeConstraintComponent'
}
BlankNode { value: 'b6' }

Let me know if I can help somehow. Did you do any progress on your code?


#5

So in my code, running in a browser, I just get that the file conforms when clearly it doesn’t. Any idea why this is happening?


#6

Your code is not easy to follow :sweat_smile:. But my guess is that either the shapes, or the data, or both are not properly loaded from file.

Maybe try to look at what’s inside the datasets before validation?


#7

They are both datasets that show the expected quads. both datasets look OK. It is odd that I don’t get errors, even for invalid tests. Is the default set to conforms = ‘true’ ? If there is an error in computing but no error is thrown, will there be a default value for the conforms attribute?