Using Linq to Ease XML Creation/Parsing

I am currently working on a Test Driven Development (TDD) Flickr API library in .NET. There already exists a FlickrNet library that is written in .NET, but it was written without using TDD and is very tightly coupled to the methods that send requests to flickr. I’ve tried refactoring the library but it just isn’t easy.

Instead I’m writing my own that I will share with others that is TDD driven. But that isn’t what this article is about. I’m writing today about Linq-to-Xml. Linq is basically an ORM technology for abstracting queries. You typically query a lot of data in programming such as XML, databases, files, and collections of information.

Linq allows you to look inside that data and pull out only what you need without having to write parsing methods. This is a gross over simplification of the process, but you can always read more at MSDN.

So why am I bringing this up? Well, the Flickr REST responses are all XML, so naturally my library has to do a lot of XML parsing. To test XML parsing, I have to pass in a bunch of XML somewhere, parse it  in my classes, and then do assertions that the objects I get back contain the same data that I sent in.

Originally my tests were looking something like this (FlickrBlogTests.cs):

[Test]
public void GetList_Returns_List_Of_Blogs() {
FlickrBlog blog1 = new FlickrBlog() { Id = “72″, Name = “Test Blog 1″, NeedsPassword = true, Url = “http://testblog1.com” };
string rawBlogResponse = “<blogs><blog id=\”" + blog1.Id + “\” name=\”" + blog1.Name +”\” … /></blogs>”;
List<FlickrBlog> blogs = FlickrBlogs.GetList();
Assert.That(blogs[0].Id, Is.EqualTo(blog1.Id));
}

Now, I started my actual code using Linq, so you will already see how Linq will come in handy. In the actual FlickrBlogs class code, I have a parse method like this:

private List<FlickrBlog> ParseResponseForBlogs(FlickrResponse response)
{
XDocument doc = XDocument.Load(new StringReader(response.RawData));
var query = from blog in doc.Elements(“blogs”).Elements(“blog”)
select new FlickrBlog
{
Id = blog.Attribute(“id”).Value,
Name = blog.Attribute(“name”).Value,
NeedsPassword = Convert.ToBoolean(blog.Attribute(“needspassword”).Value),
Url = blog.Attribute(“url”).Value
};
return query.ToList();
}

As you can tell, the test code is pretty shameful and difficult to change and test with. The FlickrBlogs code isn’t bad and it’s readable. Introducing Linq as a way to clean the test up:

[Test]
public void GetList_Correctly_Parses_Xml_Blog_Return()
{
FlickrBlog blog1 = new FlickrBlog() { Id = “73″, Name = “Bloxus Test”, NeedsPassword = true, Url = “http://remote.bloxus.com” };
FlickrBlog blog2 = new FlickrBlog() { Id = “74″, Name = “Test Blog 2″, NeedsPassword = false, Url = “http://testblog2.com” };
XDocument doc = new XDocument(
new XElement(“blogs”,
new XElement(“blog”,
new XAttribute(“id”, blog1.Id),
new XAttribute(“name”, blog1.Name),
new XAttribute(“needspassword”, blog1.NeedsPassword == true ? “1″ : “0″),
new XAttribute(“url”, blog1.Url)
),
new XElement(“blog”,
new XAttribute(“id”, blog2.Id),
new XAttribute(“name”, blog2.Name),
new XAttribute(“needspassword”, blog2.NeedsPassword == true ? “1″ : “0″),
new XAttribute(“url”, blog2.Url)
)
)
);

List<FlickrBlog> inputblogs = new List<FlickrBlog>();
inputblogs.Add(blog1);
inputblogs.Add(blog2);

FlickrResponse response = new FlickrResponse(FlickrResponseStatus.OK, doc.ToString());
commstub.Response = response;
List<FlickrBlog> blogs = flickr.Blogs.GetList();

Assert.That(commstub.Request.MethodName, Is.EqualTo(FlickrMethods.Blogs.GetList));
Assert.That(Is.Equals(blog1, blogs[0]));
Assert.That(Is.Equals(blog2, blogs[1]));
}
}

This entry was posted in .NET, Programming and tagged , , , . Bookmark the permalink.

Leave a Reply