Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XDocument Querying using Lambda

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 { }
            });
like image 953
Mike Avatar asked Mar 19 '26 13:03

Mike


1 Answers

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;
            }
        });
like image 51
Jon Skeet Avatar answered Mar 21 '26 03:03

Jon Skeet