简体   繁体   English

更新C#中的特定XML元素

[英]Updating specific XML elements in C#

I am building a game in C# which will store multiple user's data in an XML file. 我正在用C#开发一个游戏,它将在XML文件中存储多个用户的数据。 I am having trouble figuring out how to update XML data for only the current player (eg Jack): 我在弄清楚如何仅为当前播放器(例如Jack)更新XML数据时遇到了麻烦:

    <?xml version="1.0" encoding="utf-8"?>
<PlayerStats>
  <Name>Jack</Name>
  <WinCount>15</WinCount>
  <PlayCount>37</PlayCount>

  <Name>John</Name>
  <WinCount>12</WinCount>
  <PlayCount>27</PlayCount>
</PlayerStats>

The element in the XML file should match a string variable "strPlayerName" from C# (Jack). XML文件中的元素应与C#(Jack)中的字符串变量“ strPlayerName”匹配。 Then, only Jack's WinCount and PlayCount numbers should be updated. 然后,仅应更新Jack的WinCount和PlayCount编号。

How can I match the element with the strPlayerName string variable and then update the and numbers in the XML doc for only this player? 如何将元素与strPlayerName字符串变量匹配,然后仅针对此播放器更新XML文档中的和数字? Thanks, 谢谢,

As Matthew Watson recommended, a good solution would be using XML and Serialization. 正如Matthew Watson建议的那样,一个好的解决方案是使用XML和序列化。

Create an xml in your project and make sure its properties are set to none for Build Action and Copy Always or Copy if Newer for Copy to Output Directory. 在您的项目中创建一个xml,并确保将“构建操作”和“始终复制”或“如果复制到输出目录较新”,则将其属性设置为none。

Here is an example of the xml file: 这是xml文件的示例:

<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfPlayer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Player>
    <Name>Jack</Name>
    <WinCount>15</WinCount>
    <PlayCount>37</PlayCount>
  </Player>
  <Player>
    <Name>John</Name>
    <WinCount>12</WinCount>
    <PlayCount>27</PlayCount>
  </Player>
</ArrayOfPlayer>

Now we will use this XML to deserialize it into a List of Players. 现在,我们将使用此XML将其反序列化为播放器列表。 I have a helper class for serialization below. 我在下面有一个用于序列化的帮助程序类。 You would read the XML file contents and pass it to the Deserialize method as shown. 您将读取XML文件的内容,并将其传递给Deserialize方法,如图所示。 When you wish to save the Players list, pass the list to Serializer and save back to your file. 当您想要保存播放器列表时,将该列表传递给Serializer并保存回您的文件。

Serializer helper class: 序列化器帮助程序类:

public static class Serializer
{
    public static string SerializeObject(object objectToSerialize)
    {
        XmlSerializer x = new XmlSerializer(objectToSerialize.GetType());

        StringWriter writer = new StringWriter();
        x.Serialize(writer, objectToSerialize);

        return writer.ToString();
    }

    public static T DeserializeObject<T>(string serializedObject)
    {
        XmlSerializer xs = new XmlSerializer(typeof(T));
        StringReader reader = new StringReader(serializedObject);
        return (T)xs.Deserialize(reader);
    } 
}

Using the class to Deserialize: 使用该类进行反序列化:

//Change this as needed to read your XML file. 
string playersXML = File.ReadAllText(@"./Players.xml");
List<Player> players = Serializer.DeserializeObject<List<Player>>(playersXML);

Using the class to serialize and save the list: 使用该类来序列化并保存列表:

string newPlayersXML = Serializer.SerializeObject(players);
//Change this as needed to point to the XML location
File.WriteAllText(@"./Players.xml", newPlayersXML);

And finally the Player class: 最后是Player类:

public class Player
{
    public string Name { get; set; }
    public int WinCount { get; set; }
    public int PlayCount { get; set; }
}

You would use your Player class and the list as you need in the code. 您将在代码中根据需要使用Player类和列表。

Supposing your XML file looked like this: 假设您的XML文件如下所示:

<PlayerStats>
  <Player>
    <Name>Jack</Name>
    <WinCount>15</WinCount>
    <PlayCount>37</PlayCount>
  </Player>
  <Player>
    <Name>John</Name>
    <WinCount>12</WinCount>
    <PlayCount>27</PlayCount>
  </Player>
</PlayerStats>

Here's how you could update John's stats using the XmlNode API: 这是使用XmlNode API更新John的统计信息的方法:

string name = "John";

XmlNode player = doc.SelectNodes("/PlayerStats/Player")
                    .OfType<XmlNode>()
                    .FirstOrDefault(n => n["Name"].InnerText == name);

if (player != null)
{
    player["WinCount"].InnerText = "21";
    player["PlayCount"].InnerText = "22";
}

or with LINQ to XML: 或使用LINQ to XML:

var player2 = xe.Descendants("Player")
                .FirstOrDefault(n => (string)n.Element("Name") == name);

if (player != null)
{
    player2.Element("WinCount").SetValue(21);
    player2.Element("PlayCount").SetValue(22);
}

Though as others have said, for a task like this, serializing, deserializing is probably the way to go. 尽管正如其他人所说,对于这样的任务,序列化,反序列化可能是解决之道。

Change your XML structure to be as follows: 更改您的XML结构,如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<PlayerStats>
    <Player>
        <Name>Jack</Name>
        <WinCount>15</WinCount>
        <PlayCount>37</PlayCount>
    </Player>

    <Player>
        <Name>John</Name>
        <WinCount>12</WinCount>
        <PlayCount>27</PlayCount>
    </Player>
</PlayerStats>

Create some classes to hold your XML data: 创建一些类来保存您的XML数据:

[XmlRoot("PlayerStats")]
public class PlayerStats
{
    [XmlElement(ElementName = "Player")]
    public List<Player> Players { get; set; }
}

public class Player
{
    public string Name { get; set; }
    public int WinCount { get; set; }
    public int PlayCount { get; set; }
}

Then you can do the following to read it, update and re-write the file. 然后,您可以执行以下操作来读取,更新和重写文件。

PlayerStats stats;
using (var fileStream = new System.IO.FileStream("Sample.XML", System.IO.FileMode.Open))
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(PlayerStats));
    stats = (PlayerStats)xmlSerializer.Deserialize(fileStream);
}

var player = stats.Players.Where(p => p.Name == "Jack").FirstOrDefault();
if (player != null)
{
    // Update the record
    player.WinCount = player.WinCount + 1;
    player.PlayCount = player.PlayCount + 1;

    // Save back to file
    using (var fileStream = new System.IO.FileStream("Sample.XML", System.IO.FileMode.Create))
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(PlayerStats));
        xmlSerializer.Serialize(fileStream, stats);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM