SHACL - Attribute is optional, but if it exists, it has to have once a specific value

268 Views Asked by At

a class has an optional attribute. If you use this attribute, you have to set it once to a specific value. All other uses of this attribute are not restricted.

The real world example is dcat:themeTaxonomy used in dcat:Catalog in DCAT-AP. If used, it has to be set to <http://publications.europa.eu/resource/authority/data-theme> but the cardinality is *, so you are allowed to use other values.

Other use-cases would be a language skills. You have to state you overall skill-level, but when you do, you can add hearing, speaking or reading skills.

I am trying to check this constraint with SHACL.

The basic idea is: I have a property shape with the path to the attribute. There I use sh:or. Either the sh:maxCount is 0 or the sh:minCount is 1. In the second case a sh:qualifiedValueShape would check the additional conditions:

Shapes

(omitted urls to not look like spam)

ex:valueIfExists
    sh:message "Custom message for ex:valueIfExists!" ;
    sh:path ex:optionalValue ;

    sh:or ( [
            sh:maxCount 0;
        ] [
            sh:minCount 1;
            sh:qualifiedValueShape [
                sh:path ex:is ;
                sh:hasValue "ok" ;
            ] ;
            sh:qualifiedMinCount 1 ;
        ] ) ;
.

ex:mainShape
    a sh:NodeShape ;
    sh:targetClass ex:TestClass ;
    sh:message "Custom message in mainShape!" ;

    sh:property ex:valueIfExists;
.

Test data

(omitted urls to not look like spam)

ex:Test_OK_nothing
    a ex:TestClass ;
.

ex:Test_OK_1
    a ex:TestClass ;
    ex:optionalValue [ex:is "ok"] ;
.

ex:Test_OK_1_2
    a ex:TestClass ;
    ex:optionalValue [ex:is "ok"] ;
    ex:optionalValue [ex:is "other 1"] ;
    ex:optionalValue [ex:is "other 2"] ;
.

ex:Test_Not_OK
    a ex:TestClass ;
    ex:optionalValue [ex:is "other 1"] ;
    ex:optionalValue [ex:is "other 2"] ;
.

With this setup I get the following error:

VALIDATION FAILURE: Cannot find validator for constraint component http://www.w3.org/ns/shacl#MaxCountConstraintComponent

so SHACL doesn't want me to use min and maxCount at this position. Fine, I am not fixated on that, but I have no idea left on how to solve the problem.

Has anyone a solution?

1

There are 1 best solutions below

0
On

This problem is related to a common confusion about the usage of sh:or. According to the specification sh:or provides a list of shapes to validate the value nodes against, i.e., it cannot be applied to one of the property shapes of the value nodes. Property shapes are limited to at most one value for sh:path.

In order to define the constraint in question, we should instead consider the sh:or as part of the mainShape and provide the list of acceptable property shapes there. For example:


ex:valueIfExists
    sh:message "Custom message for ex:valueIfExists!" ;
    sh:path ex:optionalValue ;
    sh:minCount 1 ;
    sh:qualifiedValueShape [
        sh:path ex:is ;
        sh:hasValue "ok" ;
    ] ;
    sh:qualifiedMinCount 1 ;
.

ex:valueIfNotExists
    sh:message "Custom message for ex:valueIfNotExists!" ;
    sh:path ex:optionalValue ;
    sh:maxCount 0 ;
.

ex:mainShape
    a sh:NodeShape ;
    sh:targetClass ex:TestClass ;
    sh:message "Custom message in mainShape!" ;

    sh:or (
        [ sh:property ex:valueIfExists ]
        [ sh:property ex:valueIfNotExists ]
    )
.