How to handle missing node in LINQ to XML query
The following example illustrates how to set a default value f开发者_开发技巧or a LINQ to XML query when data is missing:
IEnumerable<Person> persons =
from e in x.Descendants("Person")
select new Person {
Name = e.Value,
Age = (int?)e.Attribute("Age") ?? 21
};
But how do you handle when an attribute is missing altogether? For example what if the node has no parent node?
IEnumerable<Person> persons =
from e in x.Descendants("Person")
select new Person {
Name = e.Value,
Age = (int?)e.Attribute("Age") ?? 21
ParentAge = e.Parent.Attribute("Age")
};
You handle it the hard way, usually with the ternary conditional operator:
IEnumerable<Person> persons =
from e in x.Descendants("Person")
select new Person {
Name = e.Value,
Age = (int?) e.Attribute("Age") ?? 21,
ParentAge = e.Parent != null ? (int) e.Parent.Attribute("Age") : 42
};
To my knowledge, there is no shorter way to do that in C#.
In my case I had to check to see if a "Notes" node existed or not and handle both cases, as well as any apostrophes in the text strings (this code is used to create MySQL insert strings). I enclose the string if it exists in single quotes and change any apostrophes to doubled, or simply insert a NULL if the node doesn't exist. I have no control over the XML client that creates XML files, and I have literally tens of thousands of them to parse through, so this is what I came up with that works:
var items =
from e in creationItems
select new
{
//other values
Notes = e.Descendants("Notes").Any() ? "'" + e.Descendants("Notes").First().Value.Replace("'", "''") + "'" : "NULL"
};
I couldn't figure out how to add this properly as a comment, so this is just an adjunct to @Frédéric Hamidi's excellent answer. This may be helpful to other folks in my predicament. This reduces my parsing code by a large amount, so it's a great solution.
精彩评论