3 Serialisierung und XML

Ähnliche Dokumente
XML Schema und Objektorientierung

C# Programmierung. Eine Einführung in das.net Framework. C# Programmierung - Tag 4: Kombination OOP/.NET

Repetitorium Informatik (Java)

Institut für Programmierung und Reaktive Systeme. Java 6. Markus Reschke

Objektorientierte Programmierung Studiengang Medieninformatik

Statische und Nichtstatische Methoden Properties/ Eigenschaften

Objektorientierte Programmierung. Kapitel 22: Aufzählungstypen (Enumeration Types)

Angewandte Softwareentwicklung Serialisierung

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Vererbung I. Kfz Eigenschaften und Methoden der Klasse Kfz Lkw. Pkw. Eigenschaften und Methoden der Klasse Kfz

II. Grundlagen der Programmierung. Beispiel: Merge Sort. Beispiel: Merge Sort (Forts. ) Beispiel: Merge Sort (Forts. )

Delegatesund Ereignisse

Java Einführung Methoden in Klassen

FH D. Objektorientierte Programmierung in Java FH D FH D. Prof. Dr. Ing. André Stuhlsatz. Referenzen. Referenzen

Übung 1 mit C# 6.0 MATTHIAS RONCORONI

Java Einführung Klassendefinitionen

XAML Extensible Application Markup Language. Manuel Naujoks (IB3)

Grundlagen der OO- Programmierung in C#

Programmieren in Java

Einführung in die Programmierung 1

Informatik B. Vorlesung 14 Serialisierung, Autoboxing. Dr. Ralf Kunze

7. Übung Informatik II - Objektorientierte Programmierung

Neben der Verwendung von Klassen ist Vererbung ein wichtiges Merkmal objektorientierter

ADT: Java Collections und ArrayList

C++ - Objektorientierte Programmierung Konstruktoren und Destruktoren

Einführung in die Java- Programmierung

Tag 4 Repetitorium Informatik (Java)

Kapitel 9 Schnittstellen

Fragen zur OOP in Java

Sichtbarkeit & statische Methoden. Einsatz von Sichtbarkeit Einsatz statischer Methoden programmatische Realisierung 2 Beispielaufgaben

Klausur Software-Entwicklung März 01

Ausnahmen. Exceptions. Definition Ausnahmen erzeugen Ausnahmen abfangen Ausnahmen weiterleiten. Dr. Beatrice Amrhein

Folienpaket 7 Themenschwerpunkte: Methoden in OOP /2016 Dr. Daniel Haase - Vorkurse Informatik V3/V4

Methoden und Klassen. Silke Trißl Wissensmanagement in der Bioinformatik

Martin Unold INFORMATIK. Geoinformatik und Vermessung

Silke Trißl Wissensmanagement in der Bioinformatik. Objektorientierte Programmierung (OOP) Vorstellung wie in der realen Welt: Farbe Hubraum Tank...

Java Einführung Methoden. Kapitel 6

Einstieg in die Informatik mit Java

C# - Einführung in die Programmiersprache Methoden. Leibniz Universität IT Services

Software Engineering Klassendiagramme Einführung

Klausur Grundlagen der Programmierung

1 Klassen anlegen und Objekte erzeugen

Prof. W. Henrich Seite 1

Vorkurs C++ Programmierung

12. Java Klassen. Klassen - Technisch. Beispiel: Erdbebendaten. Klassen - Konzeptuell

Problemstellung. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 24: Reflection 1. IDE und automatische Tests.

Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden.

Silke Trißl, Prof. Ulf Leser Wissensmanagement in der Bioinformatik. Jede Applikation braucht eine Klasse mit einer main-methode

Programmieren II. Innere Klassen. Heusch 10, Ratz 5.2.1, Institut für Angewandte Informatik

Objektorientierte Programmierung Studiengang Medieninformatik

Programmieren in C/C++ und MATLAB

Methoden und Wrapperklassen

Programmierkurs Java

Einstieg in die Informatik mit Java

3 Objektorientierte Konzepte in Java

Vererbung. Martin Wirsing. Ziele. Vererbung

! 1. Rekursive Algorithmen.! 2. Rekursive (dynamische) Datenstrukturen. II.3.2 Rekursive Datenstrukturen - 1 -

5. Tutorium zu Programmieren

14. Java Klassen. Klassen (Java) vs. Records (Pascal) Klassen - Konzeptuell. Klassen - Technisch

Objektserialisierung

C++ Teil 12. Sven Groß. 18. Jan Sven Groß (IGPM, RWTH Aachen) C++ Teil Jan / 11

Vorlesung Programmieren

Grundlagen der Objektorientierten Programmierung - Statische Arrays

Felder - Arrays. Typ feldname[] = new Typ[<ganze Zahl >]; Beispiel: double vektor[] = new double[5]; auch eine Initialisierung ist möglich.

Klassen und Objekte. Einführung in Java. Folie 1 von Mai Ivo Kronenberg

Klassen und Objekte. Klassen sind Vorlagen für Objekte. Objekte haben. Attribute. Konstruktoren. Methoden. Merkblatt

Aufbau von Klassen. class punkt {...

Deklaration einer Klasse Innere innerhalb Klassen einer in Ja anderen v a Klasse

Java in Macro, SCL und Data Step

Einführung in C#.NET. 1 Übersicht. 2 Typen (Types) Dieser Artikel stammt aus dem Magazin von C++.de (

Java: Vererbung. Teil 3: super()

Umsetzung einer Klassenkarte in einer Programmiersprache

Kapitel 9: Klassen und höhere Datentypen. Klassen und höhere. Objekte, Felder, Methoden. Küchlin/Weber: Einführung in die Informatik

Objektorientierte Programmierung und Klassen

Institut für Programmierung und Reaktive Systeme. Java 2. Markus Reschke

Einstieg in die Informatik mit Java

1 Klassen anlegen und Objekte erzeugen

Polymorphismus 179. Function.h. #include <string>

Ausgabe:

Schlussendlich geben wir die Listen aus. Es kommt zu folgender Ausgabe:

Objektorientierung. Programmierstarthilfe WS 2010/11 Fakultät für Ingenieurwissenschaften und Informatik

Programmierkurs C++ Konstruktor, Statische Methoden Namespaces

Die Klasse java.lang.object. Thorsten Treffer

Vererbung & Schnittstellen in C#

Einführung in die Programmierung Vorlesungsprüfung

Objektorientierung (OO)

ADT: Verkettete Listen

Versuchsziele Kenntnisse in der Anwendung von: Sortieren mit Klassen Benutzung von generischen Klassen o Definition o Sortierung.

Klassen mit Instanzmethoden

Algorithmen und Datenstrukturen

Tag 4 Repetitorium Informatik (Java)

Die Sprache C# Datentypen, Speicherverwaltung Grundelemente der Sprache. Dr. Beatrice Amrhein

Kapitel 8. Programmierkurs. Methoden. 8.1 Methoden

C++ Notnagel. Ziel, Inhalt. Programmieren in C++

Objektorientierte Programmierung mit C++ SS 2007

Transkript:

.NET Essentials 3 Serialisierung und XML Einführung Serialisierung bedeutet, vereinfacht ausgedrückt, das»überleben«der Objekte nach einem Programmende oder die Verpackung der Objekte für den Transport über Prozess- und Maschinengrenzen bei einem Remote-Aufruf. Für OOP-Systeme, die Mechanismen für solche Aktionen boten, wurde dies dadurch gewährleistet, dass aktuelle Daten und Variableninhalte in eine Datei geschrieben wurden. Der Code lag in der ausführbaren Datei vor und nach dem erneuten Start wurde die Datendatei geöffnet und der Entwickler hatte die Aufgabe, alle Daten wieder in die richtigen Strukturen zu laden. Innerhalb des.net-frameworks ist XML das Rückgrat für die Serialisierung von Klasseninstanzen. Die für die Nutzung dieser Funktionalität benötigten Namensräume des.net-frameworks sind System.XML und System.XML.Serialization. Terminologie Serialisierung mit XmlSerializer Die Klasse XmlSerializer ist für die Serialisierung einer Instanz in eine XML-Datei bzw. den umgekehrten Weg zurück zu einer Instanz zuständig. In der einfachsten Form erhält der Konstruktor einen Parameter mit dem Typ des Objekts, für das er zuständig sein soll. Hier eine sehr einfache Demoklasse, die in eine XML-Datei serialisiert werden soll: // eine einfache demo-klasse public class SimpleDemo public string Kennzeichen; public int KmStand; public double Verbrauch; Listing 3.1: Die erste Demoklasse Als Ziel für die Serialisierung können Sie bei der Methode Serialize des XmlSerializer drei mögliche Ausgabetypen spezifizieren: Einen XmlWriter oder einen Nachfahren Einen Stream oder einen Nachfahren Einen TextWriter oder einen Nachfahren 27

.NET 3 Serialisierung und XML Essentials Nachdem es hier nur um das Herauschreiben der Instanzdaten geht, verwenden wir im Listing einen XmlWriter, da dieser als reine vorwärtsgerichtete Nur-Schreiben-Klasse den geringsten Overhead besitzt. Hier der Code, mit dem die Instanz serialisiert wird: class TestClass static void Main(string[] args) XmlSerializer ser = new XmlSerializer(typeof(SimpleDemo)); XmlTextWriter tw = new XmlTextWriter("ausgabe.xml", null); SimpleDemo d = new SimpleDemo(); d.kennzeichen = "LA-DY 2002"; d.kmstand = 45800; d.verbrauch = 7.85; ser.serialize(tw, d); tw.close(); Console.WriteLine("Objekt serialisiert."); Console.Write("\nPress a key..."); Console.ReadLine(); Listing 3.2: Serialisierung in eine XML-Datei Nach dem erfolgreichen Durchlaufen des Codes liegt die Datei auf der Platte und Sie können sich deren Inhalt ansehen: Objekte als XML <?xml version="1.0"?> <SimpleDemo xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <Kennzeichen>LA-DY 2002</Kennzeichen> <KmStand>45800</KmStand> <Verbrauch>7.85</Verbrauch> </SimpleDemo> Listing 3.3: Der Inhalt der XML-Ausgabedatei Sie erkennen, dass das Wurzelelement den Namen der Klasse trägt und die einzelnen Elemente mit ihrer Bezeichnung den Namen der Felder entsprechen. Zusätzlich werden die beiden Deklarationen der Namens- 28

.NET Essentials räume für XML-Schemas und XML-Schemainstanzen mit in das Wurzelelement aufgenommen (mehr zu Namensräumen erfahren Sie im Kapitel»XML-Namensräume«). Deserialisierung mit XmlSerializer Um aus einer XML-Datei eine Instanz einer Klasse zu laden, gehen sie einfach den umgekehrten Weg. class TestClass static void Main(string[] args) XmlSerializer ser = new XmlSerializer(typeof(SimpleDemo)); // diesmal einen reader einsetzen XmlTextReader rdr = new XmlTextReader("ausgabe.xml"); SimpleDemo d; // klasseninstanz aus dem serializer d = ser.deserialize(rdr) as SimpleDemo; rdr.close(); // instanzdaten ausgeben Console.WriteLine("Objekt deserialisiert:"); Console.WriteLine(d.Kennzeichen); Console.WriteLine(d.KmStand); Console.WriteLine(d.Verbrauch); Console.Write("\nPress a key..."); Console.ReadLine(); Listing 3.4: Deserialisierung aus einer XML-Datei Dieser Code produziert die in Abbildung 3.1 zu sehende Ausgabe und zeigt damit, dass so sehr leicht aus einer XML-Datei eine Objektinstanz erzeugt werden kann. Ungleiche Dokumente und Klassen Falls ein Schema vorliegt, können Sie mit dem folgenden Aufruf aus dem Schema eine passende Klasse erstellen lassen, um dieses Problem zu vermeiden. 29

.NET 3 Serialisierung und XML Essentials Abbildung 3.1: Die Ausgabe des Deserialisierungsbeispiels Das Tool xsd.exe xsd schema0.xsd /classes Anschliessend wird eine Datei schema0.cs erzeugt, die eine Klasse mit den aus dem Schema gewonnen Feldern enthält. //----------------------------------------------------- // <autogenerated> // This code was generated by a tool. // Runtime Version: 1.0.3705.0 // // Changes to this file may cause // incorrect behavior and will be lost if // the code is regenerated. // </autogenerated> //----------------------------------------------------- // // This source code was auto-generated by xsd, Version=1.0.3705.0. // using System.XML.Serialization; /// <remarks/> [System.XML.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)] public class SimpleDemo /// <remarks/> public string Kennzeichen; /// <remarks/> public int KmStand; /// <remarks/> public System.Double Verbrauch; Listing 3.5: Automatisch aus einem Schema erzeugte Klasse 30

.NET Essentials Was aber passiert nun, wenn die Definition der Klasse nicht mit dem Aufbau der Datei übereinstimmt? Eine Möglichkeit wäre es, nur Dateien anzunehmen, deren Aufbau genau der Klasse entspricht, indem für die Klasse ein Schema erstellt und das Dokument damit validiert wird. Ein Beispiel dafür finden Sie im Kapitel über die Validierung von XML-Dokumenten. Für den anderen Fall wird die XML-Datei um ein zusätzliches Element ergänzt, das in der Klasse nicht vorhanden ist. Ebenso wird die Klasse um ein weiteres Feld ergänzt, das in der XML-Datei nicht vorhanden ist. Zusätzlicher Inhalt in der XML-Datei <?xml version="1.0"?> <SimpleDemo xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <Kennzeichen>LA-DY 2002</Kennzeichen> <KmStand>45800</KmStand> <Leistung>108</Leistung> <Verbrauch>7.85</Verbrauch> </SimpleDemo> Listing 3.6: Die geänderte XML-Datei // eine einfache demo-klasse public class SimpleDemo public string Kennzeichen; public int KmStand; public double Verbrauch; public string Hersteller; Listing 3.7: Die geänderte Klasse mit dem neuen Feld Bei der Ausführung des Programms erfolgt keine Fehlermeldung und die Ausgabe zeigt das Standardverhalten bei der Behandlung unbekannter Elemente in der XML-Datei: Abbildung 3.2: Deserialisierung mit den geänderten Daten 31

.NET 3 Serialisierung und XML Essentials Elemente ignorieren Zusätzlich vorhandene Elemente werden also bei der Deserialisierung ignoriert, Felder in der Klasse ohne einen Inhalt in der XML-Datei werden von der Laufzeitumgebung bei der Erzeugung der Instanz initialisiert, bekommen dann aber keinen Wert aus der XML-Datei zugewiesen. Dieses Verhalten lässt sich, wie in den spätereren Abschnitten gezeigt, auch steuern und beinflussen. 3.1 XML-Serialisierung im Detail Steuerung der XML-Struktur Den Serialisierungsprozess, genauer die Erstellung der XML-Datei, können Sie über den Einsatz verschiedener Attribute steuern. So möchten Sie vielleicht einige Felder der Klasse nicht als eigene Unterelemente, sondern als Attribute des Klassenelementes rendern lassen oder für einige Elemente den Datentyp ändern. Serialisierungs-Attribute Um das Wurzelelement der XML-Datei zu ändern, benutzen Sie vor der Klasse das Attribut [XmlRoot()]. Das Attribut [XmlElement] dient der Definition eines anderen Elementnamens, der vom Namen des Feldes abweicht. Mit Hilfe des Attributes [XmlAttribute] können Sie angeben, dass ein Feld nicht als eigenes Element, sondern als Attribut des umgebenden Elternelements gerendert wird. // eine einfache demo-klasse [XmlRoot(ElementName = "root")] public class SimpleDemo public string Kennzeichen; public int KmStand; [XmlIgnore] public double Verbrauch; [XmlAttribute(AttributeName = "marke")] public string Hersteller; Listing 3.8: Die Klasse mit XML-Steuerungsattributen Wird die geänderte Klasse jetzt serialisiert, enthält die XML-Datei die neuen Daten, wobei das mit dem Attribut [XmlIgnore] deklarierte Feld aus der Datei ausgelassen wird. <?xml version="1.0"?> <root xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" marke="renault"> 32

XML-Serialisierung im Detail.NET Essentials <Kennzeichen>LA-DY 2002</Kennzeichen> <KmStand>45800</KmStand> </root> Listing 3.9: Der neue Inhalt der XML-Datei Serialisierung komplexerer Datentypen Für die Serialisierung von Datentypen wie Eigenschaften, Arrays, geschachtelten Objekten usw. gilt im Prinzip das bereits weiter oben gesagte. Für die folgenden Beispiele wird eine etwas erweiterte Klassendefinition benutzt, die über eine öffentliche Eigenschaft, ein Array und Konstruktoren verfügt. Hier der Teil der Klassendefinition mit den entsprechenden Feldern: // demo-klasse für die serialisierung public class DemoClass // private felder der klasse private int fid; private int findentlevel = 0; // öffentliche felder public string StrField = "Nur ein String"; public System.UInt32[] liste = 1,3,5,7,11,13,17,19; // konstruktoren public DemoClass() public DemoClass(int theid) fid = theid; // eine öffentliche eigenschaft public int IndentLevel get return findentlevel; set findentlevel = value; Listing 3.10: Der erste Teil der erweiterten Klassendefinition Diese Klasse soll in der Lage sein, sich selbst zu serialisieren und über eine statische Methode aus einer anzugebenden XML-Datei die Deserialisierung durchzuführen. Dies wird in die beiden Methoden SaveToXml und LoadFromXml eingepackt. 33

.NET 3 Serialisierung und XML Essentials // serialisieren in eine xml-datei public void SaveToXml(string filename) XmlSerializer ser = new XmlSerializer(typeof(DemoClass)); // einen xmlwriter einsetzen XmlTextWriter xml = new XmlTextWriter(filename, null); xml.formatting = Formatting.Indented; xml.indentation = 4; xml.indentchar = (char)32; // klasseninsanz serialisieren ser.serialize(xml, this); xml.close(); // deserialisieren aus einer xml-datei public static object LoadFromXml(string filename) XmlSerializer ser = new XmlSerializer(typeof(DemoClass)); XmlTextReader rdr = new XmlTextReader(filename); if(ser.candeserialize(rdr)) return ser.deserialize(rdr); else return null; // ende der klassendefinition Listing 3.11: Die beiden Wrapper für die Serialisierung Arrays serialisieren Wird eine Instanz dieser Klasse über den Aufruf von SaveToXml in eine XML-Datei geschrieben, wird eine öffentliche Eigenschaft als XML-Element mit dem Namen dieser Eigenschaft geschrieben (also analog zu einem normalen öffentlichen Feld). Das Array wird als XML-Element mit dem Namen des Arrays erstellt und die einzelnen Elemente dieses Arrays werden als Unterelemente, jeweils mit dem Namen des Datentyps, in die Datei geschrieben. Hier die erstellte XML-Datei: <?xml version="1.0"?> <DemoClass xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <StrField>Hallo!!</StrField> 34

XML-Serialisierung im Detail.NET Essentials <liste> <unsignedint>1</unsignedint> <unsignedint>3</unsignedint> <unsignedint>5</unsignedint> <unsignedint>7</unsignedint> <unsignedint>11</unsignedint> <unsignedint>13</unsignedint> <unsignedint>17</unsignedint> <unsignedint>19</unsignedint> </liste> <IndentLevel>4</IndentLevel> </DemoClass> Listing 3.12: Die serialisierte Instanz als XML-Datei Für die Deserialisierung muss ein parameterloser Konstruktor in der Klasse vorhanden sein (Sie haben sich vielleicht schon darüber gewundert). Da der XmlSerializer aus den Daten der XML-Datei nicht erschließen kann, welcher Konstruktor mit welchen Parametern aufzurufen ist, muss ein Konstruktor ohne Parameter vorhanden sein, der dann aufgerufen wird, um die Instanz zu erstellen. Über das Einlesen der restlichen XML-Elemente werden anschließend die gleichlautenden öffentlichen Felder und Eigenschaften gesetzt. Unbekannten XML-Inhalt behandeln Sollte in der XML-Datei zusätzlicher Inhalt vorhanden sein (in Form von Elementen, Attributen oder z.b. CDATA-Knoten), dann können Sie über Ereignisbehandlungsroutinen das Standardverhalten der Deserialisierung ändern. Sind keine solchen Eventhandler definiert, wird zusätzlicher Inhalt in der XML-Datei einfach ignoriert und für Felder der Klasse, für die kein Element in der Datei vorhanden ist, wird keine Zuweisung durchgeführt. Für die Steuerung dieses Verhaltens definiert die Klasse XmlSerializer drei Ereignisse: UnknownElement, UnknownAttribute und UnknownNode. Erstellen Sie eine Ereignisbehandlungsroutine für das gewünschte Ereignis, wird diese Methode dann aufgerufen. Für eine Demonstration erweitern wir die Datei aus Listing 3.3 um zusätzliche Elemente. Unknown-Ereignisse <?xml version="1.0"?> <SimpleDemo xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <Kennzeichen>LA-DY 2002</Kennzeichen> <Hersteller>Renault</Hersteller> <KmStand>45800</KmStand> <Verbrauch>7.85</Verbrauch> 35

.NET 3 Serialisierung und XML Essentials <Klimaanlage /> </SimpleDemo> Listing 3.13: Der neue Inhalt der XML-Datei Jetzt wird dafür eine Ereignisbehandlungsroutine definiert: public void XmlElementEventHandler(object sender, XmlElementEventArgs args) Console.Write("Bei der Deserialisierung von 0 ", args.objectbeingdeserialized.tostring()); Console.Write("wurde ein Element <0> gefunden.", args.element.localname); Console.WriteLine(); Listing 3.14: Der EventHandler für unbekannte Elemente Diese Methode wird dem XmlSerializer nach der Instantiierung eingetragen. static void Main(string[] args) XmlSerializer ser = new XmlSerializer(typeof(SimpleDemo)); XmlTextReader rdr = new XmlTextReader(@"c:\tmp\ser.xml"); ser.unknownelement += new XmlElementEventHandler(DoUnknownElement); SimpleDemo sd = (SimpleDemo)ser.Deserialize(rdr); rdr.close(); Console.WriteLine("KmStand: 0", sd.kmstand); Console.Write("\nPress a key..."); Console.ReadLine(); Listing 3.15: Eintragen der Ereignisbehandlung 36

Zusammenfassung.NET Essentials Hier das Ergebnis des Programmablaufs: Abbildung 3.3: Die unbekannten XML-Elemente werden gemeldet. 3.2 Zusammenfassung Serialisierung nach XML ist mit dem.net-framework auf einfache Art und Weise möglich, wobei Sie jederzeit in diesen Prozess eingreifen und die Serialisierung der Objektinstanzen genauer steuern können. 37