MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Serializarea în XML cu XmlSerializer

Pentru salvarea și extragerea convenabilă a obiectelor din fișiere XML, se poate folosi clasa XmlSerializer din spațiul de nume System.Xml.Serialization. Această clasă simplifică salvarea obiectelor complexe în format XML și extragerea ulterioară a acestora.

Pentru a crea un obiect XmlSerializer, se pot folosi diverși constructori, dar aproape toți necesită specificarea tipului de date care vor fi serializați și deserializați:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person));

// [Serializable]
class Person { }

În acest caz, XmlSerializer va lucra doar cu obiecte ale clasei Person.

Trebuie luat în considerare că XmlSerializer presupune anumite restricții. De exemplu, clasa supusă serializării trebuie să aibă un constructor standard fără parametri și să fie declarată cu modificatorul de acces public.

De asemenea, sunt serializați doar membrii publici. Dacă clasa conține câmpuri sau proprietăți cu modificatorul private, acestea vor fi ignorate în timpul serializării. În plus, proprietățile trebuie să aibă getter și setter accesibile publicului.

Serializarea

Pentru serializare (adică salvarea în format XML) se folosește metoda Serialize(). Această metodă are mai multe versiuni. Vom lua cea mai simplă dintre ele:

void Serialize (Stream stream, object? o);

Ca prim parametru, se transmite un flux de tip Stream (de exemplu, un obiect FileStream), în care va avea loc serializarea. Al doilea parametru reprezintă obiectul care va fi salvat în format XML. De exemplu:

using System.Xml.Serialization;

// obiectul pentru serializare
Person person = new Person("Tom", 37);

// transmitem în constructor tipul clasei Person
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person));

// obținem fluxul în care vom scrie obiectul serializat
using (FileStream fs = new FileStream("person.xml", FileMode.OpenOrCreate))
{
   xmlSerializer.Serialize(fs, person);

   Console.WriteLine("Object has been serialized");
}

// [Serializable]
public class Person
{
   public string Name { get; set; } = "Undefined";
   public int Age { get; set; } = 1;

   public Person() { }
   public Person(string name, int age)
   {
       Name = name;
       Age = age;
   }
}

Așadar, clasa Person este publică, are proprietăți publice și un constructor fără parametri, astfel încât obiectele acestei clase sunt supuse serializării. La crearea obiectului XmlSerializer, transmitem tipul clasei Person în constructor.

În metoda Serialize, se transmite fluxul de fișier pentru salvarea datelor în fișierul person.xml și obiectul Person care va fi salvat în acest fișier. După finalizarea programului, dacă deschidem fișierul person.xml, vom vedea conținutul obiectului nostru:

<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <Name>Tom</Name>
 <Age>37</Age>
</Person>

Deserializarea

Pentru deserializarea datelor XML în obiecte C#, se folosește metoda Deserialize(). Una dintre versiunile acestei metode este:

object? Deserialize (Stream stream);

Ca parametru, în metodă se transmite un obiect Stream care conține datele în format XML. Rezultatul metodei este obiectul deserializat.

De exemplu, să deserializăm datele din fișierul person.xml creat anterior:

using System.Xml.Serialization;

XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person));

// deserializăm obiectul
using (FileStream fs = new FileStream("person.xml", FileMode.OpenOrCreate))
{
   Person? person = xmlSerializer.Deserialize(fs) as Person;
   Console.WriteLine($"Name: {person?.Name}  Age: {person?.Age}");
}

public class Person
{
   public string Name { get; set; } = "Undefined";
   public int Age { get; set; } = 1;

   public Person() { }
   public Person(string name, int age)
   {
       Name = name;
       Age = age;
   }
}

Serializarea și deserializarea colecțiilor

În mod similar, putem serializa un tablou sau o colecție de obiecte:

using System.Xml.Serialization;

Person[] people = new Person[]
{
   new Person("Tom", 37),
   new Person("Bob", 41)
};

XmlSerializer formatter = new XmlSerializer(typeof(Person[]));
// salvarea tabloului în fișier
using (FileStream fs = new FileStream("people.xml", FileMode.OpenOrCreate))
{
   formatter.Serialize(fs, people);
}
// restaurarea tabloului din fișier
using (FileStream fs = new FileStream("people.xml", FileMode.OpenOrCreate))
{
   Person[]? newpeople = formatter.Deserialize(fs) as Person[];

   if(newpeople != null)
   {
       foreach (Person person in newpeople)
       {
           Console.WriteLine($"Name: {person.Name} --- Age: {person.Age}");
       }
   }
}

public class Person
{
   public string Name { get; set; } = "Undefined";
   public int Age { get; set; } = 1;

   public Person() { }
   public Person(string name, int age)
   {
       Name = name;
       Age = age;
   }
}

Afișarea în consolă:

Name: Tom --- Age: 37
Name: Bob --- Age: 41

Acesta a fost un obiect simplu. Totuși, lucrul cu obiecte mai complexe este la fel de simplu. De exemplu:

using System.Xml.Serialization;

var microsoft = new Company("Microsoft");
var google = new Company("Google");

Person[] people = new Person[]
{
   new Person("Tom", 37, microsoft),
   new Person("Bob", 41, google)
};

XmlSerializer formatter = new XmlSerializer(typeof(Person[]));

using (FileStream fs = new FileStream("people.xml", FileMode.OpenOrCreate))
{
   formatter.Serialize(fs, people);
}

using (FileStream fs = new FileStream("people.xml", FileMode.OpenOrCreate))
{
   Person[]? newpeople = formatter.Deserialize(fs) as Person[];

   if(newpeople != null)
   {
       foreach (Person person in newpeople)
       {
           Console.WriteLine($"Name: {person.Name}");
           Console.WriteLine($"Age: {person.Age}");
           Console.WriteLine($"Company: {person.Company.Name}");
       }
   }
}

public class Company
{
   public string Name { get; set; } = "Undefined";

   // constructor standard fără parametri
   public Company() { }

   public Company(string name) => Name = name;
}
public class Person
{
   public string Name { get; set; } = "Undefined";
   public int Age { get; set; } = 1;
   public Company Company { get; set; } = new Company();

   public Person() { }
   public Person(string name, int age, Company company)
   {
       Name = name;
       Age = age;
       Company = company;
   }
}

Clasa Person conține o proprietate Company, care va stoca un obiect al clasei Company. Membrii clasei Company sunt declarați cu modificatorul public, iar constructorul standard fără parametri este, de asemenea, prezent. În cele din urmă, după serializare, vom obține următorul document XML:

<?xml version="1.0"?>
<ArrayOfPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <Person>
   <Name>Tom</Name>
   <Age>37</Age>
   <Company>
     <Name>Microsoft</Name>
   </Company>
 </Person>
 <Person>
   <Name>Bob</Name>
   <Age>41</Age>
   <Company>
     <Name>Google</Name>
   </Company>
 </Person>
</ArrayOfPerson>
← Lecția anterioară Lecția următoare →