Thanks! I did not understand your tip on sh:path, but the sh:targetNode tip did the trick.

This works:

_:RDFSVocabularyTokenShape a sh:NodeShape ;
  sh:targetNode ex:ANY_NODE ; ## matches any node
  sh:name "RDFS vocabulary element." ;
  sh:message "Unrecognised RDFS vocabulary element. Check spelling." ;
  sh:sparql [ a sh:SPARQLConstraint ;
    sh:select """
      PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
      SELECT ?value
      WHERE { { ?value ?p ?o }
        UNION { ?s ?value ?o }
        UNION { ?s ?p ?value }
FILTER (isIRI(?value) && STRSTARTS(STR(?value), "http://www.w3.org/2000/01/rdf-schema#";)) FILTER (?value NOT IN ( rdfs:Class, rdfs:Container, rdfs:ContainerMembershipProperty, rdfs:Datatype, rdfs:Literal, rdfs:Resource, rdfs:comment, rdfs:domain, rdfs:isDefinedBy, rdfs:label, rdfs:member, rdfs:range, rdfs:seeAlso, rdfs:subClassOf, rdfs:subPropertyOf ) ) } """ ]
.


Validating this input:

  [] rdfs:asdf [] .

gives me this report:

[ a            sh:ValidationReport ;
  sh:conforms  false ;
  sh:result    [ a                             sh:ValidationResult ;
                 sh:focusNode                  ex:ANY_NODE ;
sh:resultMessage "Unrecognised RDFS vocabulary element. Check spelling." ;
                 sh:resultSeverity             sh:Violation ;
sh:sourceConstraintComponent sh:SPARQLConstraintComponent ;
                 sh:sourceShape                []  ;
                 sh:value                      rdfs:asdf
               ]
] .


Martin

On 02/12/2020 11:48, Andy Seaborne wrote:
Hi Martin,

I am guessing this isbecause advanced features (https://www.w3.org/TR/shacl-af) are not supported?

Correct.

A trick ("pattern") is to use sh:targetNode because that always gets triggered, whether the object node is in the data or not and even if the data graph is empty.

---

In this case what might help is sh:path and a long alternative path except that's verbose. For some reason I never understood, the list in sh:alternativePath is only ever a pair so you end up with nesting.

SHACL compact syntax can write it compactly whioch, if nothing else, can be used to generate the RDF ("shacl print --out rdf")

shape ex:shape2 {
  targetNode = :WhatEver .
  ex:A|ex:B|ex:C  datatype=xsd:integer .
  }

     HTH
     Andy

Contributions for adding shacl-af features welcome!

On 02/12/2020 10:16, Martin G. Skjæveland wrote:
Hi all,

using SHACL I am trying to implement a check for identifying typically typos when using standard vocabularies such as RDF, RDFS and OWL, e.g., rdf:label should be rdf*s*:label.

Here is an attempt at finding IRIs in rdfs namespace but that are not defined in the standard vocabulary:

[] a sh:NodeShape ;
   sh:name "RDFS vocabulary element." ;
   sh:message "Unrecognised RDFS vocabulary element. Check spelling." ;
   sh:target [
     a sh:SPARQLTarget ;
     sh:select """
       SELECT ?this
       WHERE { { ?this ?p ?o }
         UNION { ?s ?this ?o }
         UNION { ?s ?p ?this }
       FILTER (isIRI(?this) && STRSTARTS(STR(?this), "http://www.w3.org/2000/01/rdf-schema#";))
      } """ ;
     ] ;
   sh:in ( rdfs:Class rdfs:Container rdfs:ContainerMembershipProperty rdfs:Datatype rdfs:Literal rdfs:Resource rdfs:comment rdfs:domain rdfs:isDefinedBy rdfs:label rdfs:member rdfs:range rdfs:seeAlso rdfs:subClassOf rdfs:subPropertyOf )
.

This does not work with jena-shacl version 3.16. I am guessing this isbecause advanced features (https://www.w3.org/TR/shacl-af) are not supported? https://jena.apache.org/documentation/shacl/ says: "It implements SHACL Core and SHACL SPARQL Constraints."

Is there a different way of selecting all IRIs as target, which is also supported by jena-shacl? Or maybe a better way of doing this?

Thanks!

Martin

Reply via email to