Reputation: 15475
Given the working code snippet below, I'm trying to get the target
element inside RootChild2
.
https://dotnetfiddle.net/eN4xV9
string str =
@"<?xml version=""1.0""?>
<!-- comment at the root level -->
<Root>
<RootChild1>
<Child>Content</Child>
<Child>Content</Child>
<Child>Content</Child>
</RootChild1>
<RootChild2>
<Child>Content</Child>
<Child key='target'>Content</Child>
<Child>Content</Child>
</RootChild2>
</Root>";
XDocument doc = XDocument.Parse(str);
foreach (XElement element in doc.Descendants("RootChild2"))
{
if (element.HasAttributes && element.Element("Child").Attribute("key").Value == "target")
Console.WriteLine("found it");
else
Console.WriteLine("not found");
}
Upvotes: 0
Views: 1505
Reputation: 23258
You should rewrite your foreach
loop at little bit, add accessing of child Elements()
collection in RootChild2
and check every element in enumeration. You also can check that key
attribute is present in element to prevent a potential null reference exception
foreach (XElement element in doc.Descendants("RootChild2").Elements())
{
if (element.HasAttributes && element.Attribute("key")?.Value == "target")
Console.WriteLine("found it");
else
Console.WriteLine("not found");
}
Descendants(XName)
returns only elements with matching names, therefore you are getting only one RootChild2
element as the result in your code
Upvotes: 2
Reputation: 1063338
This finds all 3 RootChild2/Child
elements, then tests each in turn:
foreach (XElement child in doc.Descendants("RootChild2").Elements("Child"))
{
if ((string)child.Attribute("key") == "target")
Console.WriteLine("found it");
else
Console.WriteLine("not found");
}
Upvotes: 3
Reputation: 766
You are accessing the RootChild2-Element itself through element
inside your loop.
Take a look at the following version:
foreach (XElement element in doc.Descendants("RootChild2").Nodes())
{
if (element.HasAttributes && element.Attribute("key").Value == "target")
Console.WriteLine("found it");
else
Console.WriteLine("not found");
}
Now it loops through all nodes of RootChild2.
Upvotes: 2
Reputation: 1502086
There are three problems here:
RootChild2
element has any attributes - and it doesn'tChild
element under each RootChild2
elementXAttribute
)Here's code which will find all the target elements within a RootChild2
:
foreach (XElement element in doc.Descendants("RootChild2"))
{
var targets = element
.Elements("Child")
.Where(child => (string) child.Attribute("key") == "target")
.ToList();
Console.WriteLine($"Found {targets.Count} targets");
foreach (var target in targets)
{
Console.WriteLine($"Target content: {target.Value}");
}
}
Note that the cast of XAttribute
to string
is a simple way of avoiding null reference issues - because the result of the explicit conversion is null when the source is null. (That's a general pattern in LINQ to XML.)
Upvotes: 2