2014-01-17 39 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