Skip to content

Commit

Permalink
Finalize bugfix code for #307
Browse files Browse the repository at this point in the history
  • Loading branch information
mdesalvo committed Jul 12, 2023
1 parent dcbab88 commit 2dcd0ad
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 11 deletions.
82 changes: 81 additions & 1 deletion RDFSharp.Test/Model/Validation/RDFValidationEngineTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,87 @@ public void ShouldWorkWithRDFXMLDeserializationOfID()
</exns:Child>
<exns:Parent rdf:ID=""parent0"" />
<exns:Parent rdf:ID=""#parent1"" /> <!--Force this value to start with '#' in order to test the new code for bugfix-->
<exns:Parent rdf:ID=""#parent1"" />
</rdf:RDF>";
MemoryStream dataStream = new MemoryStream();
using (StreamWriter dataStreamWriter = new StreamWriter(dataStream))
dataStreamWriter.WriteLine(graphData);
RDFGraph dataGraph = RDFXml.Deserialize(new MemoryStream(dataStream.ToArray()), null);

//Validate
RDFValidationReport validationReport = shapesGraph.Validate(dataGraph);

Assert.IsFalse(validationReport.Conforms);
Assert.IsTrue(validationReport.ResultsCount == 1);
Assert.IsTrue(validationReport.Results[0].Severity == RDFValidationEnums.RDFShapeSeverity.Violation);
Assert.IsTrue(validationReport.Results[0].ResultMessages.Count == 1);
Assert.IsTrue(validationReport.Results[0].ResultMessages[0].Equals(new RDFPlainLiteral("Cardinality violation. Lower bound shall be 1. exns:Parent.Child-cardinality")));
Assert.IsTrue(validationReport.Results[0].FocusNode.Equals(new RDFResource("http://test.com/#parent1")));
Assert.IsNull(validationReport.Results[0].ResultValue);
Assert.IsTrue(validationReport.Results[0].ResultPath.Equals(new RDFResource("http://ex.com/ns#Child.Parent")));
Assert.IsTrue(validationReport.Results[0].SourceConstraintComponent.Equals(RDFVocabulary.SHACL.MIN_COUNT_CONSTRAINT_COMPONENT));
Assert.IsTrue(validationReport.Results[0].SourceShape.Equals(new RDFResource("http://ex.com/ns#Parent.Child-cardinality")));
}
[TestMethod]
public void ShouldWorkWithRDFXMLDeserializationOfID2()
{
//ShapesGraph
string shapesData =
@"
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix exns: <http://ex.com/ns#> .
exns:Parent rdf:type sh:NodeShape ;
sh:property exns:Parent.Child-cardinality ;
sh:targetClass exns:Parent .
exns:Child rdf:type sh:NodeShape ;
sh:property exns:Child.Parent-cardinality ;
sh:targetClass exns:Child .
exns:Parent.Child-cardinality
rdf:type sh:PropertyShape ;
sh:description ""This constraint validates the cardinality of the association at the inverse direction."" ;
sh:group exns:CardinalityGroup ;
sh:message ""Cardinality violation. Lower bound shall be 1. exns:Parent.Child-cardinality"" ;
sh:minCount 1 ;
sh:name ""Parent.Child-cardinality"" ;
sh:order 0 ;
sh:path [ sh:inversePath exns:Child.Parent ] ;
sh:severity sh:Violation .
exns:Child.Parent-cardinality
rdf:type sh:PropertyShape ;
sh:description ""This constraint validates the cardinality of the association at the inverse direction."" ;
sh:group exns:CardinalityGroup ;
sh:message ""Cardinality violation. A child should have at least one parent. exns:Parent.Child-cardinality"" ;
sh:minCount 1 ;
sh:name ""Parent.Child-cardinality"" ;
sh:order 0 ;
sh:path exns:Child.Parent ;
sh:severity sh:Violation .";
MemoryStream shapeStream = new MemoryStream();
using (StreamWriter shapeStreamWriter = new StreamWriter(shapeStream))
shapeStreamWriter.WriteLine(shapesData);
RDFGraph shapesGraphObject = RDFTurtle.Deserialize(new MemoryStream(shapeStream.ToArray()), null);
RDFShapesGraph shapesGraph = RDFShapesGraph.FromRDFGraph(shapesGraphObject);

//DataGraph
string graphData =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<rdf:RDF
xml:base=""http://test.com/#""
xmlns:rdf=""http://www.w3.org/1999/02/22-rdf-syntax-ns#""
xmlns:exns=""http://ex.com/ns#""
>
<exns:Child rdf:ID=""child"">
<exns:Child.Parent rdf:resource=""#parent0"" />
</exns:Child>
<exns:Parent rdf:ID=""parent0"" />
<exns:Parent rdf:ID=""#parent1"" />
</rdf:RDF>";
MemoryStream dataStream = new MemoryStream();
using (StreamWriter dataStreamWriter = new StreamWriter(dataStream))
Expand Down
2 changes: 1 addition & 1 deletion RDFSharp.Test/RDFSharp.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<AssemblyTitle>RDFSharp.Test</AssemblyTitle>
<AssemblyName>RDFSharp.Test</AssemblyName>
<AssemblyVersion>$(Version)</AssemblyVersion>
<Version>3.6.0</Version>
<Version>3.6.1</Version>
<Authors>Marco De Salvo</Authors>
<Copyright>Marco De Salvo</Copyright>
<TargetFramework>net6.0</TargetFramework>
Expand Down
19 changes: 11 additions & 8 deletions RDFSharp/Model/Serializers/RDFXml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -821,34 +821,37 @@ private static string ResolveRelativeNode(XmlAttribute attr, Uri xmlBase)
if (attr != null && xmlBase != null)
{
string attrValue = attr.Value;
string xmlBaseString = xmlBase.ToString();

//Adjust corner case for clashes on namespace ending characters ("#", "/")
if (xmlBase.ToString().EndsWith("#") && attrValue.StartsWith("#"))
attrValue = string.Join(string.Empty, attrValue.SkipWhile(c => c == '#'));
if (xmlBase.ToString().EndsWith("/") && attrValue.StartsWith("/"))
attrValue = string.Join(string.Empty, attrValue.SkipWhile(c => c == '/'));
if (xmlBaseString.EndsWith("#") && attrValue.StartsWith("#"))
attrValue = attrValue.TrimStart('#');
if (xmlBaseString.EndsWith("/") && attrValue.StartsWith("/"))
attrValue = attrValue.TrimStart('/');

//"rdf:ID" relative Uri: must be resolved against the xmlBase namespace
if (attr.LocalName.Equals("rdf:ID", StringComparison.OrdinalIgnoreCase)
|| attr.LocalName.Equals("ID", StringComparison.OrdinalIgnoreCase))
|| attr.LocalName.Equals("ID", StringComparison.OrdinalIgnoreCase))
{
//This kind of syntax requires the attribute value to start with "#"
if (!attrValue.StartsWith("#"))
attrValue = string.Concat("#", attrValue);
attrValue = RDFModelUtilities.GetUriFromString(string.Concat(xmlBase, attrValue)).ToString();
if (xmlBaseString.EndsWith("#"))
xmlBaseString = xmlBaseString.TrimEnd('#');
attrValue = RDFModelUtilities.GetUriFromString(string.Concat(xmlBaseString, attrValue)).ToString();
}

//"rdf:nodeID" relative Uri: must be resolved against the "bnode:" prefix
else if (attr.LocalName.Equals("rdf:nodeID", StringComparison.OrdinalIgnoreCase)
|| attr.LocalName.Equals("nodeID", StringComparison.OrdinalIgnoreCase))
|| attr.LocalName.Equals("nodeID", StringComparison.OrdinalIgnoreCase))
{
if (!attrValue.StartsWith("bnode:"))
attrValue = string.Concat("bnode:", attrValue);
}

//"rdf:about" or "rdf:resource" relative Uri: must be resolved against the xmlBase namespace
else if (RDFModelUtilities.GetUriFromString(attrValue) == null)
attrValue = RDFModelUtilities.GetUriFromString(string.Concat(xmlBase, attrValue)).ToString();
attrValue = RDFModelUtilities.GetUriFromString(string.Concat(xmlBaseString, attrValue)).ToString();

return attrValue;
}
Expand Down
2 changes: 1 addition & 1 deletion RDFSharp/RDFSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<AssemblyTitle>RDFSharp</AssemblyTitle>
<AssemblyName>RDFSharp</AssemblyName>
<AssemblyVersion>$(Version)</AssemblyVersion>
<Version>3.6.0</Version>
<Version>3.6.1</Version>
<Authors>Marco De Salvo</Authors>
<Copyright>Marco De Salvo</Copyright>
<Description>Lightweight and friendly .NET library for realizing Semantic Web applications</Description>
Expand Down

0 comments on commit 2dcd0ad

Please sign in to comment.