Misa Kovar
Misa Kovar

Reputation: 73

Search through XDocument for XElement with certain Attribute using Linq

I have a XML document that looks like this:

<Window x:Name="winName" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="My Window" SizeToContent="WidthAndHeight">
        <Grid ShowGridLines="true">
                <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <GroupBox x:Name="grBox" Header="Main Group Box" Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" Grid.ColumnSpan="1" />
                <TabControl x:Name="tabControl" Grid.Row="1" Grid.Column="0" Grid.RowSpan="1" Grid.ColumnSpan="1">
                        <TabItem x:Name="mainTab" Header="Main Tab" />
                </TabControl>
        </Grid>
</Window>

I want my code to find XElement TabItem with x:Name mainTab. This is how my code looks:

XDocument doc = XDocument.Load(path);
XNamespace xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
XNamespace xaml = "http://schemas.microsoft.com/winfx/2006/xaml";
IEnumerable<XElement> result = from myElems in doc.Descendants(xmlns + "Window")
                               where myElems.Attribute(xaml + "Name").Value == "mainTab"
                               select myElems;

But this doesn't work, there are no results. Please advise.

Upvotes: 0

Views: 349

Answers (1)

Dan Field
Dan Field

Reputation: 21641

Couple problems. You're telling Descendants() to look for an element with the local name Window, you should be telling it to look for the element with the local name TabItem (the item you actually want).

Second, you'll get a NullReferenceException if you ever have a TabItem that doesn't have an x:Name attribute; you'd be attempting to get the Value field on a null reference, so you should cast the return of Attribute() to a string and compare that.

Here's the working select:

IEnumerable<XElement> result = from myElems in doc.Descendants(xmlns + "TabItem")
                               where (string)myElems.Attribute(xaml + "Name") == "mainTab"
                               select myElems;

Upvotes: 2

Related Questions