Search code examples
c#xml.net-framework-version

Save XML Data under Root


I'm trying to save multiple entries into an existing xml doc. But I'm not getting the desired results.

I have the following code:

public static void recordScore(ScoreModel scoreModel)
        {
            var path = "../../Media/Leaderboard/Leaderboard.xml";
            var saveModel = new LeaderboardModel();


            Stream fs = new FileStream(path, FileMode.Open);
            XmlReader reader = new XmlTextReader(fs);
            XmlSerializer serializer = new XmlSerializer(typeof(LeaderboardModel));
            if (serializer.CanDeserialize(reader))
            {
                LeaderboardModel o = (LeaderboardModel) serializer.Deserialize(reader);
                saveModel.ScoreModels.AddRange(o.ScoreModels);
            }
            fs.Close();

            saveModel.ScoreModels.Add(scoreModel);

            System.Xml.Serialization.XmlSerializer writer =
                new System.Xml.Serialization.XmlSerializer(typeof(LeaderboardModel));

            System.IO.FileStream file = System.IO.File.Open(path, System.IO.FileMode.Append);

            writer.Serialize(file, saveModel);
            file.Close();
        }

My output in the xml file is as follows:

<?xml version="1.0"?>
<LeaderboardModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ScoreModels>
    <ScoreModel>
      <Name>Test</Name>
      <GameSpeed>Normal</GameSpeed>
      <Score>11</Score>
    </ScoreModel>
  </ScoreModels>
</LeaderboardModel><?xml version="1.0"?>
<LeaderboardModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ScoreModels>
    <ScoreModel>
      <Name>Test</Name>
      <GameSpeed>Normal</GameSpeed>
      <Score>11</Score>
    </ScoreModel>
  </ScoreModels>
</LeaderboardModel><?xml version="1.0"?>
<LeaderboardModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ScoreModels>
    <ScoreModel>
      <Name>Test</Name>
      <GameSpeed>Normal</GameSpeed>
      <Score>11</Score>
    </ScoreModel>
  </ScoreModels>
</LeaderboardModel><?xml version="1.0"?>

As you can see it's outputting the LeaderboardModel and ScoreModels every time. It's only supposed to write that once and then add the new ScoreModel under that Root.

EDIT: My expected result:

    <LeaderboardModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <ScoreModels>
        <Name>Test1</Name>
        <GameSpeed>Normal</GameSpeed>
        <Score>1</Score>
      </ScoreModels>
      <ScoreModels>
        <Name>Test2</Name>
        <GameSpeed>Normal</GameSpeed>
        <Score>2</Score>
      </ScoreModels>
      <ScoreModels>
        <Name>Test3</Name>
        <GameSpeed>Normal</GameSpeed>
        <Score>3</Score>
      </ScoreModels>
    </LeaderboardModel>

Also how would I read it back again from this format?


Solution

  •  static void Main(string[] args)
        {
            LeaderboardModel lm = new LeaderboardModel();
            List<LeaderboardModelScoreModels> m = new List<LeaderboardModelScoreModels>();
            lm.ScoreModels = m;
    
            for (int i= 0;i < 2;i++)
            {
                m.Add(new LeaderboardModelScoreModels() { ScoreModel = new LeaderboardModelScoreModelsScoreModel() { GameSpeed = "hi", Name = "hi", Score = 1 } });
            }
            System.Xml.Serialization.XmlSerializer writer =
                new System.Xml.Serialization.XmlSerializer(typeof(LeaderboardModel));
    
            System.IO.FileStream file = System.IO.File.Open("D:\\a.xml", System.IO.FileMode.Append);
    
            writer.Serialize(file, lm);
            file.Close();
    
        }
    

    MOdel :

       using System.Collections.Generic;
      [System.SerializableAttribute()]
     [System.ComponentModel.DesignerCategoryAttribute("code")]
     [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
     [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = 
     false)]
     public partial class LeaderboardModel
     {
    
    private List<LeaderboardModelScoreModels> scoreModelsField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("ScoreModels")]
    public List<LeaderboardModelScoreModels> ScoreModels
    {
        get
        {
            return this.scoreModelsField;
        }
        set
        {
            this.scoreModelsField = value;
        }
    }
    }
    
    
    [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
     public partial class LeaderboardModelScoreModels
    {
    
    private LeaderboardModelScoreModelsScoreModel scoreModelField;
    
    /// <remarks/>
    public LeaderboardModelScoreModelsScoreModel ScoreModel
    {
        get
        {
            return this.scoreModelField;
        }
        set
        {
            this.scoreModelField = value;
        }
    }
    }
    
    
     [System.SerializableAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class LeaderboardModelScoreModelsScoreModel
    {
    
    private string nameField;
    
    private string gameSpeedField;
    
    private byte scoreField;
    
    /// <remarks/>
    public string Name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }
    
    /// <remarks/>
    public string GameSpeed
    {
        get
        {
            return this.gameSpeedField;
        }
        set
        {
            this.gameSpeedField = value;
        }
    }
    
    /// <remarks/>
    public byte Score
    {
        get
        {
            return this.scoreField;
        }
        set
        {
            this.scoreField = value;
        }
      }
    }