LINQ to XML : Handling blank or no Element and Attribute
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!!!