I am writing a linq query to return an IEnumerable of XElements that match the search criteria.
The program throws an exception when an element matching the search criteria isn't found and including the statement inside a try/catch block doesn't catch the exception.
Thoughts on the correct way to catch the exception?
try
{
IEnumerable<XElement> oFootnotes = oRoot.DescendantNodes().OfType<XElement>().Where(x => x.Name == "p" && x.Attribute("class").Value == "endnote" && x.Attribute("id").Value == idFootnote);
}
catch(Exception ex)
{
}
CodePudding user response:
Enumerable.Where()
will not throw an exception when an element matching the search criteria isn't found. It will simply return an empty enumerable.
You have two possible problems:
You have some elements that are missing the attributes
"id"
or"class"
.To resolve this, use null conditional operator
?.
to access their value:.Where(x => x.Name == "p" && x.Attribute("class")?.Value == "endnote" && x.Attribute("id")?.Value == idFootnote);
Somewhere outside the code shown, you are getting the first element of the enumerable by using
Enumerable.First()
.To fix this, use
Enumerable.FirstOrDefault()
instead, and check for anull
return.
Thus your fixed query might look like:
var oFootnotes = oRoot.Descendants().Where(x => x.Name == "p" && x.Attribute("class")?.Value == "endnote" && x.Attribute("id")?.Value == idFootnote);
string firstFootnoteText = oFootnotes.FirstOrDefault()?.Value ?? ""; // If you want you can return the empty string in preference to the null string using the null-coalescing operator ??
Using Descendants()
to find all descendant elements of an XElement
is equivalent to, but more concise than, DescendantNodes().OfType<XElement>()
.
Demo fiddle here.