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