Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

C# – XML Element Value Generic Extention Method

DZone's Guide to

C# – XML Element Value Generic Extention Method

·
Free Resource

Recently, I was working on integrating a help desk API into one of our applications.  The API would return XML and I was using LINQ-To-XML to get the values of the elements.  However, a number of the elements in the API were allowed to be null, like a field for the completed date of a help desk ticket.  So, I started out writing my code like this…

// constructor for Ticket class
public Ticket(XElement element)
{
     AssignedDate = (!string.IsNullOrEmpty(element.Element("assigned-date").Value)) ? DateTime.Parse(element.Element("assigned-date").Value) : (DateTime?)null;
 
     // .... on and one for about 40 elements
}

I looked back and thought I should come up with a better way of getting the data from the Element and into the datatype that I needed.  So I came up with this generic extension method…

/// <summary>
/// Gets the value of the element.  Will convert the value to specified type if
///    possible.  If not possible, will return default value for type.
/// </summary>
/// <typeparam name="T">Type that should be returned</typeparam>
/// <param name="ele"></param>
/// <returns></returns>
public static T GetElementValue<T>(this XElement ele)
{
    // if the element is null, then return the default
    if (ele == null)
        return default(T);
 
    // if value is blank or null, just return the default value
    //   for the type.
    if (string.IsNullOrEmpty(ele.Value))
        return default(T);
 
    // since the type of the Value property is a string, no need
    //   to do anything fancy.  Just return the value.
    if (typeof(T) == typeof(string))
        return (T)Convert.ChangeType(ele.Value, typeof(T));
 
    // creates new object of type T to store converted value
    T newObject = default(T);
 
    // check to see if it's a nullable type.  If so, get the underlying
    //   type.
    // Nullable types don't have a Parse method.  Therefore, we need the
    //   underlying type so we can call the Parse method through reflection
    //   to convert the value.
    PropertyInfo[] properties = typeof(T).GetProperties();
    Type underlyingType = typeof(T);
 
    // Nullable types will have two properties.  The first is the HasValue
    //   property.  The second is the underlying type.  However, some other
    //   types(such as String), and custom classes/structs could also have
    //   only two properties.  So we check to make sure that there are only
    //   2 properties, then we make sure the first property is the HasValue
    //   property.  Theoretically, this could still give a false positive.
    if (properties.Count() == 2 &&
        string.Equals(properties[0].Name, "HasValue", StringComparison.InvariantCultureIgnoreCase))
        underlyingType = properties[1].PropertyType;
 
    try
    {
        // calls Parse method for the type
        MethodInfo method = underlyingType.GetMethod("Parse", new[] { typeof(string) });
        newObject = (T)method.Invoke(null, new[] { ele.Value });
    }
    catch (Exception)
    {
        throw;
    }
 
    return newObject;
}

Now with this extension method, it really cuts down on the amount of code I have to write.  I can now use it like this..

public Ticket(XElement element)
{
     AssignedDate = element.Element("assigned-date").GetElementValue<DateTime?>();
}

I hope this can help out somebody.

Topics:

Published at DZone with permission of Ryan Alford, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}