2014-01-17 100 views
0

我有以下列格式的XML文件查詢XML和更新某些元件

<?xml version="1.0" ?> 
<AA someattrib="xyz"> 
    <BB someOtherAttrib="xyz"> 
    <Title></Title> 
     <CC> 

      <myNode rowid=""> 
       <subNode1></subNode1> 
       <subNode2></subNode2> 
       <nodeOfInterest></nodeOfInterest> 
      </myNode > 
      <myNode rowid=""> 
       <subNode1> </subNode1> 

      </myNode> 
     </CC> 
    </BB> 
</AA> 

我想使用的LINQ由其中ROWID是特定數量的名稱「MYNODE」挑選出一個節點,我將從一個對象的集合中獲取。一旦我得到myNode,我想要更新子節點nodeOfInterest的值(如果它存在)。如果不存在,那麼我想補充一下。一旦完成,我想保存該文件。

這是我目前的情況,但它可能不是正確的做法。

foreach (User employee in Users) 
    { 

     XPathNavigator node = xNav.SelectSingleNode("/AA/BB/CC/myNode[@rowid = '"+employee.ID.ToString()+"']"); 
     XPathNodeIterator nodeIterator= node.SelectChildren("nodeOfInterest", ""); 
     if (nodeIterator.Count == 1) 
     { 

     } 
     else 
     { 
     } 

    } 

有沒有一種方法可以使用List和內存中的xmldoc之間的直接連接?這將是一個大列表和一個同樣大的xml文件。我不認爲運行循環並調用selectSingleNode是最有效的方法。

感謝您的輸入

回答

0

完整的答案,與喬恩的答覆幫助...

var doc = XDocument.Load("thefile.xml"); 
var dictionary = doc.Element("AA").Element("BB").Element("CC").Elements("myNode") 
       .ToDictionary(x => x.Attribute("rowId").Value); 

foreach (User employee in Users) 
{ 
    XElement myNode; 
    if (dictionary.TryGetValue(employee.ID, out myNode)) 
    { 
      XElement nodeOfInterest = myNode.Elements("nodeOfInterest").FirstOrDefault(); 
      if (nodeOfInterest != null) 
      { 
       nodeOfInterest.Value = "update with this value"; 
      } 
      else 
      { 
       XElement nodeOfInterest = new XElement("nodeOfInterest", "Add nodeOfInterest with this value"); 
       myNode.Add(newElement); 
      } 
    } 

} 
doc.Save("TheFile.xml"); 
+0

'元素'從哪裏來的呢從來沒有宣佈過 –

+0

元素應該是myNode,我相信 – mungflesh

+0

對不起。 Mungflesh是對的。謝謝。 – user20358

2

好一個出發點是創建一個Dictionary<string, XElement>行ID映射到元素:

var dictionary = doc.Element("AA").Element("BB").Element("CC").Elements("myNode") 
        .ToDictionary(x => x.Attribute("rowId").Value); 

然後:

foreach (User employee in Users) 
{ 
    XElement myNode; 
    if (dictionary.TryGetValue(employee.ID, out myNode)) 
    { 
     // Use myNode 
    } 
    else 
    { 
     // Employee not found 
    } 
} 

我個人更喜歡使用LINQ to XML(Elements,ElementDescendants等)提供的選擇方法而不是SelectSingleNodeSelectChildren

+0

謝謝您的回答。我仍然無法更新[elementofInterest]節點或添加一個新節點,然後將整個文檔與更新/添加的[elementofInterest]節點保存到文件系統。 – user20358

+0

你是什麼意思的「我還沒有能力」 - 當你嘗試時會發生什麼?它應該是絕對好的。 –

+0

如果我理解這個權利,那麼if塊將包含整個[myNode]節點。一旦我在變量myNode中有了這個整個節點,我仍然需要檢查元素[elementofInterest]是否存在,如果它存在,我需要更新它,否則,我需要添加一個。這需要完成循環中的迭代次數,然後需要保存文檔 – user20358