Hugoware

The product of a web developer with a little too much caffeine

Saving Your Sanity – Handling XML Namespaces Using LINQ

with one comment

Have you ever worked with XML documents that have Namespaces with them? It’s that extra bit of markup in XML documents that is supposed to prevent any of your elements from conflicting with each other. For me, they tend to get in they way more than they help — Let’s take some example XML.

<?xml version="1.0"?>
<data:Inventory xmlns:data="http://www.bookstore.com/" >
    <data:Books xmlns:inv="http://www.bookstore.com/book-inventory">
        <inv:Book count="231" >C# For Dummies</inv:Book>
        <inv:Book count="35" >Using jLinq</inv:Book>
        <inv:Book count="54" >Ruby On Raylze</inv:Book>
    </data:Books>
</data:Inventory>

Typically when using XML I’ve used XPaths to find the information I need. I’m certainly not an expert but I know enough to get the job done. Normally, with plain vanilla XML, you could write a quick XPath to find your books and parse over them. There is a handful of ways you could do it but for this example let’s be a little lazy…

XDocument inventory = XDocument.Load("d:\\temp\\sample.xml");
IEnumerable<XElement> books = inventory.XPathSelectElements("//Book");

//How many books do you think we have?
Console.WriteLine(books.Count());

If you run this code you’re going to end up with a big, fat, ugly zero. You can even try a variety of other XPaths, but none of which will find you the data you want.

  • //inv:Bookthrows an error
  • Inventory/Books/Bookreturns 0
  • Inventory/Books/*returns 0
  • //Books/*returns 0

Nothing — Ouch…

LINQ To The Rescue

If you’ve been using LINQ then you know that you can’t help but use it when you realize just how powerful it is. As much as I used it though, it never occurred to me that LINQ could be used in place of an XPath. Using the same XML as before and applying a tiny bit of LINQ magic, we come up with the following solution.

var results =
    inventory.Descendants()
        .Where(o => o.Name.LocalName.Equals("Book"))
        .Select(o => new {
            Name = o.Value,
            Count = int.Parse(o.Attribute("count").Value)
        });

I didn’t do any performance tests but I doubt that something like this would incur any sort of noticeable hit. Even if it is a bit slower, I think it is worth it. With a single LINQ query I’m not only able to avoid dealing with Namespaces all together, but I’m able to parse and return my data into an anonymous type. All my information is ready to go just like that!

This certainly isn’t a monumental discovery — In fact I’m sure that I’m arriving to this late in the game, but for today my life got a lot better now that it became much less painful to work with SOAP responses!

Advertisements

Written by hugoware

August 5, 2009 at 1:07 am

Posted in General Discussions

Tagged with , , , , ,

One Response

Subscribe to comments with RSS.

  1. Exactly what I was after, thanks!

    Keith

    March 30, 2010 at 5:25 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: