XDocument使用Lambda查询

Mik*_*ike 2 c# xml lambda linq-to-xml

我有XML,如下所示

<NodeName Foo="True" Foobar="False" />
<NodeName Foo="False" Foobar="False" />
<NodeName Foo="True" Foobar="False" />
Run Code Online (Sandbox Code Playgroud)

我正在查询这个以使用以下方法找到具有Foo值'True'的NodeName:

.Where(node => node.Attribute("Foo").Value = "True");
Run Code Online (Sandbox Code Playgroud)

但是,属性Foo可能不存在,这会导致异常.

问题是如何实现逻辑来检查属性是否存在,然后检查值是否存在?

我已经尝试了以下但是不确定在else括号中返回什么,因为目前它不会编译错误,不会在所有路径上返回值.

.Where(node =>
            {
                if (node.Attribute("Foo") != null)
                {
                    node.Attribute("Foo").Value == "True";
                }
                else { }
            });
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 9

但是,属性Foo可能不存在,这会导致异常.

这是从XAttribute(实际上XElement)到字符串和许多其他类型的显式转换派上用场的地方:

.Where(node => (string) node.Attribute("Foo") == "True");
Run Code Online (Sandbox Code Playgroud)

当没有这样的属性时,转换将返回null.这比查找属性两次要方便得多 - 一次是存在,一次是值.

另外,您也可以使用转换bool?,这将返回null如果属性是缺少的,所以你需要使用空合并运算,有效地提供一个默认的:

.Where(node => (bool?) node.Attribute("Foo") ?? false);
Run Code Online (Sandbox Code Playgroud)

编辑:就你的statement-lambda方法不起作用的原因而言,你没有任何 return语句.这可行,虽然显然不是我推荐的:

.Where(node =>
        {
            if (node.Attribute("Foo") != null)
            {
                return node.Attribute("Foo").Value == "True";
            }
            else
            {
                return false;
            }
        });
Run Code Online (Sandbox Code Playgroud)