LINQ to XML : Handling blank or no Element and Attribute

LINQ to XML : Handling blank or no Element and Attribute

  • Comments 7

It quite so happen that you are working with XML where you are expecting a specific element in every set. But somehow that is missing in some of the sets.

Now at runtime you would get an error..

The XML file which I am targeting

<?xml version="1.0" encoding="utf-8"?>
<Employees>
  <Employee Location="Earth">
    <Name>Wriju</Name>
    <Email>a@a.com</Email>
  </Employee>
  <Employee Location="Moon">
    <Name>Tupur</Name>
    <Email>a@b.com</Email>
  </Employee>
  <Employee>
    <Name>Wrishika</Name>
  </Employee>  
</Employees>

Notice above the third element has missing Location attribute and Email element. So this would throw me a runtime error if I try to execute as below.

var xml = XElement.Load(@"D:\Temp\Employee.xml");

var q = from e in xml.Descendants("Employee")
        select new 
        {
            Name = e.Element("Name").Value,
            Location = e.Attribute("Location").Value,
            Email = e.Element("Email").Value
        };

foreach (var k in q)
{
    Console.WriteLine("Name : {0}, Email : {1}, Location : {2}", 
        k.Name, k.Email, k.Location);
}

Error would come for the 3rd element where both Location attribute and Email element are missing.

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object

Now what I need is simple. By using C# 3.0 extension method I can create two additional methods in a public static class as below

//This method is to handle if element is missing
public static string ElementValueNull(this XElement element)
{
    if (element != null)
        return element.Value;

    return "";
}

//This method is to handle if attribute is missing
public static string AttributeValueNull(this XElement element, string attributeName)
{
    if (element == null)
        return "";
    else
    {
        XAttribute attr = element.Attribute(attributeName);
        return attr == null ? "" : attr.Value;
    }
}

Now my code would look like and would not throw any runtime error

var xml = XElement.Load(@"D:\Temp\Employee.xml");

var q = from e in xml.Descendants("Employee")
        select new 
        {
            Name = e.Element("Name").ElementValueNull(),
            Location = e.AttributeValueNull("Location"),
            Email = e.Element("Email").ElementValueNull()
        };

foreach (var k in q)
{
    Console.WriteLine("Name : {0}, Email : {1}, Location : {2}", 
        k.Name, k.Email, k.Location);
}

Namoskar!!!

Leave a Comment
  • Please add 6 and 8 and type the answer here:
  • Post
  • ElementValueOrEmpty

    AttributeValueOrEmpty

  • Thank you for this post, it looks like exactly what I'm looking for...but I can't get it to work.  I created a method and ran my linq-to-xml query in there.  The query works well but there are a couple records where expected nodes don't exist just like in your example.  So, I copied and pasted your ElementValueNull method below the method with the query in it.  Then I changed the query to look for loop.Element("pan").ElementValueNull() instead of loop.Element("pan").Value() but I keep getting an error "System.Xml.Linq.XElement does not contain a definition for..."  How do I get my query to see my new method?

  • great post

  • thanks

  • Here is how I made it work for me:

     public static class XElementExtensionMethods

       {

          code for ElementValueNull(this XElement element){}

          code for AttributeValueNull{}

       }

    It worked for me only after I moved the declaration of XElementExtensionMethods to outside of my class. Make it the very first class in your program after "using ;" statements.

    --- this part of my message can be removed by blogger ---

    Here is another person doing it:

    tutorialgenius.blogspot.com/.../linqtoxml-safe-element-and-attribute.html

  • Sweet, Exactly what i was after

  • i am beginner in linq this post is really help full to me implement the logic .thanks you so much

Page 1 of 1 (7 items)