http://example.org/EbomMbom
a owl:Ontology ;
owl:imports http://datashapes.org/dash ;
owl:versionInfo "Created with TopBraid Composer" ;
.
EbomMbom:Engine
a rdfs:Class ;
a sh:NodeShape ;
rdfs:subClassOf rdfs:Resource ;
sh:property [
a sh:PropertyShape ;
sh:path EbomMbom:isConnectedWith ;
sh:class EbomMbom:Fuel_Tank ;
sh:maxCount 2 ;
sh:minCount 2 ;
sh:name "is connected with" ;
sh:nodeKind sh:IRI ;
] ;
.
EbomMbom:Fuel_Tank
a rdfs:Class ;
a sh:NodeShape ;
rdfs:subClassOf rdfs:Resource ;
Basically, my constraint is to say that any instance of my Engine class has to be related to exactly 2 instances of my Fuel_Tank class through the 'isConnectedWith' relationship.
For testing purposes, I created in my graph an 'Engine_1' instance and linked it to 3 Fuel_Tank instances. The constraint is thus violated
When I launch the validation of my graph in Neo4J through the call n10s.validation.shacl.validate query, I get this result :
Actually, nothing went wrong, the thing is the offending value is generally used when the violation comes from a property value (regex, datatype, minvalue...). But because the violation you're finding has to do with the cardinality of a relationship (MaxCountConstraintComponent), the offending value field is left as null.
But instead, you have the following elements to make sense of the constraint violation:
The resultMessage field with a description of the problem: "unnacceptable cardinality: 3"`
The nodeType field with the type of the problematic node: "Engine" in our case.
The focus node field, with the id of the problematic node. All you need to do is look it up by id. This cypher can help you:
match (n) where id(n) = 5 return n
In my case, this returns the node representing the Engine that has the three tanks.
Thanks a lot Jesus!
Actually I was missing the 'resultMessage' argument in my n10s.validation.shacl command, now it's much more clear!
Do you think there is a way to return in the same n10s.validation query the label of the focus Node (focusNode.label doesn't work) ?
M. Zemmama
Great to hear that helped, Mehdi
Maybe I should reorder the fields so that the more relevant are immediately obvious...
Not sure I understand what you mean. I think the nodeType field is exactly that, isn't it?
I see that you're getting the focusNode = 44 and the nodeType= Engine
Thanks for your reply Jesus. Actually here, 'Engine' is the class to which the focusNode 44 (which is an instance/NamedIndividual) belongs. My question was if we could display in the grid the label of this instance/NamedIndividual and not just its Id ?
That is a very good point: How to identify the focus node.
When the instance data is imported from RDF it shows the uri which is an unambiguous global identifier but when it's not RDF data the only element that's always there is the internal id. But you're right, probably something more descriptive would be better/more user friendly.