I am using a chain of calls to the XElement.Element() method to drill down into an XML document and pull out the value of an attribute:
XElement root = ...;
XNamespace ns = "...";
var firstName =
root
.Element(ns + "Employee")
.Element(ns + "Identity")
.Element(ns + "Name")
.Attribute(ns + "FirstName");
However, since the incoming document has not been schema validated it is possible that a malformed document will cause a NullReferenceException if any of the expected intermediate elements does not exist.
Is there a way to avoid this risk, whilst keeping the code succinct?
I can wrap the code above in a handler for NullReferenceException however this feels wrong, and would also not specifically indicate where the failure occurred. Constructing an informative error message would be manual, tedious, error prone, and a maintenance hazard.
Should I be using XPath instead, that way I can check for a null return and then easily construct an error message indicating that the XPath expression could not be resolved?
One option is to use
Elements()instead ofElement()– which will yield an empty sequence if the element isn’t found. Using the extension methods in Extensions, you can go from a sequence of elements to a sequence of elements – and the same for attributes. So:There is a difference between the two snippets, mind you – this will find the first matching attribute even if it comes from (say) the first Name element within the third Identity element within the second Employee element. That may or may not be an issue for you.
(Just to check, do you definitely need the namespace on the attribute? Unlike elements, attributes don’t inherit a “default” namespace. It’s rarer to use attributes on namespaces than on elements.)