Search code examples
c#.netxmllinq-to-xmlxelement

Getting null elements using xelement with c# .net


Let us consider the following xml document:

<contact>
    <name>Hines</name>
    <phone>206-555-0144</phone>
    <mobile>425-555-0145</mobile>
</contact>

from which I retrieve a value as

var value = parent.Element("name").Value;

The code above will throw a NullReferenceException if "name" is not present, as Element will return null in C# but not in vb.net which will throw empty value.

So my problem is to identify when the xml nodes below the root node are missing and to get an empty value instead.


Solution

  • You could create an extension method that can easily be reused. Place it in a static class

    public static string ElementValue(this XElement parent, string elementName)
    {
        var xel = parent.Element(elementName);
        return xel == null ? "" : xel.Value;
    }
    

    Now you can call it like this

    string result = parent.ElementValue("name");
    

    UPDATE

    If you return null instead of an empty string when the element is not present, this gives you the possibility to differentiate between an empty element and the absence of an element.

    public static string ElementValue(this XElement parent, string elementName)
    {
        var xel = parent.Element(elementName);
        return xel == null ? null : xel.Value;
    }
    

     

    string result = parent.ElementValue("name");
    if (result == null) {
        Console.WriteLine("Element 'name' is missing!");
    } else {
        Console.WriteLine("Name = {0}", result);
    }
    

    EDIT

    Microsoft uses the following pattern in different places in the .NET Framework Class Library

    public static bool TryGetValue(this XElement parent, string elementName,
                                                         out string value)
    {
        var xel = parent.Element(elementName);
        if (xel == null) {
            value = null;
            return false;
        }
        value = xel.Value;
        return true;
    }
    

    It can be called like this

    string result;
    if (parent.TryGetValue("name", out result)) {
        Console.WriteLine("Name = {0}", result);
    }
    

    UPDATE

    With C# 6.0 (Visual Studio 2015) Microsoft has introduced the null propagation operator ?. simplifying things a lot:

    var value = parent.Element("name")?.Value;
    

    This will simply set the value to null even if the element was not found.

    You can also combine it with the coalesce operator ??, if you want to return another value than null:

    var value = parent.Element("name")?.Value ?? "";