C# 使用Lambda查询XDocument
我有如下所示的XMLC# 使用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,因为当前它不会编译,并且在所有路
<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");