1

我正在用 C# 构建一个游戏,它将多个用户的数据存储在一个 XML 文件中。我无法弄清楚如何仅为当前播放器(例如 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>

XML 文件中的元素应匹配来自 C# (Jack) 的字符串变量“strPlayerName”。然后,应该只更新 Jack 的 WinCount 和 PlayCount 数字。

如何将元素与 strPlayerName 字符串变量匹配,然后仅针对该播放器更新 XML 文档中的和数字?谢谢,

4

3 回答 3

1

正如 Matthew Watson 建议的那样,一个好的解决方案是使用 XML 和序列化。

在您的项目中创建一个 xml,并确保其属性设置为 none 用于 Build Action 和 Copy Always 或 Copy if Newer for Copy to Output Directory。

以下是 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>

现在我们将使用这个 XML 将其反序列化为玩家列表。我在下面有一个用于序列化的辅助类。您将读取 XML 文件内容并将其传递给 Deserialize 方法,如图所示。当您希望保存 Players 列表时,将列表传递给 Serializer 并保存回您的文件。

序列化器帮助类:

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);
    } 
}

使用类反序列化:

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

使用类序列化和保存列表:

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

最后是 Player 类:

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

您将在代码中根据需要使用您的 Player 类和列表。

于 2013-05-17T20:37:19.797 回答
0

假设您的 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>

以下是使用XmlNodeAPI 更新 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";
}

或使用 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);
}

尽管正如其他人所说,对于这样的任务,序列化、反序列化可能是要走的路。

于 2013-05-17T20:30:20.030 回答
0

将您的 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>

创建一些类来保存您的 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; }
}

然后您可以执行以下操作来读取、更新和重写文件。

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);
    }
}
于 2013-05-17T20:43:42.063 回答