MohamedG's Log

TW9oYW1lZCBFbC1HZWlzaA==

Extending XElement to Match Child Elements by LocalName

If you want to ignore the child elements’ namespaces, and match by local name only, you can do something similar to the following:

/// <summary>
/// Represents an extension for <see cref="XElement"/>.
/// </summary>
internal static class XElementExtension
{
    /// <summary>
    /// Gets the first (in document order) child element with the specified <paramref name="localName"/>.
    /// </summary>
    /// <param name="parent">The parent element.</param>
    /// <param name="localName">The local name to match.</param>
    /// <returns>An <see cref="XElement"/> that matches the specified <paramref name="localName"/>, or <c>null</c>.</returns>
    public static XElement LocalNameElement(this XElement parent, string localName)
    {
        return parent.Elements().FirstOrDefault(e => e.Name.LocalName == localName);
    }

    /// <summary>
    /// Returns a filtered collection of the child elements of the specified <paramref name="parent"/>, in document order.
    /// Only elements that have a matching <paramref name="localName"/> are included in the collection.
    /// </summary>
    /// <param name="parent">The parent element.</param>
    /// <param name="localName">The local name to match.</param>
    /// <returns>
    /// An <see cref="IEnumerable{T}"/> of <see cref="XElement"/> containing the children that have a matching <paramref name="localName"/>,
    /// in document order.
    /// </returns>
    public static IEnumerable<XElement> LocalNameElements(this XElement parent, string localName)
    {
        return parent.Elements().Where(e => e.Name.LocalName == localName);
    }
}

You can use the same pattern to extend Attributes(XName) and the rest of the select/search methods. For the list of methods, see: XElement Methods.