2009-11-18 53 views
0

我有一個問題。我有諸如分層XML數據:XElement.Descendants(「節點」)行爲不如預期,返回多級後代

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

,我需要得到公正鮮花(玫瑰,鬱金香,無論),而紅,粉,白(下玫瑰) 我用下面的代碼,但由於到所有節點都是「節點」的事實,我得到了所有級別的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查詢可以retreive只有節點分支我需要的,但大量的研究和測試後,我不能找到答案......(我的XML位於SQL 2008的XML列中)

回答

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

,但我必須補充...有最肯定一個更好的方式來做到這一點。我不知道它會如何處理你的情況,因爲大部分代碼需要比這更動態地工作。

我看到了這個問題,決定深入Linq,我猜這不是那麼糟糕。如果這不能滿足需要,至少這是一個開始。

+0

感謝您的輸入。我也在做同樣的事情。只是想知道有一個更快的方法。可選地,SQL 2008 XML查詢會很棒,但是我找不到任何方法來獲取我需要的節點集。我想避免加載到內存巨大的XML,實際上我只需要其中一個分支,並且只有這個分支的一個層次。 – mfr 2009-11-19 12:15:35