14.9 Serialisierung mit »XmlSerializer«
Bisher sind wir immer davon ausgegangen, dass die Daten bereits im XML-Format vorliegen. Das .NET Framework bietet zahlreiche Möglichkeiten, Daten in ein XML-Format zu überführen. Das können Sie sogar mit den Daten x-beliebiger Objekte umsetzen. Diese Technik wird als XML-Serialisierung bezeichnet.
In Kapitel 13 wurde bereits die binäre Serialisierung besprochen, die nun in diesem Abschnitt ihre Fortsetzung findet.
Für die XML-Serialisierung ist die Klasse XmlSerializer zuständig, die zum Namespace System.Xml.Serialization.XmlSerializer gehört. Um Objektdaten in das XML-Format überführen zu können, sind einige Einschränkungen zu beachten:
- Die zu serialisierende Klasse muss public definiert sein.
- Es werden nur public deklarierte Felder oder Eigenschaften serialisiert. Die Eigenschaften müssen den lesenden und schreibenden Zugriff zulassen.
- Die zu serialisierende Klasse muss einen öffentlichen, parameterlosen Konstruktor haben.
- Die Steuerung der XML-Serialisierung erfolgt mit Attributen, die im Namespace System.Xml.Serialization zu finden sind. Damit ist es beispielsweise möglich, bestimmte Felder vom Serialisierungsprozess auszuschließen.
- Im Gegensatz zu BinaryFormatter (siehe Kapitel 13) ist das Serializable-Attribut nicht zwingend vorgeschrieben.
Im folgenden Beispiel wird das Prinzip der XML-Serialisierung gezeigt.
// Beispiel: ..\Kapitel 14\XMLSerialisierung
using System;
using System.IO;
using System.Xml.Serialization;
class Program {
static XmlSerializer serializer;
static FileStream stream;
static void Main(string[] args) {
serializer = new XmlSerializer(typeof(Person));
Person person = new Person("Jutta Speichel", 34);
SerializeObject(person);
Person oldPerson = DeserializeObject();
Console.WriteLine("Name: " + oldPerson.Name);
Console.WriteLine("Alter: " + oldPerson.Alter);
Console.ReadLine();
}
// Objekt serialisieren
public static void SerializeObject(object obj) {
stream = new FileStream(@"D:\PersonData.xml", FileMode.Create);
serializer.Serialize(stream, obj);
stream.Close();
}
// Objekt deserialisieren
public static Person DeserializeObject() {
stream = new FileStream(@"D:\PersonData.xml", FileMode.Open);
return (Person)serializer.Deserialize(stream);
}
}
// Zu serialisierende Klasse
public class Person {
// Felder
public int Alter { get; set; }
private string _Name;
// ----- Konstruktoren -----
public Person() { }
public Person(string name, int alter) {
Name = name;
Alter = alter;
}
// Eigenschaft
public string Name {
get { return _Name; }
set { _Name = value; }
}
}
Listing 14.59 Beispielprogramm zur XML-Serialisierung
Zur Einleitung des Serialisierungsprozesses wird der Konstruktor von XmlSerializer aufgerufen, der die Type-Angabe über das zu serialisierende Objekt entgegennimmt.
XmlSerializer serializer = new XmlSerializer(typeof(Person));
Wie bei der binären Serialisierung mit der Klasse BinaryFormatter werden die Objekte mit der Methode Serialize serialisiert. Sehen wir uns den Inhalt der XML-Datei an:
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Alter>34</Alter>
<Name>Jutta Speichel</Name>
</Person>
Listing 14.60 Das Ergebnis der XML-Serialisierung aus Listing 14.59
Mit Deserialize werden die XML-Daten deserialisiert und in ein Objekt geschrieben. Da Deserialize den Typ Object ausliefert, müssen wir abschließend nur noch eine Typumwandlung in Person vornehmen.
14.9.1 XML-Serialisierung mit Attributen steuern
Die XML-Serialisierung lässt sich auch mit zusätzlichen Attributen steuern, um das Ausgabeformat der serialisierten Daten zu bestimmen. Diese Attribute gehören zum Namespace System.Xml.Serialization. Die folgende Tabelle gibt einen kleinen Überblick über die wichtigsten Attribute.
Attribut | Beschreibung |
Gibt an, dass ein bestimmter Klassen-Member als Array serialisiert werden soll. |
|
Legt den Bezeichner in der XML-Datei für den vom Array verwalteten Typ fest. |
|
Die Eigenschaft wird als XML-Attribut und nicht als XML-Element serialisiert. |
|
Dieses Attribut legt den Elementnamen in der XML-Datei fest. Standardmäßig wird der Bezeichner des Feldes verwendet. |
|
Legt fest, dass die Eigenschaft nicht serialisiert werden soll. |
|
Legt den Bezeichner des Wurzelelements der XML-Datei fest. Standardmäßig wird der Bezeichner der zu serialisierenden Klasse verwendet. |
Am folgenden Beispiel wollen wir uns die Wirkungsweise der Attribute verdeutlichen. In der Anwendung ist erneut eine Klasse Person definiert. Mehrere Objekte vom Typ Person können von einem Objekt der Klasse Personenliste verwaltet werden.
// Beispiel: ..\Kapitel 14\XMLAttributeSample
using System.Xml.Serialization;
using System.IO;
[...]
[XmlRoot("PersonenListe")]
public class PersonenListe {
[XmlElement("Listenbezeichner")]
public string Listenname;
[XmlArray("PersonenArray")]
[XmlArrayItem("PersonObjekt")]
public Person[] Personen;
// Konstruktoren
public PersonenListe() { }
public PersonenListe(string name) {
this.Listenname = name;
}
}
public class Person {
[XmlElement("Name")]
public string Zuname;
[XmlElement("Wohnort")]
public string Ort;
[XmlElement("Alter")]
public int Lebensalter;
[XmlAttribute("PersID", DataType = "string")]
public string ID;
// Konstruktoren
public Person() { }
public Person(string zuname, string ort, int alter, string id) {
this.Zuname = zuname;
this.Ort = ort;
this.Lebensalter = alter;
this.ID = id;
}
}
Listing 14.61 XML-Serialisierung mit »Attribute« beeinflussen
Ehe wir uns die Auswirkung der Attributierung ansehen, folgt hier zuerst der Code, der Person-Objekte mit XmlSerializer serialisiert:
class Program {
static void Main(string[] args) {
PersonenListe catalog = new PersonenListe("Teilnehmerliste");
catalog.Listenname = "Teilnehmerliste";
Person[] persons = new Person[2];
// Personen erzeugen
persons[0] = new Person("Peter", "Berlin", 45, "117");
persons[1] = new Person();
persons[1].Zuname = "Franz-Josef";
persons[1].Ort = "Aschaffenburg";
catalog.Personen = persons;
// serialisieren
XmlSerializer serializer = new XmlSerializer(typeof(PersonenListe));
FileStream fs = new FileStream("Personenliste.xml", FileMode.Create);
serializer.Serialize(fs, catalog);
fs.Close();
catalog = null;
// deserialisieren
fs = new FileStream("Personenliste.xml", FileMode.Open);
catalog = (PersonenListe)serializer.Deserialize(fs);
serializer.Serialize(Console.Out, catalog);
Console.ReadLine();
}
}
Listing 14.62 Serialisierung der Typen aus Listing 14.61
Das Array persons beschreibt ein Array von Person-Objekten, das zwei Objekte dieses Typs enthält. Die Referenz auf persons wird der Eigenschaft Personen eines PersonenListe-Objekts zugewiesen. Danach erfolgt die Serialisierung mit XmlSerializer in eine XML-Datei.
Nach der Serialisierung wird die Datei deserialisiert und ein serialisierender Datenstrom erzeugt, der in der Konsole seinen Abnehmer findet. So können wir uns den Inhalt des XML-Stroms direkt im Konsolenfenster ansehen, ohne die XML-Datei öffnen zu müssen (siehe Abbildung 14.12).
Abbildung 14.12 Ausgabe der Listings 14.61 und 14.62
Beachten Sie, wie die Verwendung der Attribute Einfluss auf die Elementbezeichner in der XML-Ausgabe nimmt.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.