Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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!!!
Comments
Anonymous
February 15, 2012
ElementValueOrEmpty AttributeValueOrEmptyAnonymous
August 05, 2012
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?Anonymous
September 06, 2012
great postAnonymous
December 25, 2012
thanksAnonymous
May 16, 2013
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.htmlAnonymous
October 23, 2013
Sweet, Exactly what i was afterAnonymous
May 22, 2014
i am beginner in linq this post is really help full to me implement the logic .thanks you so much