0

I want to be able to load xml file to Dictionary(string,customClass) on app start, and use UI to add new elements to it. At end, I would like to save that new xml that consist of old and new elements.

[Serializable]
public class Student
{
    public string ime;
    public string prezime;
    public DateTime datumRodjenja;
    public string mestoRodjenja;
    public string JMBG;
    public string brojIndeksa;

    public string adresa;
    public string grad;
    public string brojTelefona;
    public string brojMobilnog;

...

That's my class. I have tried many things I could think of as a beginer, but without success.

I would appreciate any suggestions. Thanks!

Iske
  • 1,150
  • 9
  • 18
  • 2
    How is your code related to Dictionary? I'll be happy to help, but I don't get understand your problem. – Matyas Sep 10 '15 at 18:07
  • You need to write a class that will serialize and deserialize your dictionary. see [Why isn't there an XML-serializable dictionary in .NET?](http://stackoverflow.com/questions/1124597/why-isnt-there-an-xml-serializable-dictionary-in-net) – Conrad Frix Sep 10 '15 at 18:12
  • Well, that is my problem. I have Dictinary(string, Student), where for the key I would like to use JMBG from the class itself. I have an UI where you can enter all these things and add it to a dictionary. But I would like to be able to load an XML with few Students to Dictionary, then while app is open add more students to Dic and at the and save new Dictionary to XML. – Iske Sep 10 '15 at 18:15

1 Answers1

1

XmlSerializer does not support Dictionary serialization directly, but we can define set of helper methods to save it as a list and later retrieve it to a dictionary, here is an example using extension methods and a data holder class Entry

public static class Helper
{
    public static void Load<TK, TV>(this Dictionary<TK, TV> dic, Stream stream)
    {
        var reader = new XmlSerializer(typeof (List<Entry<TK, TV>>));
        var list = (List<Entry<TK, TV>>)reader.Deserialize(stream);

        foreach(var l in list)
            dic.Add(l.Key,l.Value);
    }

    public static void Save<TK, TV>(this Dictionary<TK, TV> dic, Stream stream)
    {
        var list = new List<Entry<TK, TV>>();
        foreach (var pair in dic)
            list.Add(new Entry<TK, TV> {Key = pair.Key, Value = pair.Value});

        var writer = new XmlSerializer(typeof(List<Entry<TK, TV>>));
        writer.Serialize(stream, list);
    }

    public static void Load<TK, TV>(this Dictionary<TK, TV> dic, string path)
    {
        using(var f=File.OpenRead(path))
            Load(dic,f);
    }

    public static void Save<TK, TV>(this Dictionary<TK, TV> dic, string path)
    {
        using (var f = File.OpenWrite(path))
            Save(dic, f);
    }
}

public class Entry<TK, TV>
{
    [XmlAttribute]
    public TK Key { get; set; }
    public TV Value { get; set; }
}

and here is an usage example:

public class Student
{
    public string ime { get; set; }
    public string prezime { get; set; }
    public DateTime datumRodjenja { get; set; }
    public string mestoRodjenja { get; set; }
    public string JMBG { get; set; }
    public string brojIndeksa { get; set; }

    public string adresa { get; set; }
    public string grad { get; set; }
    public string brojTelefona { get; set; }
    public string brojMobilnog { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var dic=new Dictionary<string,Student>();

        var student1 = new Student
        {
            adresa = "adresa",
            JMBG = "1234",
            prezime = "prezime",
            datumRodjenja = DateTime.Now
        };

        var student2= new Student
        {
            adresa = "adresa",
            JMBG = "4567",
            prezime = "prezime",
            datumRodjenja = DateTime.Now
        };

        dic.Add(student1.JMBG,student1);
        dic.Add(student2.JMBG,student2);

        dic.Save("test.xml"); //save sample

        dic.Clear();
        dic.Load("test.xml"); //load sample

        var student3 = new Student
        {
            adresa = "adresa",
            JMBG = "9012",
            prezime = "prezime",
            datumRodjenja = DateTime.Now
        };

        dic.Add(student3.JMBG,student3); //adding new student 

            dic.Save("test.xml"); //saving again to add recently added student
    }

and final test.xml is:

<?xml version="1.0"?>
<ArrayOfEntryOfStringStudent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <EntryOfStringStudent Key="1234">
    <Value>
      <prezime>prezime</prezime>
      <datumRodjenja>2015-09-10T23:19:20.6226745+04:30</datumRodjenja>
      <JMBG>1234</JMBG>
      <adresa>adresa</adresa>
    </Value>
  </EntryOfStringStudent>
  <EntryOfStringStudent Key="4567">
    <Value>
      <prezime>prezime</prezime>
      <datumRodjenja>2015-09-10T23:19:20.6266749+04:30</datumRodjenja>
      <JMBG>4567</JMBG>
      <adresa>adresa</adresa>
    </Value>
  </EntryOfStringStudent>
  <EntryOfStringStudent Key="9012">
    <Value>
      <prezime>prezime</prezime>
      <datumRodjenja>2015-09-10T23:19:20.722681+04:30</datumRodjenja>
      <JMBG>9012</JMBG>
      <adresa>adresa</adresa>
    </Value>
  </EntryOfStringStudent>
</ArrayOfEntryOfStringStudent>
user3473830
  • 7,165
  • 5
  • 36
  • 52