From c6eb4e921a2626094276c2dad86159285049dd13 Mon Sep 17 00:00:00 2001 From: lycilph Date: Thu, 26 Feb 2015 09:35:44 +0100 Subject: [PATCH 1/2] Make the attributes search work the same as for elements --- RestSharp.Tests/RestSharp.Tests.csproj | 4 ++++ RestSharp.Tests/SampleClasses/Goodreads.cs | 23 ++++++++++++++++++ RestSharp.Tests/SampleData/Goodreads.xml | 17 +++++++++++++ RestSharp.Tests/XmlDeserializerTests.cs | 14 +++++++++++ RestSharp/Deserializers/XmlDeserializer.cs | 28 +++++++++++----------- 5 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 RestSharp.Tests/SampleClasses/Goodreads.cs create mode 100644 RestSharp.Tests/SampleData/Goodreads.xml diff --git a/RestSharp.Tests/RestSharp.Tests.csproj b/RestSharp.Tests/RestSharp.Tests.csproj index 48c027dcd..66b8c8b1a 100644 --- a/RestSharp.Tests/RestSharp.Tests.csproj +++ b/RestSharp.Tests/RestSharp.Tests.csproj @@ -84,6 +84,7 @@ + @@ -122,6 +123,9 @@ Always + + Always + Always diff --git a/RestSharp.Tests/SampleClasses/Goodreads.cs b/RestSharp.Tests/SampleClasses/Goodreads.cs new file mode 100644 index 000000000..796a4ad6c --- /dev/null +++ b/RestSharp.Tests/SampleClasses/Goodreads.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +namespace RestSharp.Tests.SampleClasses +{ + public class GoodReadsReviewCollection + { + public int Start { get; set; } + public int End { get; set; } + public int Total { get; set; } + public List Reviews { get; set; } + } + + public class GoodReadsReview + { + public string Id { get; set; } + public GoodReadsBook Book { get; set; } + } + + public class GoodReadsBook + { + public string Isbn { get; set; } + } +} diff --git a/RestSharp.Tests/SampleData/Goodreads.xml b/RestSharp.Tests/SampleData/Goodreads.xml new file mode 100644 index 000000000..f6d82bafc --- /dev/null +++ b/RestSharp.Tests/SampleData/Goodreads.xml @@ -0,0 +1,17 @@ + + + + + + 0345475836 + + + + + 1198344567 + + 0802775802 + + + + \ No newline at end of file diff --git a/RestSharp.Tests/XmlDeserializerTests.cs b/RestSharp.Tests/XmlDeserializerTests.cs index 63dfe0a8b..cf29b09ce 100644 --- a/RestSharp.Tests/XmlDeserializerTests.cs +++ b/RestSharp.Tests/XmlDeserializerTests.cs @@ -546,6 +546,20 @@ public void Can_Deserialize_Google_Weather_Xml() Assert.Equal("Sunny", output.weather[0].condition.data); } + [Fact] + public void Can_Deserialize_Goodreads_Xml() + { + var xmlpath = PathFor("Goodreads.xml"); + var doc = XDocument.Load(xmlpath); + var response = new RestResponse { Content = doc.ToString() }; + var d = new XmlDeserializer(); + var output = d.Deserialize(response); + + Assert.Equal(2, output.Reviews.Count); + Assert.Equal("1208943892", output.Reviews[0].Id); // This fails without fixing the XmlDeserializer + Assert.Equal("1198344567", output.Reviews[1].Id); + } + [Fact] public void Can_Deserialize_Boolean_From_Number() { diff --git a/RestSharp/Deserializers/XmlDeserializer.cs b/RestSharp/Deserializers/XmlDeserializer.cs index 886b3096d..714eb07ce 100644 --- a/RestSharp/Deserializers/XmlDeserializer.cs +++ b/RestSharp/Deserializers/XmlDeserializer.cs @@ -470,33 +470,33 @@ protected virtual XElement GetElementByName(XElement root, XName name) protected virtual XAttribute GetAttributeByName(XElement root, XName name) { - var lowerName = name.LocalName.ToLower().AsNamespaced(name.NamespaceName); - var camelName = name.LocalName.ToCamelCase(Culture).AsNamespaced(name.NamespaceName); + var lower_name = name.LocalName.ToLower().AsNamespaced(name.NamespaceName); + var camel_name = name.LocalName.ToCamelCase(Culture).AsNamespaced(name.NamespaceName); if (root.Attribute(name) != null) { return root.Attribute(name); } - if (root.Attribute(lowerName) != null) + if (root.Attribute(lower_name) != null) { - return root.Attribute(lowerName); + return root.Attribute(lower_name); } - if (root.Attribute(camelName) != null) + if (root.Attribute(camel_name) != null) { - return root.Attribute(camelName); + return root.Attribute(camel_name); } // try looking for element that matches sanitized property name - var element = root.Attributes().FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName); - - if (element != null) - { - return element; - } - - return null; + return root.Descendants() + .OrderBy(d => d.Ancestors().Count()) + .Attributes() + .FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName) ?? + root.Descendants() + .OrderBy(d => d.Ancestors().Count()) + .Attributes() + .FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName.ToLower()); } } } From 416146f276176a29a092ef58a8d10c750321fe4e Mon Sep 17 00:00:00 2001 From: lycilph Date: Mon, 16 Mar 2015 12:42:57 +0100 Subject: [PATCH 2/2] Fix unit tests --- RestSharp/Deserializers/XmlDeserializer.cs | 49 ++++++---------------- 1 file changed, 13 insertions(+), 36 deletions(-) diff --git a/RestSharp/Deserializers/XmlDeserializer.cs b/RestSharp/Deserializers/XmlDeserializer.cs index 714eb07ce..7c2c532c7 100644 --- a/RestSharp/Deserializers/XmlDeserializer.cs +++ b/RestSharp/Deserializers/XmlDeserializer.cs @@ -453,50 +453,27 @@ protected virtual XElement GetElementByName(XElement root, XName name) } // try looking for element that matches sanitized property name (Order by depth) - var element = - root.Descendants() - .OrderBy(d => d.Ancestors().Count()) - .FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName) ?? root.Descendants() - .OrderBy(d => d.Ancestors().Count()) - .FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName.ToLower()); - - if (element != null) - { - return element; - } - - return null; + return root.Descendants() + .OrderBy(d => d.Ancestors().Count()) + .FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName) ?? + root.Descendants() + .OrderBy(d => d.Ancestors().Count()) + .FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName.ToLower()); } protected virtual XAttribute GetAttributeByName(XElement root, XName name) { - var lower_name = name.LocalName.ToLower().AsNamespaced(name.NamespaceName); - var camel_name = name.LocalName.ToCamelCase(Culture).AsNamespaced(name.NamespaceName); - - if (root.Attribute(name) != null) + var names = new List { - return root.Attribute(name); - } + name.LocalName, + name.LocalName.ToLower().AsNamespaced(name.NamespaceName), + name.LocalName.ToCamelCase(Culture).AsNamespaced(name.NamespaceName) + }; - if (root.Attribute(lower_name) != null) - { - return root.Attribute(lower_name); - } - - if (root.Attribute(camel_name) != null) - { - return root.Attribute(camel_name); - } - - // try looking for element that matches sanitized property name - return root.Descendants() + return root.DescendantsAndSelf() .OrderBy(d => d.Ancestors().Count()) .Attributes() - .FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName) ?? - root.Descendants() - .OrderBy(d => d.Ancestors().Count()) - .Attributes() - .FirstOrDefault(d => d.Name.LocalName.RemoveUnderscoresAndDashes() == name.LocalName.ToLower()); + .FirstOrDefault(d => names.Contains(d.Name.LocalName.RemoveUnderscoresAndDashes())); } } }