[BUG] Validation of `sh:path` with `sh:alternativePath` not working per the SHACL spec
Pingviinituutti opened this issue · 4 comments
Describe the bug
It seems that sh:alternativePath
is not working according to the SHACL spec.
Expected behavior
Link to SHACL Playground
sh:alternativePath
should basically be an or to check that either one (or both) of the given paths should exist. So in this case for a ex:Person
with sh:path [ sh:alternativePath ( ex:Person.mobilePhone ex:Person.landLine ) ]
, either the path ex:Person.MobilePhone
or the path ex:Person.landLine
should be given.
The issue is that RDFSharp triggers an sh:Violation
for every a person with or without the any of the given paths.
Library Version
RDFSharp version '3.5.0'
Additional context
Minimal working example:
# SHACL_constraints_person.ttl
@prefix ex: <http://example.com/ns#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
ex:Person rdf:type sh:NodeShape ;
sh:property ex:Person.mobile-landline-cardinality ;
sh:targetClass ex:Person .
ex:Person.mobile-landline-cardinality
rdf:type sh:PropertyShape ;
sh:description "This constraint validates that a Person has either mobileNumber or landLine set." ;
sh:minCount 1 ;
sh:message "Either mobileNumber or landLine should be present" ;
sh:name "Person.mobileNumber-landLine-cardinality" ;
sh:order 0 ;
sh:path [ sh:alternativePath ( ex:Person.mobilePhone ex:Person.landLine ) ] ;
sh:severity sh:Violation .
<!-- person.xml -->
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ex="http://example.com/ns#"
>
<ex:Person rdf:about="http://example.com/ns#person0">
<ex:Person.mobilePhone>0123456789</ex:Person.mobilePhone>
</ex:Person>
<ex:Person rdf:about="http://example.com/ns#person1">
<ex:Person.landLine>0123456789</ex:Person.landLine>
</ex:Person>
<ex:Person rdf:about="http://example.com/ns#person2">
<ex:Person.mobilePhone>0123456789</ex:Person.mobilePhone>
<ex:Person.landLine>0123456789</ex:Person.landLine>
</ex:Person>
<ex:Person rdf:about="http://example.com/ns#person3">
</ex:Person>
</rdf:RDF>
// Program.cs
using RDFSharp.Model;
using System;
using System.Text;
string shapesValidationFilePath = "SHACL_constraints_person.ttl";
string dataFilePath = "person.xml";
try
{
RDFGraph dataGraph = RDFGraph.FromFile(RDFModelEnums.RDFFormats.RdfXml, dataFilePath);
RDFGraph shapesGraphObject = RDFGraph.FromFile(
RDFModelEnums.RDFFormats.Turtle,
shapesValidationFilePath
);
RDFShapesGraph shapesGraphValidation = RDFShapesGraph.FromRDFGraph(shapesGraphObject);
//validate
StringBuilder sb = new StringBuilder();
RDFValidationReport validationResults = shapesGraphValidation.Validate(dataGraph);
if (!validationResults.Conforms)
{
foreach (RDFValidationResult result in validationResults)
{
foreach (RDFLiteral resultMessage in result.ResultMessages)
{
sb.AppendLine(result.ResultPath.URI.Fragment + " " + resultMessage.ToString() + ". ID: " + result.FocusNode.ToString());
}
}
Console.WriteLine("RDFSharp Validation errors:");
string errors = sb.ToString();
Console.WriteLine(errors);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Results:
RDFSharp Validation errors:
Either mobileNumber or landLine should be present. ID: http://example.com/ns#person0
Either mobileNumber or landLine should be present. ID: http://example.com/ns#person1
Either mobileNumber or landLine should be present. ID: http://example.com/ns#person2
Either mobileNumber or landLine should be present. ID: http://example.com/ns#person3
Expected: only person3
should throw an sh:Violation
.
Hi Henrik,
thanks for the report (precise as usual).
I'm working on this to add support for "sh:alternativePath" syntax and will let you know here the progress.
Regards,
Marco
Hi Henrik,
I merged the work for proper detection and handling of "sh:path" declared with "sh:alternativePath", which should allow you to successfully deal with this use case. It was my glitch (again) to not know this kind of syntax.
Expect a new release containing also this feature in the next days.
Thanks again and regards,
Marco
Hi Marco!
No problems here! Thanks a bunch for adding the fix :)
Best regards,
Henrik
I'm also adding "sh:path (prop1 prop2)" which I saw is the sequential form of paths.
Other variants can't be supported (like the ones stating cardinality with "+" or "*") because unfortunately our algebra is not capable of computing them neither in SPARQL. But, at least, with your support our SHACL engine has improved nicely :)
Thanks and regards,
Marco