将xml doc反序列化为键值对列表

时间:2012-04-11 13:31:32

标签: c# xml

我正在尝试反序列化表示高分和首字母列表的键值对列表。我在尝试反序列化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();
    }
  }
}

3 个答案:

答案 0 :(得分: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就是这样做

答案 1 :(得分:0)

There is an error in XML document ...说明

  

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

或者可能是这个问题Error during deserialization

  

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

答案 2 :(得分: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);