C# 使用Lambda查询XDocument

C# 使用Lambda查询XDocument,c#,xml,lambda,linq-to-xml,C#,Xml,Lambda,Linq To Xml,我有如下所示的XML <NodeName Foo="True" Foobar="False" /> <NodeName Foo="False" Foobar="False" /> <NodeName Foo="True" Foobar="False" /> 但是,属性Foo可能不存在,这会导致异常 问题是如何实现逻辑来检查属性是否存在,然后检查值是否存在 我尝试了下面的方法,但不确定else括号中的内容是否返回nothing,因为当前它不会编译,并且在所有路

我有如下所示的XML

<NodeName Foo="True" Foobar="False" />
<NodeName Foo="False" Foobar="False" />
<NodeName Foo="True" Foobar="False" />
但是,属性Foo可能不存在,这会导致异常

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

我尝试了下面的方法,但不确定else括号中的内容是否返回nothing,因为当前它不会编译,并且在所有路径上都不会返回值

.Where(node =>
            {
                if (node.Attribute("Foo") != null)
                {
                    node.Attribute("Foo").Value == "True";
                }
                else { }
            });
但是,属性Foo可能不存在,这会导致异常

这就是从
XAttribute
(实际上是
XElement
)到string和许多其他类型显式转换的方便之处:

.Where(node => (string) node.Attribute("Foo") == "True");
当没有此类属性时,转换将返回null。这比两次查找属性方便得多——一次用于显示,一次用于值

或者,您可以使用到
bool?
的转换,如果缺少属性,该转换也将返回null,因此您需要使用null合并运算符来有效地提供默认值:

.Where(node => (bool?) node.Attribute("Foo") ?? false);
编辑:关于语句lambda方法不起作用的原因,您没有任何返回语句。这是可行的,尽管我显然不推荐:

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

lambda必须返回一个布尔值,以确定节点是否位于结果集中。 试试这个:

 xml.Where(node => node.Attribute("Foo") != null && node.Attribute("Foo").Value == "True");
就这么做吧

.Where(node => node.Attribute("Foo") == null ? false : node.Attribute("Foo").Value == "True"); 

Will.Where(node=>node.Attributes(“Foo”).Any()?node.Attribute(“Foo”).Value==“True”:false);工作?它确实工作,但是@Jon Skeet提供了一种更干净的方法。这些方法非常适合我所做的,为知识洞察力干杯。会在允许的情况下标记答案。很好!还没有想到这种可能性。只是尝试了一行
.Where(node=>(bool)node.Attribute(“Foo”)?false)但是它不会编译,因为无法使用??跟布尔和布尔一起。@Mike:对不起,这应该是对
bool?
.Where(node => node.Attribute("Foo") == null ? false : node.Attribute("Foo").Value == "True");