I’ve recently started with Linq, and I’m currently trying to use it to parse a heavily nested XML file (which I have no control over). However, I get the “Object reference not set to an instance of an object” error when trying to run the below statement.
The problem is in the “City” line. The data for the city property comes from the xml structure prospect/contactinfo/City/Answer.
But since the field is not mandatory, sometimes the XML will NOT have the city/answer nodes. So I get the error because the “city” node does not exist, and I’m trying to call “.Element()” on it. I’ve found plenty of solutions for this problem, when it is only one node-level down (i.e. if the data I needed was in city, and city was the only node missing).
But when it is two levels down (I.e. trying to get the childnode of a nonexisting node), I have not been able to find any solution.
Hope the question is expressed clearly enough.
Best regards,
Morten
var prospects = (from prospect in xdoc.Descendants("PROSPECT")
select new Prospect {
ProspectID = (string) prospect.Element("PROSPECTINFO").Element("PROSPECT_ID"),
Name = (string) prospect.Element("PERSONALINFO").Element("FIRSTNAME")+ " " + prospect.Element("PERSONALINFO").Element("SURNAME"),
address = (string) prospect.Element("CONTACTINFO").Element("ADDRESSLINE1").Element("ANSWER"),
zipCode = (string)prospect.Element("CONTACTINFO").Element("POSTALCODE").Element("ANSWER").Value,
City = (string) prospect.Element("CONTACTINFO").Element("CITY").Element("ANSWER"),
}).ToList();
One option is to use
Elementsinstead ofElement. That’s an extension method which finds all elements (optionally with a given name) within either a single element or in a collection of elements. So if you use that repeatedly, you’ll end up with a collection of 0 elements at the end if there aren’t any matches. UseFirstOrDefaultto get that element or null, and then the string conversion will do what you want:That way you don’t have to write any conditional code – it all just drops out.
The biggest advantage of this over the sort of check that ChrisF suggests is if the navigation path becomes long. Imagine there are 6 parts of the path, and every one of them is option – you’d need 5 checks (first “a”, then “a.b”, then “a.b.c” etc) followed by the real “fetch the thing”, whereas in this scheme you just add one extra
Elementscall for each new navigation link.