1

I'm looking to make some SHACL shapes for certain properties in my ontology that have a speicified unit. Example:

My instance data would look something like this:

otlc:surgeprotector_1
  rdf:type otlc:Surgeprotector ;
  otlc:Nominal_voltage[
      rdf:type otlc:QuantityValue ;
      rdf:value "225"^^xsd:float ;
      otlc:hasUnit unit:KiloV ;
    ] ;
.

I then have some shapes to validate this data:

otlc:Nominal_voltageShape
  rdf:type sh:PropertyShape ;
  sh:path otlc:Nominal_voltage ;
  sh:class otlc:QuantityValue ;
  **otlc:hasUnit unit:KiloV ;**
  sh:maxCount 1 ;
  sh:minCount 1 ;
.

otlc:SurgeprotectorShape
  rdf:type sh:NodeShape ;
  sh:property otlc:Nominal_voltageShape ;
  sh:targetClass otlc:Surgeprotector ;
.

My question: How can I specify the unit given for the predicate "otlc:hasUnit" in the instance data for each property in my ontology? My desired end result is to have a nodeshape for the surgeprotector, and a propertyshape for the property "nominal_voltage", to restrict the value for nominal_voltage to unit:KiloV. I'm hoping there is some kind of shacl keyword I had not heard of/realized I can use here, to add onto my propertyshape (right now, i put in what I would imagine exists for shacl in **). (for example, sh:pattern can be used to specify the value with regex, but I want to specify the value of a piece of metadata of my value, if that makes sense...)

Thanks in advance! Robin

Robin
  • 135
  • 10

1 Answers1

2

I believe you can replace your highlighted line with

sh:property [
    sh:path otlc:hasUnit ;
    sh:hasValue unit:KiloV ;
] ;

This would mean that this property shape must apply to all values of the surrounding property shape, i.e. all values of otlc:Nominal_voltage.

Alternative, you could use a path expression in a property shape one level higher up, e.g.

otlc:SurgeprotectorShape
    ...
    sh:property [
        sh:path ( otlc:Nominal_voltage otlc:hasUnit ) ;
        sh:hasValue unit:KiloV ;
    ] ;

Note that sh:hasValue also implies sh:minCount 1, i.e. the value must be present. You may want to add sh:maxCount 1 as extra protection.

Holger Knublauch
  • 1,176
  • 5
  • 4
  • Hi Holger, thanks for your answer! The second option works, but for some reason the first option does not render any results when I try to validate a unit that is not KiloV. Perhaps it's something trivial I am not seeing, but my propertyshape now looks as follows: `otlc:Nominale_spanningShape` ` rdf:type sh:NodeShape ;` ` sh:path otlc:Nominal_voltageShape ;` ` sh:class otlc:QuantityValue ;` ` sh:property [` ` sh:path otlc:hasUnit ;` ` sh:hasValue unit:KiloV ;` ` ] ; ` ` .` If I then fill an invalid unit in my instances, I don't get any validation results. – Robin Jul 02 '21 at 08:08
  • The markdown is not really working, but I hope it's still readable! – Robin Jul 02 '21 at 08:11
  • 1
    I found my mistake why the first method was not working: Spelling error on my side. Both answers work. Thank you! – Robin Jul 02 '21 at 09:17