简体   繁体   English

处理 linq XML 不返回元素的查询(因此抛出异常)

[英]Handling linq XML queries that do not return an element (and thus throw an exception)

I am writing a linq query to return an IEnumerable of XElements that match the search criteria.我正在编写一个 linq 查询以返回与搜索条件匹配的 XElements 的 IEnumerable。

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.当未找到与搜索条件匹配的元素并且在 try/catch 块中包含语句未捕获异常时,程序将抛出异常。

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)
{
}

Enumerable.Where() will not throw an exception when an element matching the search criteria isn't found.当找不到符合搜索条件的元素时, Enumerable.Where()不会抛出异常。 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" .您有一些元素缺少属性"id""class"

    To resolve this, use null conditional operator ?.要解决此问题,请使用null 条件运算符?. 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() .在所示代码之外的某处,您将使用Enumerable.First()获取可枚举的第一个元素。

    To fix this, use Enumerable.FirstOrDefault() instead, and check for a null return.要解决此问题,请改用Enumerable.FirstOrDefault() ,并检查null返回值。

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>() .使用Descendants()查找XElement的所有后代元素等效于但比DescendantNodes().OfType<XElement>()更简洁。

Demo fiddle here .演示小提琴在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM