【问题标题】:Edit specific Element in XDocument在 XDocument 中编辑特定元素
【发布时间】:2013-09-01 18:11:49
【问题描述】:

我最近开始学习 C#,但在使用 XML.Linq 存储数据时遇到了问题。我希望这个问题可以理解,因为我还不熟悉所有正确的术语,而且英语不是我的第一语言。

我阅读了很多问题/谷歌搜索,但我自己无法弄清楚。

我想更新如下所示的现有 XDocument 文件:

<Data>
  <IDCounter>2</IDCounter>
  <Highscores>
     .......
  </Highscores>
  <savegames>
    <savegame>
       <IdNumber>1</IdNumber>
       <salutation>Mr</salutation>
       <prename>Prename1</prename>
       <surname>Surname1</surname>
       <maximumbalance>100</maximumbalance>
       <balance>100</balance>
    </savegame>
    <savegame>
       <IdNumber>2</IdNumber>
       <salutation>Mr</salutation>
       <prename>Prename2</prename>
       <surname>Surname2</surname>
       <maximumbalance>100</maximumbalance>
       <balance>100</balance>
     </savegame>
   </savegames>
</Data> 

更改特定元素中的值的最简单方法是什么?

假设我想更改特定存档游戏平衡

我想通过 IdNumber 访问存档游戏(这些数字是唯一的)

然后我想更改 balance 的值(例如更改为 50),然后将这些更改保存到我的文档中。

【问题讨论】:

    标签: c# xml linq


    【解决方案1】:

    using System.Xml.Linq; 变成了

     var doc = XElement.Load(fileName);
     var saveGame = doc
          .Element("savegames")
          .Elements("savegame")
          .Where(e => e.Element("IdNumber").Value == "2")
          .Single();
    
     saveGame.Element("balance").Value = "50";
    
     doc.Save(fileName);
    

    【讨论】:

    • 由于某种原因,我有一个错误“对象引用未设置为实例...”然后我用XDocument.Load(fileName);修复它
    • 我也得到“对象引用未设置为实例”。我发现添加 XNamespace 为我解决了这个问题:doc.Element(Ns + "Foo")...
    • 一个 XElement 几乎在所有情况下都可以扮演 Document 的角色。 Xml 可能需要也可能不需要命名空间。
    【解决方案2】:

    我认为最简洁的方式是使用 XDocument (System.Xml.Linq) 和 XPath 扩展 (System.Xml.XPath):

    var xdoc = XDocument.Load(file);
    xdoc.XPathSelectElement("//savegame/IdNumber[text()='2']/../balance").Value = "50";
    xdoc.Save(file);
    

    一旦你学会了 XPath,你就再也不想回到手动枚举节点了。

    编辑:查询是什么意思:

    //savegame/IdNumber[text()='2']/../balance"
      |        |                    |  ^ balance element ...
      |        |                    ^ ... of parent ...
      |        ^ ... of IdNumber element with inner value '2' ...
      ^ ... of any savegame element in the doc
    

    您可以找到 XPath 帮助 herethe updated link here

    【讨论】:

    • 这里是更新后的link XPath 帮助。
    • 这里是 XPath 帮助的更新更新 link
    • 编辑一个值是可以的,但是如果我想编辑 100 怎么办?它将“循环”100 次以更新值。
    【解决方案3】:
       UpdateGameAttr(id ,  bal);
    
       private void UpdateGameAttr(int id, int bal)
       {
           XDocument gmaes = XDocument.Load(@"D:\xxx\xxx\Game.xml");            
    
           XElement upd = (from games in games.Descendants("savegame")
                          where games.Element("IdNumber").Value == id.ToString()
                          select games).Single();
           upd.Element("balance").Value = bal.ToString();
           gmaes.Save(@"D:\xxxx\xxx\Game.xml");
    
       }
    

    【讨论】:

      【解决方案4】:

      这是一个简单的方法:

           XmlDocument doc = new XmlDocument();
           doc.Load(@"d:\tmp.xml");
           XmlNode node = doc["Data"]["savegames"];
      
           foreach (XmlNode childNode in node.ChildNodes)
           {
              if (childNode["IdNumber"].InnerText.Equals("1"))
              {
                 childNode["balance"].InnerText = "88";
              }
      
           }
           doc.Save(@"d:\tmp.xml");
      

      这段代码只改变id“1”的余额

      它通过遍历“savegames”的子项并检查每个项目的“IdNumber”来实现

      【讨论】:

      • XmlDocument 不是“简单”的方式。这是老办法。
      • @HenkHolterman(和支持者)你非常迂腐。不是说“THE简单的方式”,只是A简单的方式。它仍然很简单。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      • 1970-01-01
      • 1970-01-01
      • 2012-01-17
      • 2020-03-29
      • 1970-01-01
      相关资源
      最近更新 更多