From 8cf0354ef451ec849e781e867ddc9d0af334e376 Mon Sep 17 00:00:00 2001 From: Marco De Salvo Date: Sun, 6 Oct 2024 12:38:13 +0200 Subject: [PATCH] Dev (#343) Remove support for serializing RDF/XML "parseType=Collection" --- RDFSharp.Test/Model/RDFModelUtilitiesTest.cs | 16 +-- .../{RDFXMLTest.cs => RDFXmlTest.cs} | 101 +++++------------- RDFSharp/Model/RDFCollection.cs | 4 +- RDFSharp/Model/RDFModelUtilities.cs | 14 ++- RDFSharp/Model/Serializers/RDFXml.cs | 77 ++----------- 5 files changed, 51 insertions(+), 161 deletions(-) rename RDFSharp.Test/Model/Serializers/{RDFXMLTest.cs => RDFXmlTest.cs} (94%) diff --git a/RDFSharp.Test/Model/RDFModelUtilitiesTest.cs b/RDFSharp.Test/Model/RDFModelUtilitiesTest.cs index 2ffdc6b7..c22c3f6a 100644 --- a/RDFSharp.Test/Model/RDFModelUtilitiesTest.cs +++ b/RDFSharp.Test/Model/RDFModelUtilitiesTest.cs @@ -1223,7 +1223,7 @@ public void ShouldDeserializeSPOCollectionFromGraphExitingOnMissingFirst() } [TestMethod] - public void ShouldDeserializeSPOCollectionFromGraphExitingOnInvalidItemType() + public void ShouldDeserializeSPOMixedCollectionFromGraph() { RDFGraph graph = new RDFGraph( [ @@ -1240,9 +1240,10 @@ public void ShouldDeserializeSPOCollectionFromGraphExitingOnInvalidItemType() RDFCollection coll1 = RDFModelUtilities.DeserializeCollectionFromGraph(graph, new RDFResource("bnode://coll1/"), RDFModelEnums.RDFTripleFlavors.SPO); Assert.IsNotNull(coll1); - Assert.IsTrue(coll1.ItemsCount == 2); + Assert.IsTrue(coll1.ItemsCount == 3); Assert.IsTrue(coll1.Items.Any(x => x.Equals(new RDFResource("http://item1/")))); Assert.IsTrue(coll1.Items.Any(x => x.Equals(new RDFResource("http://item2/")))); + Assert.IsTrue(coll1.Items.Any(x => x.Equals(new RDFPlainLiteral("item3")))); } [TestMethod] @@ -1257,8 +1258,7 @@ public void ShouldDeserializeEmptySPOCollectionFromGraph() RDFCollection coll1 = RDFModelUtilities.DeserializeCollectionFromGraph(graph, new RDFResource("bnode://coll1/"), RDFModelEnums.RDFTripleFlavors.SPO); Assert.IsNotNull(coll1); - Assert.IsTrue(coll1.ItemsCount == 1); - Assert.IsTrue(coll1.Items.Any(x => x.Equals(RDFVocabulary.RDF.NIL))); + Assert.IsTrue(coll1.ItemsCount == 0); } [TestMethod] @@ -1378,7 +1378,7 @@ public void ShouldDeserializeSPLCollectionFromGraphExitingOnMissingFirst() } [TestMethod] - public void ShouldDeserializeSPLCollectionFromGraphExitingOnInvalidItemType() + public void ShouldDeserializeSPLMixedCollectionFromGraph() { RDFGraph graph = new RDFGraph( [ @@ -1395,9 +1395,10 @@ public void ShouldDeserializeSPLCollectionFromGraphExitingOnInvalidItemType() RDFCollection coll1 = RDFModelUtilities.DeserializeCollectionFromGraph(graph, new RDFResource("bnode://coll1/"), RDFModelEnums.RDFTripleFlavors.SPL); Assert.IsNotNull(coll1); - Assert.IsTrue(coll1.ItemsCount == 2); + Assert.IsTrue(coll1.ItemsCount == 3); Assert.IsTrue(coll1.Items.Any(x => x.Equals(new RDFPlainLiteral("item1")))); Assert.IsTrue(coll1.Items.Any(x => x.Equals(new RDFPlainLiteral("item2")))); + Assert.IsTrue(coll1.Items.Any(x => x.Equals(new RDFResource("http://item3/")))); } [TestMethod] @@ -1412,7 +1413,8 @@ public void ShouldDeserializeEmptySPLCollectionFromGraph() RDFCollection coll1 = RDFModelUtilities.DeserializeCollectionFromGraph(graph, new RDFResource("bnode://coll1/"), RDFModelEnums.RDFTripleFlavors.SPL); Assert.IsNotNull(coll1); - Assert.IsTrue(coll1.ItemsCount == 0); } + Assert.IsTrue(coll1.ItemsCount == 0); + } [TestMethod] public void ShouldDetectSPOCollectionFlavorFromGraph() diff --git a/RDFSharp.Test/Model/Serializers/RDFXMLTest.cs b/RDFSharp.Test/Model/Serializers/RDFXmlTest.cs similarity index 94% rename from RDFSharp.Test/Model/Serializers/RDFXMLTest.cs rename to RDFSharp.Test/Model/Serializers/RDFXmlTest.cs index 0ce85804..209b1f81 100644 --- a/RDFSharp.Test/Model/Serializers/RDFXMLTest.cs +++ b/RDFSharp.Test/Model/Serializers/RDFXmlTest.cs @@ -179,21 +179,6 @@ public void ShouldSerializeGraphWithSPBTripleHavingAltContainerOfLiteralsAsObjec Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",8}lit1{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); } - [TestMethod] - public void ShouldSerializeGraphWithSPBTripleHavingBagContainerOfLiteralsAsObject() - { - RDFContainer cont = new RDFContainer(RDFModelEnums.RDFContainerTypes.Bag, RDFModelEnums.RDFItemTypes.Literal); - cont.AddItem(new RDFPlainLiteral("lit1")); - RDFGraph graph = new RDFGraph(); - graph.AddTriple(new RDFTriple(new RDFResource("http://subj/"), new RDFResource("http://pred/pred/"), cont.ReificationSubject)); - graph.AddContainer(cont); - RDFXml.Serialize(graph, Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithSPBTripleHavingBagContainerOfLiteralsAsObject.rdf")); - - Assert.IsTrue(File.Exists(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithSPBTripleHavingBagContainerOfLiteralsAsObject.rdf"))); - string fileContent = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithSPBTripleHavingBagContainerOfLiteralsAsObject.rdf")); - Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",8}lit1{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); - } - [TestMethod] public void ShouldSerializeGraphWithSPBTripleHavingSeqContainerOfLiteralsAsObject() { @@ -214,7 +199,7 @@ public void ShouldSerializeGraphWithSPBTripleHavingCollectionOfResourcesAsObject { RDFCollection coll = new RDFCollection(RDFModelEnums.RDFItemTypes.Resource); coll.AddItem(new RDFResource("http://item1/")); - coll.AddItem(new RDFResource("bnode:item2")); + coll.ReificationSubject = new RDFResource("http://coll/"); RDFGraph graph = new RDFGraph(); graph.AddTriple(new RDFTriple(new RDFResource("http://subj/"), new RDFResource("http://pred/pred/"), coll.ReificationSubject)); graph.AddCollection(coll); @@ -222,7 +207,7 @@ public void ShouldSerializeGraphWithSPBTripleHavingCollectionOfResourcesAsObject Assert.IsTrue(File.Exists(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithSPBTripleHavingCollectionOfResourcesAsObject.rdf"))); string fileContent = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithSPBTripleHavingCollectionOfResourcesAsObject.rdf")); - Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); + Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); } [TestMethod] @@ -258,13 +243,22 @@ public void ShouldSerializeGraphWithSPBTripleHavingCollectionOfLanguagedLiterals } [TestMethod] - public void ShouldThrowExceptionOnSerializingGraphWithSPOTripleBecauseBadFormedCollectionAsObject() + public void ShouldSerializeGraphWithSPBTripleHavingMixedCollectionAsObject() { + RDFCollection coll = new RDFCollection(RDFModelEnums.RDFItemTypes.Resource); + coll.AddItemInternal(new RDFResource("urn:swrl:var#V")); + coll.AddItemInternal(new RDFPlainLiteral("item1")); + coll.AddItemInternal(new RDFResource("http://item2/")); + coll.ReificationSubject = new RDFResource("http://coll/"); RDFGraph graph = new RDFGraph(); - graph.AddTriple(new RDFTriple(new RDFResource("http://subj/"), new RDFResource("http://pred/pred"), new RDFResource("bnode:12345"))); - graph.AddTriple(new RDFTriple(new RDFResource("bnode:12345"), RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.LIST)); - graph.AddTriple(new RDFTriple(new RDFResource("bnode:12345"), RDFVocabulary.RDF.FIRST, new RDFResource("http://item1/"))); - Assert.ThrowsException(() => RDFXml.Serialize(graph, Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldThrowExceptionOnSerializingGraphWithSPOTripleBecauseBadFormedCollectionAsObject.rdf"))); + graph.AddTriple(new RDFTriple(new RDFResource("http://subj/"), new RDFResource("http://pred/pred/"), coll.ReificationSubject)); + graph.AddCollection(coll); + RDFXml.Serialize(graph, Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithSPBTripleHavingMixedCollectionAsObject.rdf")); + + Assert.IsTrue(File.Exists(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithSPBTripleHavingMixedCollectionAsObject.rdf"))); + string fileContent = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithSPBTripleHavingMixedCollectionAsObject.rdf")); + Assert.IsNotNull(fileContent); + Assert.IsTrue(!fileContent.Contains("rdf:parseType")); } [TestMethod] @@ -654,29 +648,25 @@ public void ShouldSerializeGraphWithFloatingCollectionOfResources() { RDFCollection coll = new RDFCollection(RDFModelEnums.RDFItemTypes.Resource); coll.AddItem(new RDFResource("http://item1/")); - coll.AddItem(new RDFResource("http://item2/")); - coll.AddItem(new RDFResource("http://item3/")); coll.ReificationSubject = new RDFResource("bnode:12345"); RDFXml.Serialize(coll.ReifyCollection(), Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfResources.rdf")); Assert.IsTrue(File.Exists(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfResources.rdf"))); string fileContent = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfResources.rdf")); - Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); + Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); } [TestMethod] - public void ShouldSerializeGraphWithFloatingCollectionOfBlankResources() + public void ShouldSerializeGraphWithFloatingCollectionOfLiterals() { - RDFCollection coll = new RDFCollection(RDFModelEnums.RDFItemTypes.Resource); - coll.AddItem(new RDFResource("bnode:item1")); - coll.AddItem(new RDFResource("bnode:item2")); - coll.AddItem(new RDFResource("bnode:item3")); + RDFCollection coll = new RDFCollection(RDFModelEnums.RDFItemTypes.Literal); + coll.AddItem(new RDFPlainLiteral("item1","en--rtl")); coll.ReificationSubject = new RDFResource("bnode:12345"); - RDFXml.Serialize(coll.ReifyCollection(), Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfBlankResources.rdf")); + RDFXml.Serialize(coll.ReifyCollection(), Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfLiterals.rdf")); - Assert.IsTrue(File.Exists(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfBlankResources.rdf"))); - string fileContent = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfBlankResources.rdf")); - Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); + Assert.IsTrue(File.Exists(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfLiterals.rdf"))); + string fileContent = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfLiterals.rdf")); + Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}item1{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); } [TestMethod] @@ -685,14 +675,10 @@ public void ShouldSerializeGraphWithBothFloatingAndNonFloatingCollectionsOfResou RDFGraph graph = new RDFGraph(); RDFCollection coll = new RDFCollection(RDFModelEnums.RDFItemTypes.Resource); coll.AddItem(new RDFResource("http://item1/")); - coll.AddItem(new RDFResource("http://item2/")); - coll.AddItem(new RDFResource("http://item3/")); coll.ReificationSubject = new RDFResource("bnode:12345"); graph.AddCollection(coll); RDFCollection coll2 = new RDFCollection(RDFModelEnums.RDFItemTypes.Resource); coll2.AddItem(new RDFResource("http://item1/")); - coll2.AddItem(new RDFResource("http://item2/")); - coll2.AddItem(new RDFResource("http://item3/")); coll2.ReificationSubject = new RDFResource("bnode:54321"); graph.AddCollection(coll2); graph.AddTriple(new RDFTriple(new RDFResource("http://subj/"), new RDFResource("http://pred/pred"), coll2.ReificationSubject)); @@ -700,44 +686,7 @@ public void ShouldSerializeGraphWithBothFloatingAndNonFloatingCollectionsOfResou Assert.IsTrue(File.Exists(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithBothFloatingAndNonFloatingCollectionsOfResources.rdf"))); string fileContent = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithBothFloatingAndNonFloatingCollectionsOfResources.rdf")); - Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); - } - - [TestMethod] - public void ShouldSerializeGraphWithBothFloatingAndNonFloatingCollectionsOfBlankResources() - { - RDFGraph graph = new RDFGraph(); - RDFCollection coll = new RDFCollection(RDFModelEnums.RDFItemTypes.Resource); - coll.AddItem(new RDFResource("bnode:item1")); - coll.AddItem(new RDFResource("bnode:item2")); - coll.AddItem(new RDFResource("bnode:item3")); - coll.ReificationSubject = new RDFResource("bnode:12345"); - graph.AddCollection(coll); - RDFCollection coll2 = new RDFCollection(RDFModelEnums.RDFItemTypes.Resource); - coll2.AddItem(new RDFResource("bnode:item1")); - coll2.AddItem(new RDFResource("bnode:item2")); - coll2.AddItem(new RDFResource("bnode:item3")); - coll2.ReificationSubject = new RDFResource("bnode:54321"); - graph.AddCollection(coll2); - graph.AddTriple(new RDFTriple(new RDFResource("http://subj/"), new RDFResource("http://pred/pred"), coll2.ReificationSubject)); - RDFXml.Serialize(graph, Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithBothFloatingAndNonFloatingCollectionsOfBlankResources.rdf")); - - Assert.IsTrue(File.Exists(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithBothFloatingAndNonFloatingCollectionsOfBlankResources.rdf"))); - string fileContent = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithBothFloatingAndNonFloatingCollectionsOfBlankResources.rdf")); - Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",6}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); - } - - [TestMethod] - public void ShouldSerializeGraphWithFloatingCollectionOfLiterals() - { - RDFCollection coll = new RDFCollection(RDFModelEnums.RDFItemTypes.Literal); - coll.AddItem(new RDFPlainLiteral("item1","en--rtl")); - coll.ReificationSubject = new RDFResource("bnode:12345"); - RDFXml.Serialize(coll.ReifyCollection(), Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfLiterals.rdf")); - - Assert.IsTrue(File.Exists(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfLiterals.rdf"))); - string fileContent = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"RDFXmlTest_ShouldSerializeGraphWithFloatingCollectionOfLiterals.rdf")); - Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}item1{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); + Assert.IsTrue(fileContent.Equals($"{XmlHeader}{Environment.NewLine}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",2}{Environment.NewLine}{" ",4}{Environment.NewLine}{" ",2}{Environment.NewLine}")); } [TestMethod] diff --git a/RDFSharp/Model/RDFCollection.cs b/RDFSharp/Model/RDFCollection.cs index 3d6d92ce..bc9647b3 100644 --- a/RDFSharp/Model/RDFCollection.cs +++ b/RDFSharp/Model/RDFCollection.cs @@ -198,8 +198,8 @@ public RDFGraph ReifyCollection() reifColl.AddTriple(new RDFTriple(reifSubj, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.LIST)); // Subject -> rdf:first -> RDFCollection.ITEM[i] - if (ItemType == RDFModelEnums.RDFItemTypes.Resource) - reifColl.AddTriple(new RDFTriple(reifSubj, RDFVocabulary.RDF.FIRST, (RDFResource)collectionItem)); + if (collectionItem is RDFResource collectionItemRes) + reifColl.AddTriple(new RDFTriple(reifSubj, RDFVocabulary.RDF.FIRST, collectionItemRes)); else reifColl.AddTriple(new RDFTriple(reifSubj, RDFVocabulary.RDF.FIRST, (RDFLiteral)collectionItem)); diff --git a/RDFSharp/Model/RDFModelUtilities.cs b/RDFSharp/Model/RDFModelUtilities.cs index 2e553ee8..b7897dd5 100644 --- a/RDFSharp/Model/RDFModelUtilities.cs +++ b/RDFSharp/Model/RDFModelUtilities.cs @@ -431,12 +431,16 @@ internal static RDFCollection DeserializeCollectionFromGraph(RDFGraph graph, RDF { #region rdf:first RDFTriple first = rdfFirst[itemRest, null, null, null].FirstOrDefault(); - if (first != null && first.TripleFlavor == expectedFlavor) + if (first != null) { - if (expectedFlavor == RDFModelEnums.RDFTripleFlavors.SPO) - collection.AddItem((RDFResource)first.Object); + if (first.Object is RDFResource firstObjRes) + { + //Avoid rdf:nil to be collected... + if (!firstObjRes.Equals(RDFVocabulary.RDF.NIL)) + collection.AddItemInternal(firstObjRes); + } else - collection.AddItem((RDFLiteral)first.Object); + collection.AddItemInternal((RDFLiteral)first.Object); } else nilFound = true; @@ -446,7 +450,7 @@ internal static RDFCollection DeserializeCollectionFromGraph(RDFGraph graph, RDF //Ensure considering exit signal from bad-formed rdf:first if (!nilFound) { - RDFTriple rest = rdfRest.SelectTriplesBySubject(itemRest).FirstOrDefault(); + RDFTriple rest = rdfRest[itemRest, null, null, null].FirstOrDefault(); if (rest != null) { if (rest.Object.Equals(RDFVocabulary.RDF.NIL)) diff --git a/RDFSharp/Model/Serializers/RDFXml.cs b/RDFSharp/Model/Serializers/RDFXml.cs index 52aa41aa..1eea7914 100644 --- a/RDFSharp/Model/Serializers/RDFXml.cs +++ b/RDFSharp/Model/Serializers/RDFXml.cs @@ -99,22 +99,10 @@ internal static void Serialize(RDFGraph graph, Stream outputStream) { ContainerUri = (RDFResource)t.Subject, ContainerType = t.Object.Equals(RDFVocabulary.RDF.ALT) ? RDFModelEnums.RDFContainerTypes.Alt : - t.Object.Equals(RDFVocabulary.RDF.BAG) ? RDFModelEnums.RDFContainerTypes.Bag : - RDFModelEnums.RDFContainerTypes.Seq, + t.Object.Equals(RDFVocabulary.RDF.BAG) ? RDFModelEnums.RDFContainerTypes.Bag : + RDFModelEnums.RDFContainerTypes.Seq, IsFloatingContainer = !graph.IndexedTriples.Any(v => v.Value.ObjectID.Equals(t.Subject.PatternMemberID)) }).ToList(); - - //Fetch data describing collections of the graph - var collections = rdfType.SelectTriplesByObject(RDFVocabulary.RDF.LIST) - .Select(t => new - { - CollectionUri = (RDFResource)t.Subject, - CollectionValue = rdfFirst.SelectTriplesBySubject((RDFResource)t.Subject) - .FirstOrDefault()?.Object, - CollectionNext = rdfRest.SelectTriplesBySubject((RDFResource)t.Subject) - .FirstOrDefault()?.Object, - IsFloatingCollection = !graph.IndexedTriples.Any(v => v.Value.ObjectID.Equals(t.Subject.PatternMemberID)) - }).ToList(); #endregion #region linq @@ -125,7 +113,7 @@ internal static void Serialize(RDFGraph graph, Stream outputStream) #region graph //Iterate over the calculated groups - foreach (var triplesGroup in triplesGroupedBySubject) + foreach (IGrouping triplesGroup in triplesGroupedBySubject) { #region subject //Check if the current subject is a container/collection and it is not floating: if so, @@ -134,7 +122,6 @@ internal static void Serialize(RDFGraph graph, Stream outputStream) string subj = triplesGroup.Key; long subjHash = RDFModelUtilities.CreateHash(subj); var subjContainer = containers.Find(x => x.ContainerUri.PatternMemberID == subjHash); - var subjCollection = collections.Find(x => x.CollectionUri.PatternMemberID == subjHash); //It is a container subject and it is not floating => add it to the containersXML pool if (subjContainer != null && !subjContainer.IsFloatingContainer) @@ -153,11 +140,6 @@ internal static void Serialize(RDFGraph graph, Stream outputStream) } containersXML.Add(subjHash, subjNode); } - - //It is a collection subject of resources and it is not floating => do not append its triples because - //we will reconstruct the collection later and append it as "rdf:parseType=Collections" - else if (subjCollection != null && subjCollection.CollectionValue is RDFResource && !subjCollection.IsFloatingCollection) - continue; //It is a traditional subject else @@ -190,7 +172,7 @@ internal static void Serialize(RDFGraph graph, Stream outputStream) if (!(triple.Predicate.Equals(RDFVocabulary.RDF.TYPE) && (subjNode.Name.Equals("rdf:Bag", StringComparison.OrdinalIgnoreCase) || subjNode.Name.Equals("rdf:Seq", StringComparison.OrdinalIgnoreCase) - || subjNode.Name.Equals("rdf:Alt", StringComparison.OrdinalIgnoreCase)))) + || subjNode.Name.Equals("rdf:Alt", StringComparison.OrdinalIgnoreCase)))) { #region predicate string predString = triple.Predicate.ToString(); @@ -216,57 +198,10 @@ internal static void Serialize(RDFGraph graph, Stream outputStream) if (triple.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO) { var containerObj = containers.Find(x => x.ContainerUri.Equals(triple.Object)); - var collectionObj = collections.Find(x => x.CollectionUri.Equals(triple.Object)); //Object is a container subject and it is not floating => append its node saved in containersXML if (containerObj != null && !containerObj.IsFloatingContainer) predNode.AppendChild(containersXML[containerObj.ContainerUri.PatternMemberID]); - - //Object is a collection subject of resources and it is not floating => append its "rdf:parseType=Collection" representation - else if (collectionObj != null && collectionObj.CollectionValue is RDFResource && !collectionObj.IsFloatingCollection) - { - //Append "rdf:parseType=Collection" attribute - XmlAttribute rdfParseType = rdfDoc.CreateAttribute("rdf:parseType", RDFVocabulary.RDF.BASE_URI); - XmlText rdfParseTypeText = rdfDoc.CreateTextNode("Collection"); - rdfParseType.AppendChild(rdfParseTypeText); - predNode.Attributes.Append(rdfParseType); - - //Append "rdf:parseType=Collection" elements - bool nilFound = false; - RDFResource currentCollItem = (RDFResource)triple.Object; - List collElements = new List(); - XmlNode collElementToAppend = null; - XmlAttribute collElementAttr = null; - XmlText collElementAttrText = null; - while (!nilFound) - { - var collElement = collections.Find(x => x.CollectionUri.Equals(currentCollItem)); - if (collElement == null || collElement.CollectionValue == null || collElement.CollectionNext == null) - throw new RDFModelException(string.Format("Collection having '{0}' as subject is not well-formed. Please check presence of its 'rdf:type/rdf:first/rdf:rest' triples.", currentCollItem)); - - collElementToAppend = rdfDoc.CreateNode(XmlNodeType.Element, "rdf:Description", RDFVocabulary.RDF.BASE_URI); - if (collElement.CollectionValue.ToString().StartsWith("bnode:", StringComparison.Ordinal)) - { - collElementAttrText = rdfDoc.CreateTextNode(collElement.CollectionValue.ToString().Replace("bnode:", string.Empty)); - collElementAttr = rdfDoc.CreateAttribute("rdf:nodeID", RDFVocabulary.RDF.BASE_URI); - } - else - { - collElementAttrText = rdfDoc.CreateTextNode(collElement.CollectionValue.ToString()); - collElementAttr = rdfDoc.CreateAttribute("rdf:about", RDFVocabulary.RDF.BASE_URI); - } - collElementAttr.AppendChild(collElementAttrText); - collElementToAppend.Attributes.Append(collElementAttr); - collElements.Add(collElementToAppend); - - //Verify if this is the last element of the collection (pointing to next="rdf:nil") - if (collElement.CollectionNext.Equals(RDFVocabulary.RDF.NIL)) - nilFound = true; - else - currentCollItem = (RDFResource)collElement.CollectionNext; - } - collElements.ForEach(c => predNode.AppendChild(c)); - } //Object is traditional else @@ -334,8 +269,8 @@ internal static void Serialize(RDFGraph graph, Stream outputStream) //Raw containers must not be written as-is, instead they have to be saved //and attached whenever their subject is found as object of a triple if (!subjNode.Name.Equals("rdf:Bag", StringComparison.OrdinalIgnoreCase) - && !subjNode.Name.Equals("rdf:Seq", StringComparison.OrdinalIgnoreCase) - && !subjNode.Name.Equals("rdf:Alt", StringComparison.OrdinalIgnoreCase)) + && !subjNode.Name.Equals("rdf:Seq", StringComparison.OrdinalIgnoreCase) + && !subjNode.Name.Equals("rdf:Alt", StringComparison.OrdinalIgnoreCase)) { rdfRoot.AppendChild(subjNode); }