logicrdfshacl

limit SHACL class to one of the specific types and nothing else


Suppose I have data like:

<http://domain/mySubj> abc:someProperty <http://domain/myObj>.
<http://domain/myObj> a <http://domain/Type1>.
<http://domain/myObj> a <http://domain/Type2>.
<http://domain/myObj> a <http://domain/WrongType>.

I want to write a SHACL rule that raise a violation if myObj has any type other that Type1 and Type2.

I have tried to write it like

sh:property [
      a sh:PropertyShape ;
      sh:path abc:someProperty ;
      sh:or   (
                   [ sh:class <http://domain/Type1> ; ]
                   [ sh:class <http://domain/Type2> ; ]
               ) ;
     ...
     

But this will not raise a violation since sh:or will pass as soon as one of the tests are correct. I can't also use sh:xone since this will need only one of Type1 and Type2 and not both, to be present. Even if I try to say sh:or([sh:xone (type1 type2)] [sh:and (type1 type2)]) my test will not produce the correct result since the and test will pass because we have type1 and type2 present and don't care about the Wrongtype.

Is there a way that I can say the class should be one or more things from a specific set of things and not anything else.


Solution

  • If this is about direct rdf:types only, I believe you can solve this using sh:in on the rdf:type of the values:

    sh:property [
        a sh:PropertyShape ;
        sh:path abc:someProperty ;
        sh:property [
            sh:path rdf:type ;
            sh:in ( abc:Type1 abc:Type2 ) ;
        ] ;
    ]