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ドキュメントは、ヘルパークラスをシリアル化することによって生成されました。

NickGravelynのstreamEasyStorageライブラリから以下から取得します。

/// <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

XMLドキュメントにエラーがあります...次のように述べています

ストリームに書き込んだ後、最後に配置されます...同じストリームから読み取ろうとすると、ルート要素が見つかりません...ストリームを再配置する必要があります...

または、おそらくこのSO質問の逆シリアル化中のエラー

FileMode.CreateではなくFileMode.Openである必要があります

于 2012-04-11T13:41:58.070 に答える
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 に答える