在 XDocument 中编辑特定元素
Posted
技术标签:
【中文标题】在 XDocument 中编辑特定元素【英文标题】:Edit specific Element in 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),然后将这些更改保存到我的文档中。
【问题讨论】:
【参考方案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 帮助 here 和 the 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简单的方式。它仍然很简单。以上是关于在 XDocument 中编辑特定元素的主要内容,如果未能解决你的问题,请参考以下文章
使用 xmlReader 在 C# 中过滤特定元素值的大型 XML