Rediscovering the Obvious

…stumbling in the footsteps of greatness

More LINQ (to XML) happiness

without comments

Namespace handling is much improved! Yay for easy namespaces!

Anybody who has worked with XML in .NET 1.x or 2.0 knows how much of a pain XML namespaces can be in extracting data, yet they fill a very important part of the XML technology. Now, for linq.

Let’s say you’ve got a document on disk and you need to pull out the namespace of the root element. I’m messing with XAML, and here’s the code to open the file and extract the namespace.

            XElement xamlCanvas;

            using( StreamReader sr = new StreamReader( path ) )
            {
                xamlCanvas = XElement.Load(sr);
            }

            XNamespace ns = xamlCanvas.Name.Namespace;

The next thing I want to do is pull out a List<XElement> all of the child elements with an element name of “Canvas” and a “Tag” attribute of “Text”. Easy!

                IList< XElement > matchingElements =
                    xamlCanvas.Descendants( ns + “Canvas”)
                        .Where<XElement>(xe => xe.HasAttributeWithValue( “Tag”, “Text”))
                        .ToList<XElement>();

                templateContentMap.Add(ct, matchingElements );

The key element to notice is the one in bold – I just ADDED the tag name to the name of the element! How does that work? Well, first, “Canvas” is actually being implicitly converted to an XName instance, and XNamespace + XName is a perfectly valid expression of a node’s XName (can I XUse any more X’s?) This implicit conversion is making life easier throughout Linq to Xml, to the point it’s happening without me evening needing to be aware of it most of the time. Also, for completeness, that same thing could have been xamlCanvas.Descendants( “{http://schemas.microsoft.com/client/2007}Canvas” ) just as correctly, but I wanted to limit what was hard coded.

As an aside, HasAttributeWithValue is an extension method I wrote to clean up the lambda – it’s implemented as such:

    public static class XElementExtensions
    {
        public static bool HasAttributeWithValue(this XElement element, string name, string value)
        {
            if ( element.Attribute(name) == null )
                return false;

            return element.Attribute(name).Value == value;
        }
    }

Written by erwilleke

February 27th, 2008 at 1:21 pm

Posted in Uncategorized

Leave a Reply