I have XML as shown below
<NodeName Foo="True" Foobar="False" />
<NodeName Foo="False" Foobar="False" />
<NodeName Foo="True" Foobar="False" />
I am querying this to find NodeName's with a Foo value of 'True' using:
.Where(node => node.Attribute("Foo").Value = "True");
However there is the possibility that the attribute Foo may not exist and this causes an exception.
The question is how do you implement logic to check if the attribute exists and then check for the value if it does exist?
I have tried the following however not sure what goes in the else bracket to return nothing as currently it wont compile with an error of not returning a value on all paths.
.Where(node =>
{
if (node.Attribute("Foo") != null)
{
node.Attribute("Foo").Value == "True";
}
else { }
});
However there is the possibility that the attribute Foo may not exist and this causes an exception.
This is where the explicit conversion from XAttribute (and indeed XElement) to string and a number of other types comes in handy:
.Where(node => (string) node.Attribute("Foo") == "True");
The conversion will return null when there's no such attribute. This is much more convenient than finding the attribute twice - once for presence and once for the value.
Alternatively, you could use the conversion to bool? which will also return null if the attribute is missing, so you need to use the null-coalescing operator to effectively provide a default:
.Where(node => (bool?) node.Attribute("Foo") ?? false);
EDIT: In terms of why your statement-lambda approach doesn't work, you don't have any return statements. This would work, although obviously it's not what I'd recommend:
.Where(node =>
{
if (node.Attribute("Foo") != null)
{
return node.Attribute("Foo").Value == "True";
}
else
{
return false;
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With