XElement.Потомки (“Узел”) ведут себя не так, как ожидалось, возвращает несколько уровней потомков
Вопрос
У меня есть проблема.У меня есть иерархические XML-данные, такие как:
<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>
И мне нужно купить просто Цветы (Розы, Тюльпаны, Что угодно) БЕЗ Красного, Розового, Белого (под Розами). Я использую следующий код, но из-за того, что все узлы являются "Узловыми", я получаю все уровни потомков.Я бы хотел ограничить это только одним уровнем.
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);
Желаемый результат:
<Tree>
<Node Text="Flowers" ItemGUID="cefa8c34-af06-48e7-9c00-4b1422d217a4">
<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>
Спасибо,
Добавлено:Возможно, запрос SQL 2008 мог бы восстановить только нужную мне ветвь узла, но после множества исследований и тестирования я не смог найти ответа...(Мой XML находится в столбце XML в SQL 2008)
Решение
Итак, у нас есть это...
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);
Лучший способ, который я нашел, - это удалить все дочерние элементы после выполнения запроса LINQ.Вот так:
foreach (XElement xl in procXML.Element("Node").Elements("Node"))
{
if (xl.HasElements) // just remove the ones without child elements
{
xl.RemoveNodes();
}
}
Это приведет к тому, что вы пожелали, но я должен добавить...Есть наиболее определенно лучший способ сделать это.Я не знаю, насколько хорошо это будет работать в вашей ситуации, учитывая, что большинство написанных кодов должны работать более динамично, чем это.
Я увидел этот вопрос и решил углубиться в Linq, думаю, это было не так уж плохо.Если это работает не так, как нужно, по крайней мере, это начало.