1

我正在尝试反序列化表示高分和首字母列表的键值对列表。当我尝试反序列化 XML 文档时,我不断收到错误消息:There is an error in XML document (0, 0).

我正在反序列化我的 XML 文档,如下所示:

GameHighScore highScoreHelper = new GameHighScore();

XmlSerializer deserializer = new XmlSerializer(typeof(GameHighScore));
highScoreHelper = (GameHighScore)deserializer.Deserialize(stream);

for (int i = 0; i < highScoreHelper.highScoreList.Count; i++)
{
  highScore[i] = new KeyValuePair<string, int>(highScoreHelper.highScoreList[i].Initials, highScoreHelper.highScoreList[i].Score);
}

我在我的助手类中遗漏了什么吗?

  [XmlRootAttribute("GameScore")]
  public class GameHighScore
  {
    [XmlArray("Scores")]
    [XmlArrayItem("HighScore")]
    public List<HighScoreStruct<string, int>> highScoreList;

    private HighScoreStruct<string, int> scoreListHelper;

    [Obfuscation(Exclude = true)]
    public struct HighScoreStruct<K, V>
    {
      [XmlElement("Initials")]
      public K Initials
      { get; set; }

      [XmlElement("Score")]
      public V Score
      { get; set; }

      public HighScoreStruct(K initials, V score) : this() 
      {
        Initials = initials;
        Score = score;
      }
    }

    /// <summary>
    /// The constructor instanstiates the highscore list and 
    /// the high score struct.
    /// </summary>
    public GameHighScore()
    {
      highScoreList = new List<HighScoreStruct<string, int>>();
      scoreListHelper = new HighScoreStruct<string, int>();
    }

    /// <summary>
    /// This method creates the list of scores to be stored to the disk.
    /// </summary>
    /// <param name="scoreList"></param>
    public void CreateGameHighScore(List<KeyValuePair<string, int>> scoreList)
    {

      for (int i = 0; i < scoreList.Count; i++)
      {
        scoreListHelper = new HighScoreStruct<string, int>(scoreList[i].Key, scoreList[i].Value);
        highScoreList.Add(scoreListHelper);
      }
    }
  }

生成的 XML 文档

<?xml version="1.0"?>
<GameScore xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Scores>
    <HighScore>
      <Initials>ZZZ</Initials>
      <Score>53125</Score>
    </HighScore>
    <HighScore>
      <Initials>AAA</Initials>
      <Score>50000</Score>
    </HighScore>
    <HighScore>
      <Initials>AAA</Initials>
      <Score>45000</Score>
    </HighScore>
    <HighScore>
      <Initials>AAA</Initials>
      <Score>40000</Score>
    </HighScore>
    <HighScore>
      <Initials>AAA</Initials>
      <Score>35000</Score>
    </HighScore>
    <HighScore>
      <Initials>AAA</Initials>
      <Score>30000</Score>
    </HighScore>
    <HighScore>
      <Initials>AAA</Initials>
      <Score>25000</Score>
    </HighScore>
    <HighScore>
      <Initials>AAA</Initials>
      <Score>20000</Score>
    </HighScore>
    <HighScore>
      <Initials>AAA</Initials>
      <Score>15000</Score>
    </HighScore>
    <HighScore>
      <Initials>AAA</Initials>
      <Score>10000</Score>
    </HighScore>
  </Scores>
</GameScore>

编辑

上面的 XML 文档是通过序列化我的帮助类生成的。

stream是从 Nick Gravelyn 的 EasyStorage 库中获得的:

/// <summary>
/// Loads a file.
/// </summary>
/// <param name="containerName">The name of the container from which to load the file.</param>
/// <param name="fileName">The file to load.</param>
/// <param name="loadAction">The load action to perform.</param>
public void Load(string containerName, string fileName, FileAction loadAction)
{
  VerifyIsReady();

  // lock on the storage device so that only one storage operation can occur at a time
  lock (storageDevice)
  {
    // open a container
using (StorageContainer currentContainer = OpenContainer(containerName))
{
      // attempt the load
  using (var stream = currentContainer.OpenFile(fileName, FileMode.Open))
  {
    loadAction(stream);
  }
}
  }
}

我的完整加载方法如下: 注意:保存设备只是我的 EasyStorage 保存设备的一个实例。

public static void Load()
{
  if (Global.SaveDevice.IsReady)
  {
    if (Global.SaveDevice.FileExists(Global.containerName, Global.filename_highscores_xml))
    {
      Global.SaveDevice.Load(
        Global.containerName,
        Global.filename_highscores_xml,
        stream =>
        {
          try
          {
            //stream.Position = 0;
            GameHighScore highScoreHelper = new GameHighScore();

            XmlSerializer deserializer = new XmlSerializer(typeof(GameHighScore));
            highScoreHelper = (GameHighScore)deserializer.Deserialize(stream);

            for (int i = 0; i < highScoreHelper.highScoreList.Count; i++)
            {
              highScore[i] = new KeyValuePair<string, int>(highScoreHelper.highScoreList[i].Initials, highScoreHelper.highScoreList[i].Score);
            }
          }
          catch (Exception e)
          {
            //if (!Global.SaveDevice.IsBusy && Global.SaveDevice.IsReady)
            //  Global.SaveDevice.DeleteAsync(Global.containerName, Global.filename_highscores_xml);
            //Save();
            Logger.LogError("Score.Load", e);
          }
        });
    }
    else
    {
      Save();
    }
  }
}
4

3 回答 3

1

我刚刚使用了您发布的代码,它有效

GameHighScore highScoreHelper = new GameHighScore();

using (var stream = new FileStream("GameScore.xml", FileMode.Open))
{
    XmlSerializer deserializer = new XmlSerializer(typeof(GameHighScore));
    highScoreHelper = (GameHighScore)deserializer.Deserialize(stream);

    for (int i = 0; i < highScoreHelper.highScoreList.Count; i++)
    {
        Console.WriteLine(new KeyValuePair<string, int>(highScoreHelper.highScoreList[i].Initials, highScoreHelper.highScoreList[i].Score));
    }
}

顺便提一句。文件的编码是 UTF-8,VS 就是这么做的

于 2012-04-11T13:52:39.043 回答
0

尝试使用 LINQ 填充字典:

//initialize the dictionary
var dict = new Dictionary<string, string>();

//populate the dictionary with the xml document
doc.Descendants("HighScore")
    .Select(x => dict[x.Element("Initials").Value] = x.Element("Score").Value);
于 2012-04-11T14:02:00.140 回答
0

XML 文档中存在错误...指出

写入流后,它位于末尾...如果您尝试从同一流中读取,则找不到根元素...您需要重新定位流...

或者可能是这个 SO question在反序列化期间出现错误

应该是 FileMode.Open 而不是 FileMode.Create

于 2012-04-11T13:41:58.070 回答