XElement case insensitive 'Element' extension

Just a small bit of code, I've been playing around with converting some Xml* code to Linq to Xml code, and pretty successfully achieved everything I wanted, one thing missing was the ability to retrieve an XElement ignoring case.

First - I'd like mention that yes I know Xml is case sensitive - and this is a bad thing to do - but I needed to do it due to some wierdness in the input xml...

Anyhews, below is the extension method I wrote to deal with this..

public static class XElementExtensions
{
    /// <summary>Gets the first (in document order) child element with the specified <see cref="XName"/>.</summary>
    /// <param name="element">The element.</param>
    /// <param name="name">The <see cref="XName"/> to match.</param>
    /// <param name="ignoreCase">If set to <c>true</c> case will be ignored whilst searching for the <see cref="XElement"/>.</param>
    /// <returns>A <see cref="XElement"/> that matches the specified <see cref="XName"/>, or null. </returns>
    public static XElement Element( this XElement element, XName name, bool ignoreCase )
    {
        var el = element.Element( name );
        if (el != null)
            return el;
 
        if (!ignoreCase)
            return null;
 
        var elements = element.Elements().Where( e => e.Name.LocalName.ToString().ToLowerInvariant() == name.ToString().ToLowerInvariant() );
        return elements.Count() == 0 ? null : elements.First();
    }
}

 

Cheers!

Print | posted @ Thursday, December 3, 2009 3:50 AM

Comments on this entry:

Gravatar # re: XElement case insensitive 'Element' extension
by CoderX at 1/30/2011 6:04 AM

I used something like this b/c documentation was distributed with errors.

FYI, there appears to be a bug in the posted code...

The where needs to be:

.Where(e => e.Name.LocalName.ToString().ToLowerInvariant() == name.LocalName.ToString().ToLowerInvariant());

name.LocalName.ToString().ToLowerInvariant() instead of just name.ToString().ToLowerInvariant()
Gravatar # re: XElement case insensitive 'Element' extension
by Adrian at 4/28/2011 1:37 AM

There is a way to do the same, but more performant:

return element.SingleOrDefault(s => string.Compare(s.Name.ToString(), name, true) == 0);

Just one line. No matter if name exists, this will return null or XElement found.
Gravatar # re: XElement case insensitive 'Element' extension
by Punkster812 at 3/23/2012 4:49 AM

Adrian,

I like the code you have except for your use of SingleOrDefault instead of FirstOrDefault. SingleOrDefault will throw an exception if there is more than one element that matches the condition, which is a different behavior than the normal Element method does. FirstOrDefault says 'I don't care how many there are, return the first or the default value' (which would be null in a XElement case).
Post A Comment
Title:
Name:
Email:
Comment:
Verification: