Home > Back-end >  Handling linq XML queries that do not return an element (and thus throw an exception)
Handling linq XML queries that do not return an element (and thus throw an exception)

Time:12-29

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:

  1. 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);
    
  2. 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 a null 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.

  • Related