Hi Andy, Thank you for the reply. I can get your example to work as you indicate, but have some questions:
1) I went through the latest SHACL draft <https://w3c.github.io/data-shapes/shacl/> and I cannot find how to know that sh:targetNode always executes. It’s also not clear to me what it means to execute. I thought that sh:targetNode X was a way to restrict a shape to X in the data graph, whatever X might be. 2) What I’m trying to do is validate that a resource like http://purl.bdrc.io/resource/P707 <http://purl.bdrc.io/resource/P707> is a Person, which at a minimum means that: <http://purl.bdrc.io/resource/P707 <http://purl.bdrc.io/resource/P707>> a <http://purl.bdrc.io/ontology/core/Person <http://purl.bdrc.io/ontology/core/Person>> . is present in the http://purl.bdrc.io/graph/P707 <http://purl.bdrc.io/graph/P707>. The PersonShape <https://github.com/buda-base/editor-templates/blob/master/templates/core/person.shapes.ttl> has: sh:targetClass bdo:Person but that only serves to say that PersonShape only applies to resources of class bdo:Person and if there are none, then there are no violations which means I can try to validate a bibliographic element such as http://purl.bdrc.io/resource/W1FPL1 <http://purl.bdrc.io/resource/W1FPL1> which is of class bdo: ImageInstance but of course that still sh:conforms true since bds:PersonShape doesn’t apply and hence there aren’t any violations. (to see the resources, use http://ldspdi-dev.bdrc.io/resource/W1FPL1.ttl <http://ldspdi-dev.bdrc.io/resource/W1FPL1.ttl>, for example). The use case is: a client submits a graph of a resource and claims it to be a bdo:Person or a subClassOf* it; and we want to validate the graph as a bdo:Person and so want to get the result “false" for bdr:W1FPL1 instead of “true". It’s our intent to use a tool like shacl for this top-level task as well as validating the details liuke having at least one name, a gender, and so on. I tried using something like your example: bds:CheckPersonClassShape a sh:NodeShape ; rdfs:label "Check Person Class Shape"@en ; sh:targetNode "Check Class" ; sh:sparql [ a sh:SPARQLConstraint ; sh:prefixes [ sh:declare [ sh:prefix "rdf" ; sh:namespace "http://www.w3.org/1999/02/22-rdf-syntax-ns#" ; ] , [ sh:prefix "bdo" ; sh:namespace "http://purl.bdrc.io/ontology/core/" ; ] ] ; sh:select """ select $this (rdf:type as ?path) (bdo:Person as ?value) where { filter not exists { $this ?path ?value } } """ ; ] ; . But this just always reports a violation that the literal, “Check Class”, doesn’t conform, which is true since it isn’t in the data graph. 3) The original reason for wanting to use the shacl endpoint was so that we could PUT the submitted graph in the Fuseki dataset and then use the endpoint to validate the resource bdr:P707 (or bdr:W1FPL1) as a Person (or not) with the rest of the dataset graph available to handle things like subClassOf* and subPropertyOf* for various items as well as validating the minimum of resources referenced by P707 such as that P705 is a male person and hence can be a father of P707. The graph for P707 that is submitted would only have references to P705, with no properties on P705, since that resource is in its own graph. I thought this is pretty much how validate(Shapes Graph, Node) would work, where Graph would be the union dataset graph. I’m evidently missing some understanding. I appreciate your patience, Chris > On May 12, 2020, at 3:52 AM, Andy Seaborne <a...@apache.org> wrote: > > Chris, > > Here's a shape that always executes and tests for an empty data graph. > > # No violation > shacl validate -v -shapes ex-shapes.ttl -data not-empty.ttl > > # Violation > shacl validate -v -shapes ex-shapes.ttl -data empty.nt > > "sh:targetNode" always executes. > > With this pattern, the SPARQL query can do arbitrary checks. > > Andy > > ## ex-shapes.ttl > 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#> > > PREFIX ex: <http://example/> > > ex:NotEmptyGraphShape > rdf:type sh:NodeShape ; > sh:targetNode "Empty Graph" ; > sh:sparql [ > a sh:SPARQLConstraint ; > sh:select """ > SELECT $this ?value > WHERE { > FILTER NOT EXISTS { ?s ?p ?o } > } > """ ; > ] . > > On 11/05/2020 17:14, Chris Tomlinson wrote: > >> I appreciate that it works that way but until and unless I can understand >> your point about >> [] sh:targetNode ex:myNode >> then I don’t know how to distinguish: 1) no violations because a Person >> graph conforms to the PersonShapes - like there’s no Work indicated as a >> parent of the person or a rdfs:label is used where a skos:prefLabel is >> expected; versus 2) no violations because the question is vacuous like >> asking if a Work looks like a person or an empty non-existent graph looks >> like a person.