2009-11-18 2 views
0

У меня проблема. У меня есть иерархические данные XML, такие как:XElement.Descendants («Node») не ведет себя так, как ожидалось, возвращает несколько уровней потомков

<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> 

И мне нужно получить только цветы (розы, тюльпаны, Whatever) БЕЗ красный, розовый, белый (под розы) Я использую следующий код, но из-за к тому, что все узлы являются «Узлом», я получаю все уровни Descendats. Я хотел бы ограничить его только одним уровнем.

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)

ответ

0

Итак, у нас есть ...

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(); 
    } 
} 

Это будет выводить то, что вы желали, но я должен добавить ... Существует наиболее определенно лучший способ сделать это. Я не знаю, насколько хорошо он будет работать с вашей ситуацией, если большинство написанных кодов должно работать более динамично, чем это.

Я увидел этот вопрос и решил погрузиться в Линк, я думаю, это было не так уж плохо. Если это не работает так, как нужно, по крайней мере, это начало.

+0

Спасибо за ввод. Я делал то же самое. Просто интересно, есть ли более быстрый путь. Опционально XML-запрос SQL 2008 был бы замечательным, но я не могу найти способ получить только тот набор узлов, который мне нужен. Я бы хотел, чтобы избежать загрузки в ram огромный XML, когда на самом деле мне просто нужна одна из многих ветвей и только один уровень этой ветви. – mfr