xml file save/read error (making a highscore system for XNA game)

Posted by Eddy on Game Development See other posts from Game Development or by Eddy
Published on 2012-04-07T15:56:43Z Indexed on 2012/04/07 17:48 UTC
Read the original article Hit count: 394

Filed under:
|
|
|
|

i get an error after i write player name to the file for second or third time (An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.dll

Additional information: There is an error in XML document (18, 17).) (in highscores load method In data = (HighScoreData)serializer.Deserialize(stream); it stops)

the problem is that some how it adds additional ">" at the end of my .dat file could anyone tell me how to fix this?

the file before save looks:

<?xml version="1.0"?>
<HighScoreData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <PlayerName>
    <string>neil</string>
    <string>shawn</string>
    <string>mark</string>
    <string>cindy</string>
    <string>sam</string>
  </PlayerName>
  <Score>
    <int>200</int>
    <int>180</int>
    <int>150</int>
    <int>100</int>
    <int>50</int>
  </Score>
  <Count>5</Count>
</HighScoreData>

the file after save looks:

<?xml version="1.0"?>
<HighScoreData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <PlayerName>
    <string>Nick</string>
    <string>Nick</string>
    <string>neil</string>
    <string>shawn</string>
    <string>mark</string>
  </PlayerName>
  <Score>
    <int>210</int>
    <int>210</int>
    <int>200</int>
    <int>180</int>
    <int>150</int>
  </Score>
  <Count>5</Count>
</HighScoreData>>

the part of my code that does all of save load to xml is: DECLARATIONS PART

  [Serializable]
    public struct HighScoreData
    {
        public string[] PlayerName;
        public int[] Score;

        public int Count;

        public HighScoreData(int count)
        {
            PlayerName = new string[count];
            Score = new int[count];

            Count = count;
        }
    }


    IAsyncResult result = null;
 bool inputName;
    HighScoreData data;
int Score = 0;
    public string NAME;

    public string HighScoresFilename = "highscores.dat";

Game1 constructor

 public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        Width = graphics.PreferredBackBufferWidth = 960;
        Height = graphics.PreferredBackBufferHeight =640;
        GamerServicesComponent GSC = new GamerServicesComponent(this);
        Components.Add(GSC); 
    }

Inicialize function (end of it)

  protected override void Initialize()
    {

//other game code base.Initialize();

        string fullpath =Path.Combine(HighScoresFilename);

        if (!File.Exists(fullpath))
        {
            //If the file doesn't exist, make a fake one...
            // Create the data to save
            data = new HighScoreData(5);
            data.PlayerName[0] = "neil";
            data.Score[0] = 200;

            data.PlayerName[1] = "shawn";
            data.Score[1] = 180;

            data.PlayerName[2] = "mark";
            data.Score[2] = 150;

            data.PlayerName[3] = "cindy";
            data.Score[3] = 100;

            data.PlayerName[4] = "sam";
            data.Score[4] = 50;

            SaveHighScores(data, HighScoresFilename);
        }

}

all methods for loading saving and output

 public static void SaveHighScores(HighScoreData data, string filename)
{
// Get the path of the save game
    string fullpath = Path.Combine("highscores.dat");


// Open the file, creating it if necessary
FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate);
try
{
// Convert the object to XML data and put it in the stream
    XmlSerializer serializer = new XmlSerializer(typeof(HighScoreData));
serializer.Serialize(stream, data);
}
finally
{
// Close the file
stream.Close();
}
        }


    /* Load highscores */
    public static HighScoreData LoadHighScores(string filename)
    {
    HighScoreData data;

    // Get the path of the save game
    string fullpath = Path.Combine("highscores.dat"); 

    // Open the file
    FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate, FileAccess.Read);
    try
    {
    // Read the data from the file
        XmlSerializer serializer = new XmlSerializer(typeof(HighScoreData));
    data = (HighScoreData)serializer.Deserialize(stream);//this is the line
    // where program gives an error
    }
    finally
    {
    // Close the file
    stream.Close();
    }

    return (data);


    }


    /* Save player highscore when game ends */
    private void SaveHighScore()
    {
    // Create the data to saved
    HighScoreData data = LoadHighScores(HighScoresFilename);

    int scoreIndex = -1;
    for (int i = 0; i < data.Count ; i++)
    {
    if (Score > data.Score[i])
    {
    scoreIndex = i;
    break;
    }
    }

    if (scoreIndex > -1)
    {
    //New high score found ... do swaps
    for (int i = data.Count - 1; i > scoreIndex; i--)
    {
    data.PlayerName[i] = data.PlayerName[i - 1];
    data.Score[i] = data.Score[i - 1];
    }

    data.PlayerName[scoreIndex] = NAME; //Retrieve User Name Here
    data.Score[scoreIndex] = Score; // Retrieve score here

    SaveHighScores(data, HighScoresFilename);
    }
    }

    /* Iterate through data if highscore is called and make the string to be saved*/
    public string makeHighScoreString()
    {
    // Create the data to save
    HighScoreData data2 = LoadHighScores(HighScoresFilename);

    // Create scoreBoardString
    string scoreBoardString = "Highscores:\n\n";


for (int i = 0; i<5;i++)
{
scoreBoardString = scoreBoardString + data2.PlayerName[i] + "-" + data2.Score[i] + "\n";
}
return scoreBoardString;
}

when ill make this work i will start this code when i call game over (now i start it when i press some buttons, so i could test it faster)

   public void InputYourName()
   {
                     if (result == null && !Guide.IsVisible)
                     {

                          string title = "Name";
                          string description = "Write your name in order to save your Score";
                          string defaultText = "Nick";
                          PlayerIndex playerIndex = new PlayerIndex();
                          result= Guide.BeginShowKeyboardInput(playerIndex, title, description, defaultText, null, null);
                        // NAME = result.ToString();

                     }

                if (result != null && result.IsCompleted)
                     {
                         NAME = Guide.EndShowKeyboardInput(result);
                         result = null;
                         inputName = false;
                         SaveHighScore();
                     }

  }

this where i call output to the screen (ill call this in highscores meniu section when i am done with debugging)

spriteBatch.DrawString(Font1, "" + makeHighScoreString(),new Vector2(500,200), Color.White);



  }

© Game Development or respective owner

Related posts about XNA

Related posts about Xml