Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
programmieren:java:android:xml:start [2016/02/18 06:40] – [Model-Klassen] martinprogrammieren:java:android:xml:start [2021/12/29 10:40] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== Objekte <-> XML (Serialisierung/Deserialisierung) ======
 +Im Folgenden wird beschrieben, wie man mithilfe der Open-Source-Bibliothek [[http://simple.sourceforge.net/home.php|Simple XML]] einen Objektbaum in eine XML-Zeichenkette umwandelt und umgekehrt eine XML-Zeichenkette in einen Objektbaum. \\ 
 +Die beschriebene Vorgehensweise deckt nur einen sehr kleinen Funktionsumfang von [[http://simple.sourceforge.net/home.php|Simple XML]] ab. Es wird dringend empfohlen, das sehr verständliche [[http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php|Tutorial]] durchzuarbeiten.
 +
 +===== Aufnahme der Bibliothek ins Projekt =====
 +Auf der [[http://simple.sourceforge.net/download.php|Downloadseite des Projekts]] kann ein Archiv heruntergeladen werden, das die Simple XML-Bibliothek, die Quelltexte und die Dokumentation enthält. In der Entwicklungsumgebung benötigen wir nur die Bibliothek selbst, also die Datei ''simple-xmml-2.7.1.jar''. Sie muss in den Ordner ''libs'' des Projekts kopiert werden. ("Reinziehen" vom Dateiexplorer in den Package Explorer von Eclipse oder Kopieren im Dateisystem und anschließend "F5" aufs Projekt im Package-Explorer).
 +
 +===== Model-Klassen =====
 +Damit Objekte mit Simple XML serialisiert und deserialisiert werden können, müssen sie mit Annotations versehen werden, die angeben, welche Attribute wie umgewandelt werden sollen. Hier ein Beispiel:
 +<code java>
 +@Root
 +public class Buch {
 +
 + @Element
 + private String titel;
 +
 + @Element
 + private String autor;
 +
 + @Element
 + private int seitenzahl;
 +
 + public Buch() {
 + };
 +
 + public Buch(String titel, String autor, int seitenzahl) {
 + super();
 + this.titel = titel;
 + this.autor = autor;
 + this.seitenzahl = seitenzahl;
 + }
 +
 + public String getTitel() {
 + return titel;
 + }
 +
 + public void setTitel(String titel) {
 + this.titel = titel;
 + }
 +
 + public String getAutor() {
 + return autor;
 + }
 +
 + public void setAutor(String autor) {
 + this.autor = autor;
 + }
 +
 + public int getSeitenzahl() {
 + return seitenzahl;
 + }
 +
 + public void setSeitenzahl(int seitenzahl) {
 + this.seitenzahl = seitenzahl;
 + }
 +
 + @Override
 + public String toString() {
 +
 + return "[" + titel + "; " + autor + "; " + seitenzahl + "]";
 +
 + }
 +
 +}
 +</code>
 +
 +Die Annotation ''@Root'' zeigt an, dass es sich um eine serialisierbare Klasse handelt. ''@Element'' bedeutet, dass das Attribut des Klasse als XML-Unterelement serialisiert wird (im Unterschied zu ''@Attribute''). Enthält ein Objekt eine Liste anderer Objekte, so gibt es dazu die Annotation ''@ElementList''. So besteht eine Bibliothek beispielsweise aus mehreren Büchern:
 +<code java>
 +@Root
 +public class Bibliothek {
 +
 + @Attribute
 + private String name;
 +
 + @ElementList
 + private List<Buch> buecher = new ArrayList<Buch>();
 +
 + public Bibliothek(){};
 +
 +...
 +</code>
 +
 +Ein beispielhafter Objektbaum sieht so aus:
 +<code XML>
 +<bibliothek name="CSG-Schülerbücherei">
 +   <buecher class="java.util.ArrayList">
 +      <buch>
 +         <autor>Michael Ende</autor>
 +         <titel>Jim Knopf und Lukas der Lokomotivführer</titel>
 +         <seitenzahl>327</seitenzahl>
 +      </buch>
 +      <buch>
 +         <autor>Astrid Lindgren</autor>
 +         <titel>Pippi Langstrumpf</titel>
 +         <seitenzahl>451</seitenzahl>
 +      </buch>
 +      <buch>
 +         <autor>Benno Beispiel</autor>
 +         <titel>Mathe macht Spass</titel>
 +         <seitenzahl>1265</seitenzahl>
 +      </buch>
 +   </buecher>
 +   <verlage class="java.util.ArrayList">
 +      <verlag>
 +         <name>Oettinger</name>
 +         <ort>Hamburg</ort>
 +      </verlag>
 +      <verlag>
 +         <name>Klett</name>
 +         <ort>München</ort>
 +      </verlag>
 +   </verlage>
 +</bibliothek>
 +</code>
 +
 +===== Code zum Serialisieren =====
 +Hier der Code zum Serialisieren:
 +<code java>
 +    Bibliothek bib = BeispielFactory.getBeispielBibliothek();
 +   
 +    Style style = new HyphenStyle();
 +    Format format = new Format(style);
 +    
 +    Serializer serializer = new Persister(format);
 +
 +    StringWriter writer = new StringWriter();
 +   
 +    try {
 +    serializer.write(bib, writer);
 +    Log.i("XML", writer.getBuffer().toString()); // Statt Ausgabe ins Log kann der String bspw. auch per HttpRequest an einen Server gesendet werden ...
 +   
 +    } catch (Exception ex){
 +    ausgabe.setText(ex.toString());
 +    }
 +</code>
 +
 +===== Code zum Deserialisieren =====
 +Hier der Code zum Deserialisieren:
 +<code java>
 +    String xml = ... // Von irgendwoher kommt der XML-Text...
 +   
 +    Serializer serializer = new Persister();
 +
 +    try {   
 +    Bibliothek bib = serializer.read(Bibliothek.class, xml);
 +    // bib ist der Knoten des Objektbaums, mit dem jetzt weitergearbeitet werden kann!
 +    } catch (Exception ex){
 +    ausgabe.setText(ex.toString());
 +    }
 +</code>
 +
 +
 +===== Was tun bei Objektgraphen mit Zyklen? =====
 +Das obige Vorgehen funktioniert natürlich nur bei baumförmigen Objektstrukturen. Sobald der Objektgraph Zyklen besitzt, ist eine direkte Umsetzung in einen XML-Baum nicht mehr möglich, weil ein Objekt in mehreren anderen Objekten enthalten sein kann. Hier hält Simple XML eine Lösung bereit: Es versieht alle XML-Objekte mit einem zusätzliche Attribut "id", das eine fortlaufende Nummerierung enthält. Ist ein Objekt in zwei anderen Objekte enthalten, so wird es nur als Unterelement des ersten serialisiert. Beim zweiten fügt Simple XML nur eine Referenz auf die id des Objekts ein. Vor dem Serialisieren muss dem Serializer nur eine ''CycleStrategy'' mitgegeben werden:
 +
 +<code java>
 +    Strategy strategy = new CycleStrategy("id", "ref");
 +    Serializer serializer = new Persister(strategy, format);
 +    
 +    ...
 +</code>
 +Ebenso vor dem Deserialisieren:
 +<code java>
 +    Strategy strategy = new CycleStrategy("id", "ref");
 +    Serializer serializer = new Persister(strategy);
 +...
 +</code>
 +
 +Fügt man dem obigen Objektmodell noch eine Klasse ''Verlag'' hinzu und referenziert man die Verlage sowohl als Liste beim ''Bibliothek''-Objekt als auch als Attribut jedes einzelnen Buchs, so erhält man etwa folgendes:
 +<code java>
 +public class Verlag {
 +
 + @Element
 + private String name;
 +
 + @Element
 + private String ort;
 +...
 +
 +}
 +
 +@Root
 +public class Bibliothek {
 +
 + @Attribute
 + private String name;
 +
 + @ElementList
 + private List<Verlag> verlage = new ArrayList<Verlag>();
 +
 + @ElementList
 + private List<Buch> buecher = new ArrayList<Buch>();
 +...
 +
 +}
 +
 +@Root
 +public class Buch {
 +
 + @Element
 + private String titel;
 +
 + @Element
 + private Verlag verlag;
 +
 +...
 +}
 +</code>
 +
 +Ein Beispiel für eine als XML serialisierte Bibliothek sieht dann so aus:
 +
 +<code XML>
 +<bibliothek id="0" name="CSG-Schülerbücherei">
 +   <buecher class="java.util.ArrayList" id="1">
 +      <buch id="2">
 +         <autor id="3">Michael Ende</autor>
 +         <verlag id="4">
 +            <name id="5">Oettinger</name>
 +            <ort id="6">Hamburg</ort>
 +         </verlag>
 +         <titel id="7">Jim Knopf und Lukas der Lokomotivführer</titel>
 +         <seitenzahl id="8">327</seitenzahl>
 +      </buch>
 +      <buch id="9">
 +         <autor id="10">Astrid Lindgren</autor>
 +         <verlag ref="4"/>
 +         <titel id="11">Pippi Langstrumpf</titel>
 +         <seitenzahl id="12">451</seitenzahl>
 +      </buch>
 +      <buch id="13">
 +         <autor id="14">Benno Beispiel</autor>
 +         <verlag id="15">
 +            <name id="16">Klett</name>
 +            <ort id="17">München</ort>
 +         </verlag>
 +         <titel id="18">Mathe macht Spass</titel>
 +         <seitenzahl id="19">1265</seitenzahl>
 +      </buch>
 +   </buecher>
 +   <verlage class="java.util.ArrayList" id="20">
 +      <verlag ref="4"/>
 +      <verlag ref="15"/>
 +   </verlage>
 +</bibliothek>
 +</code>
 +
 +===== Ausblick =====
 +Die Bibliothek Simple XML bietet noch weit mehr Möglichkeiten als oben gezeigt, bspw.:
 +  * XML-Elementnamen, die von den Attributnamen abweichen
 +  * Optionale XML-Elemente
 +  * Möglichkeit, Binärdaten (z.B. Grafiken) zu serialisieren, z.B. als Base64-String
 +  * Möglichkeit, CDATA-Sections in XML zu schreiben und zu lesen
 +  * Transiente Attribute (d.h. Attribute, die nicht serialisiert werden)
 +  * Aufruf bestimmter Methoden vor dem Serialisieren bzw. nach dem Serialisieren der Objekte
 +  * Serialisieren von Maps
 +  * Einfach Implementierung einer XML-basierten Template Engine
 +  * ...
 +
 +
 +
  
Drucken/exportieren
QR-Code
QR-Code programmieren:java:android:xml:start (erstellt für aktuelle Seite)