Site logo
Site logo
Programmieren aus Leidenschaft
Programmieren aus Leidenschaft

XML durch Serialisierung


Serialisierung ist ein Verfahren, mit dem die aktuellen Eigenschaftenswerte eines Objektes gespeichert und zu einem späteren Zeitpunkt wieder geladen werden können. War Serialisierung in der Vergangenheit ein sehr komplizierter Vorgang so wurde jetzt vieles vereinfacht und es braucht nur wenige Schritte um ein Objekt in eine XML-Datei zu serialisieren.

Zuerst benötigt man zwei Namespaces, die für die Serialisierung wichtig sind.
using System.IO;
using System.Xml.Serialization;
Ziel dieses Beispieles ist es, den Inhalt einer generischen Liste zu speichern und später den Inhalt neu einzulesen. Um es etwas anspruchsvoller zu gestalten entwerfen wir zunächst eine neue Klasse, aus der wir die Liste aufbauen werden.
public class Person
{
   public string name;
   public string vorname;

   public Person ()
   {
   }

   public Person (string _name , string _vorname)
   {
      this.name = _name;
      this.vorname = _vorname;
   }
}
Für einen erfahrenen Programmierer sollte diese Klasse keine Überraschung darstellen. Aus Gründen der Bequemlichkeit gibt es hier einen zweiten Konstruktor, der uns das Erstellen von neuen Listenelemente etwas vereinfacht. Auch das Instanzieren der Liste und das Hinzufügen von Elementen sollte bekannt sein.
List meinePersonen = new List();
meinePersonen.Add(new Person("Muster", "Max"));
meinePersonen.Add(new Person("Meier", "Werner"));
Um diese Liste nun tatsächlich als Datei abzuspeichern, benötigen wir zwei weitere Objekte. Einen XmlSerializer und einen StreamWriter.
XmlSerializer meinSerializer = new XmlSerializer(typeof(List));
StreamWriter meinStream = new StreamWriter("d:\\klasse.xml");
meinSerializer.Serialize(meinStream, meinePersonen);
meinStream.Close();
Schon beim Instanzieren bekommt der XmlSerializer den Objekttyp mitgeteilt, den es abzuspeichern gilt. Hier ist es natürlich eine Liste vom Typ "Person". Der Befehl "Serialize" speichert die Datei dann endgültig. Allerdings benötigt er als weiteren Parameter einen Stream, der die Daten aufnimmt. Diesen Teil übernimmt der StreamWriter, der nach Abschluß des Vorganges wieder geschlossen wird.

Wie man sieht, ist das Serialisieren unserer Personenliste mit wenigen Befehlen realisierbar. Allerdings gibt es einige Punkte, die man beachten muss. Generell sind nur Objekte serialisierbar, die als "public" deklariert sind. Würden wir unsere Klasse "Person" auf "private" ändern, ist dies nicht mehr möglich und wir bekämen eine Fehlermeldung. Etwas anders verhält es sich mit den Feldern der Klassen. Setzen wir beispielsweise "name" auf "private", so wird dieses Feld nicht serialisiert und ist in der gespeicherten Datei nicht mehr enthalten. Nun kann es durchaus möglich sein, dass man gar nicht alle Felder eines Objektes serialisieren will, sie aber trotzdem als "public" deklariert sein müssen. Will man dies erreichen kann man das Attribut "XmlIgnore" benutzen.
[XmlIgnore] public string name;
Dieses Feld wird dann bei der Serialisierung ignoriert und nicht mit abgespeichert.

Um aus der gespeicherten Datei wieder eine Personenliste zu machen, benötigt man den "Deserialize" Befehl des XmlSerializer. Da die Datei dazu geladen werden muss kommt hier ein StreamReader zum Einsatz.
XmlSerializer meinSerializer = new XmlSerializer( typeof(List) );
StreamReader meinStream = new StreamReader("d:\\klasse.xml");
meinePersonen = meinSerializer.Deserialize(meinStream) as List;
meinStream.Close();
Es ist also durchaus möglich, ohne viel Aufwand den Inhalt auch komplexer Objekte (z. B. Klassen oder Listen) zu serialisieren und in eine XML-Datei zu schreiben. Auch das spätere Einlesen benötigt nur wenig Programmierarbeit.

Der Vollständigkeit halber hier noch der Inhalt der XML-Datei die wir erzeugt haben.
<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Person>
<name>Muster</name>
<vorname>Max</vorname>
</Person>
<Person>
<name>Meier</name>
<vorname>Werner</vorname>
</Person>
</ArrayOfPerson>