XDocument使用Lambda查询

时间:2012-10-17 13:16:57

标签: c# xml lambda linq-to-xml

我有XML,如下所示

<NodeName Foo="True" Foobar="False" />
<NodeName Foo="False" Foobar="False" />
<NodeName Foo="True" Foobar="False" />

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

.Where(node => node.Attribute("Foo").Value = "True");

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

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

我已经尝试过以下但是不确定else括号中的内容是什么,因为当前它不会编译,并且没有在所有路径上返回值的错误。

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

3 个答案:

答案 0 :(得分:9)

  

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

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

.Where(node => (string) node.Attribute("Foo") == "True");

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

或者,您可以使用转换为bool?,如果属性丢失,将返回null,因此您需要使用null-coalescing运算符来有效地提供默认值:

.Where(node => (bool?) node.Attribute("Foo") ?? false);

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

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

答案 1 :(得分:2)

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

 xml.Where(node => node.Attribute("Foo") != null && node.Attribute("Foo").Value == "True");

答案 2 :(得分:2)

就这样做

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