shexjs / shex.js

shex.js javascript package
MIT License
58 stars 17 forks source link

Failing to run your Readme example #297

Closed benjaminaaron closed 8 months ago

benjaminaaron commented 8 months ago

Hi, I am failing to run your README example:

const shexc = "http://shex.io/examples/Issue.shex";
const data = "http://shex.io/examples/Issue1.ttl";
const node = "http://shex.io/examples/Issue1";

const ShExLoader = require("@shexjs/loader");
const { ctor: RdfJsDb } = require('@shexjs/neighborhood-rdfjs')
const {ShExValidator} = require("@shexjs/validator");
ShExLoader.load({shexc: [shexc]}, {turtle: [data]}).then(function (loaded) {
    var db = RdfJsDb(loaded.data);
    var validator = new ShExValidator(loaded.schema, db, { results: "api" });
    var result = validator.validate([{node: node, shape: ShExValidator.Start}]);
    console.log(result);
});

It says there is no method .load on ShExLoader. I am running this using node script.js after having npm install the three dependencies.

ericprud commented 8 months ago

oops, a lagged behind API changes. be back to you in a few mins.

ericprud commented 8 months ago

I haven't fixed the README yet, but here's some code:

const shexc = "http://shex.io/examples/IssueSchema.shex"; // changed to avoid conneg confusions
const data = "http://shex.io/examples/Issue1";            // conneg to Issue1.ttl (or include
const node = "http://shex.io/examples/Issue1#Issue1";     // '.ttl' in node name here)

const N3 = require("n3");
const ShExLoader = require("@shexjs/loader")({            // initialize with
  fetch: require('node-fetch'),                           //   fetch implementation
  rdfjs: N3,                                              //   RdfJs parser
});
const { ctor: RdfJsDb } = require('@shexjs/neighborhood-rdfjs')
const {ShExValidator} = require("@shexjs/validator");
ShExLoader.load({shexc: [shexc]}, {turtle: [data]}).then(function (loaded) {
    var db = RdfJsDb(loaded.data);
    var validator = new ShExValidator(loaded.schema, db, { results: "api" });
                                                          // validateShapeMap or validateNodeShapePair
    var result = validator.validateShapeMap([{node: node, shape: ShExValidator.Start}]);
    console.log(JSON.stringify(result, null, 2));         // dump proof by default
});
benjaminaaron commented 8 months ago

Thanks, this works, much appreciated! Although I had to import node-fetch dynamically with an await for some reason.

Is there a way to not have to specify a node or a ShapeMap and just have it validate the whole file like it is done with SHACL?

ericprud commented 8 months ago

You'd want something you could mix into the schema at run time 'cause embedding target selection into the schema makes it essentially unusable in other contexts. E.g. if I stick a targetNode on a shape and I try to validate some other node with that shape, I get errors on the originally embedded target node; likewise with target classes or nodes with the target class that I don't want to validate with that shape.

You could merge in a graph like:

{ "@context": {
    "node":  { "@id": "http://a.example/node", "@type": "@id"},
    "shape": { "@id": "http://a.example/shape", "@type": "@id"} },
  "node": "http://shex.io/examples/Issue1#Issue1", "shape": "http://shex.io/examples/IssueSchema" }
_:b0 <http://a.example/node> <http://shex.io/examples/Issue1#Issue1> .
_:b0 <http://a.example/shape> <http://shex.io/examples/IssueSchema> .

at run-time, but I don't think it would buy you much 'cause you'd still need the selection of candidate node/shape pairs to be an atomic operation that precedes validation (as it is in SHACL, but the syntax obscures that point).

ericprud commented 8 months ago

BTW, I think the shexc link should elide the extension

const shexc = "http://shex.io/examples/IssueSchema";

to allow conneg to choose between ShExC, ShExJ and ShExR. Added to READsME in 8052bfe7e52f1d20d7c75f28c05fc2c6e5ac8f59 . Feel free to re-open if I closed prematurely.