Reputation: 675
I have this code based on Microsoft docs.
string xml =
"<products>" +
"<product name=\"p1\">" +
"<market name=\"m1\">" +
"<areacode>12345</areacode>" +
"<areacode>12346</areacode>" +
"</market>" +
"<market name=\"m2\">" +
"<areacode>12345</areacode>" +
"<areacode>13346</areacode>" +
"</market>" +
"<market name=\"m3\">" +
"<areacode>12346</areacode>" +
"<areacode>13346</areacode>" +
"</market>" +
"</product>" +
"<product name=\"p2\">" +
"<market name=\"m1\">" +
"<areacode>12340</areacode>" +
"<areacode>12346</areacode>" +
"</market>" +
"<market name=\"m2\">" +
"<areacode>12340</areacode>" +
"<areacode>13346</areacode>" +
"</market>" +
"<market name=\"m3\">" +
"<areacode>12346</areacode>" +
"<areacode>13346</areacode>" +
"</market>" +
"</product>" +
"</products>";
XElement prods = XElement.Parse(xml);
IEnumerable<XElement> els =
from e1 in prods.Elements("product")
where
(string)e1.Attribute("name") == "p1" &&
(
from e2 in e1.Elements("market")
where
(
from e3 in e2.Elements("areacode")
where e3.Value == "12345"
select e3
).Any()
select e2
).Any()
select e1;
foreach (XElement el in els)
Console.WriteLine(el);
The output is
<product name="p1">
<market name="m1">
<areacode>12345</areacode>
<areacode>12346</areacode>
</market>
<market name="m2">
<areacode>12345</areacode>
<areacode>13346</areacode>
</market>
<market name="m3">
<areacode>12346</areacode>
<areacode>13346</areacode>
</market>
</product>
How can I exclude markets that do not have the specified area code from the output? Product name, market name and area codes are all required for the rest of the code if it matches the condition.
Upvotes: 0
Views: 30
Reputation: 26917
There's no easy way to create a new tree that has just what you want, since you can't filter children directly. However, you can modify your tree:
prods.Descendants("market").Where(m => m.Descendants("areacode").All(a => a.Value != "13346")).Remove();
prods.Descendants("product").Where(p => !p.Descendants("market").Any()).Remove();
Upvotes: 1