如何在XML根节点下追加ScoreModel数据?代码问题求助
问题分析与解决
你的核心问题是写入XML时使用了FileMode.Append,这会把完整的LeaderboardModel序列化内容直接追加到文件末尾,导致XML出现多个根节点(每个追加操作都写入一个完整的LeaderboardModel),这是不符合XML规范的,自然也无法正常读取。
修正保存逻辑
正确的做法应该是:读取现有所有分数条目,合并新条目后,覆盖写入原文件(而不是追加),这样就能保证整个XML只有一个根节点LeaderboardModel,其下的ScoreModels节点包含所有ScoreModel条目。
另外,建议用using语句管理流和序列化对象,自动释放资源,避免手动关闭流可能带来的问题。修正后的代码如下:
public static void recordScore(ScoreModel scoreModel) { var path = "../../Media/Leaderboard/Leaderboard.xml"; LeaderboardModel saveModel = new LeaderboardModel(); // 读取现有数据(如果文件存在) if (File.Exists(path)) { using (Stream fs = new FileStream(path, FileMode.Open)) { XmlSerializer serializer = new XmlSerializer(typeof(LeaderboardModel)); if (serializer.CanDeserialize(XmlReader.Create(fs))) { LeaderboardModel existingModel = (LeaderboardModel)serializer.Deserialize(fs); saveModel.ScoreModels.AddRange(existingModel.ScoreModels); } } } // 添加新分数 saveModel.ScoreModels.Add(scoreModel); // 覆盖写入文件 using (FileStream file = new FileStream(path, FileMode.Create)) { XmlSerializer writer = new XmlSerializer(typeof(LeaderboardModel)); writer.Serialize(file, saveModel); } }
关于你预期的XML格式的小说明
你给出的预期格式里,把每个分数条目写成了<ScoreModels>,这其实是不符合XML序列化逻辑的。如果你的LeaderboardModel类里ScoreModels是List<ScoreModel>类型,正确的XML结构应该是:
<LeaderboardModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <ScoreModels> <ScoreModel> <Name>Test1</Name> <GameSpeed>Normal</GameSpeed> <Score>1</Score> </ScoreModel> <ScoreModel> <Name>Test2</Name> <GameSpeed>Normal</GameSpeed> <Score>2</Score> </ScoreModel> <ScoreModel> <Name>Test3</Name> <GameSpeed>Normal</GameSpeed> <Score>3</Score> </ScoreModel> </ScoreModels> </LeaderboardModel>
也就是ScoreModels作为一个父节点,包含所有ScoreModel子节点,这样才是符合集合序列化的标准结构,也能正常被XmlSerializer读取。
读取XML的方法
现在XML结构是标准的单个根节点,读取就非常简单了,直接反序列化整个LeaderboardModel即可,代码示例:
public static LeaderboardModel LoadLeaderboard() { var path = "../../Media/Leaderboard/Leaderboard.xml"; if (!File.Exists(path)) { return new LeaderboardModel(); // 返回空模型 } using (Stream fs = new FileStream(path, FileMode.Open)) { XmlSerializer serializer = new XmlSerializer(typeof(LeaderboardModel)); return (LeaderboardModel)serializer.Deserialize(fs); } }
调用这个方法后,你可以通过leaderboardModel.ScoreModels获取所有的分数条目集合。
内容的提问来源于stack exchange,提问作者Enthused Dragon
相关产品推荐
相关产品推荐

