XElement.Descendants("Node") not behaving as expected, returns multiple levels of Descendants
I have an issue. I have hierarchical XML data such as:
<Tree>
<Node Text="Stuff" ItemGUID="064a9bf0-0594-47f8-87be-88dd73763c77" >
<Node Text="Food" ItemGUID="326f1f7a-d364-4838-9bdc-ce5fd93f88ca" ItemType="2" />
<Node Text="Wines" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="Flowers" ItemGUID="cefa8c34-af06-48e7-9c00-4b1422d217a4">
<Node Text="Roses" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f">
<Node Text="Red" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="Pink" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="White" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
</Node>
<Node Text="Tulips" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="Whatever" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
</Node>
<Node Text="Sweet Delights" ItemGUID="1df7dbae-adf0-49a9-aaac-1358468a245b" />
</Node>
</Tree>
And I need to get just Flowers (Roses, Tulips, Whatever) WITHOUT Red, Pink, White (under Roses) I'm using the following code, but due to the fact that all nodes are "Node" I get all levels of Descendats. I would like to limit it to only one level.
XElement loadedXML = clients.ItemTreeXML;
//filter only current node
XElement procXML;
procXML = new XElement ("Tree",
from el in loadedXML.Descendants("Node")
where (string)el.Attribute("ItemGUID") == currentNodeGUID
select el);
Result Wanted:
<Tree>
<Node Text="Flowers" ItemGUID="cefa8c34-af06-48e7-9c00-4b1422d217开发者_StackOverflowa4">
<Node Text="Roses" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="Tulips" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
<Node Text="Whatever" ItemGUID="950e3ca3-27a1-41fd-89f3-7a8b08633a9f" />
</Node>
</Tree>
Thanks,
Added: Maybe a SQL 2008 query could retreive only the node branch I need, but after lots of research and testing, I could not find an answer... (My XML is in a XML column in SQL 2008)
So we have this...
XElement loadedXML = XElement.Load("test.xml");
//filter only current node
XElement procXML;
procXML = new XElement("Tree",
from el in loadedXML.Descendants("Node")
where (string)el.Attribute("ItemGUID") == currentNodeGUID
select el);
Best way I found was to remove all the child elements after you do the LINQ query. Like this:
foreach (XElement xl in procXML.Element("Node").Elements("Node"))
{
if (xl.HasElements) // just remove the ones without child elements
{
xl.RemoveNodes();
}
}
That will output what you have desired, but I must add... There is most definately a better way to do this. I don't know how well it will work with your situation given most code written needs to work more dynamically than this.
I saw this question and decided to take a dive into Linq, I guess it wasn't that bad. If that doesn't work just the way it needs to, at least it's a start.
精彩评论