Deserialisierung von XML in Java

Liebe/-r Experte/-in,

als Hobby versuche ich mich gerade an meiner ersten Android-Anwendung und muss mit dieser ein XML parsen. Da das XML an sich nicht wirklich groß ist, dafür aber recht kompliziert, will ich auf SAX als Parser verzichten. Stattdessen probiere ich, das XML in Java-Klassen bzw. Objekte zu deserialisieren. Allerdings habe ich dabei folgendes Verständnisproblem.

In dem zu parsenden XML kann auf so ziemlich allen Ebenen folgendes Element auftreten:

Beispiel:

<?xml version="1.0" encoding="UTF-8"?>

Da aber prinzipiell ja jede XML-Ebene einer Klasse entsprechen kann (

public class ebene1

usw.), muss ich dann für jede einzelne Klasse auch die Umsetzung für das Err-Element deklarieren? Da gibt es doch bestimmt eine sauberere Lösung?

Momentan umgehe ich das folgendermaßen: ich habe eine Klasse

ApiError

erzeugt. Alle anderen Klassen () erben von dieser, damit sie das Err-Element behandeln können.

public class ApiError {
 private String code;
 private String level;
 private String text;

 public get/set...() {}
}

Aber auch das scheint mir noch zu aufwändig. Zumal ich dann nicht weiß, welche Klasse eine Instanz von ApiError erzeugt hat, wenn das Element im XML-Baum auftaucht.

Ich hoffe, dass ich mein Problem einigermaßen verständlich darstellen konnte. Falls nicht, bitte einfach nachfragen :smile: Freue mich über jeden Hinweis.

Vielen Dank,
Robert

Hallo Robert,

wenn ich dich richtig verstanden habe müsstest du mit JDom dein Problem lösen können.

schaus dir mal an.

Grüße

Benny

Hallo Robert,

ich denke ich hab verstanden was du vorhast kann aber nicht unbedingt erklären wie ich es machen würde. Ich versuch’s trotzdem.

Ich denke ich würde nicht ApiError selbst vererben, sondern mehr oder weniger dem klassischen Modell eines „Elements“ folgen, das dann vererbt wird und eine Eigenschaft „ApiError“ hat. Beim Lesen des Elements kannst du dann diese Eigenschaft setzen, sofern sie vorhanden ist. Dem ApiError selbst verpasst du eine Eigenschaft „Parent“, die du dann sozusagen rekursiv mit dem Element befüllst, das den ApiError enthält und somit sollte auch das Verweisproblem behoben sein.

Hoffe das hilft ein wenig.

Beste Grüße
Stefan

Hi, Robert

es ist - immer - gut, für eine XML-Datei ein XML-Schema zu haben, damit man nicht raten muss, was in der XML-Datei alles auftauchen könnte.

Ich habe mal schnell ein Schema für deine Datei angefertigt:

http://paste.pocoo.org/show/402203/

Für jeden complexType benötigst du eine Klasse, um die xml-Repräsentation der Daten im Speicher zu halten.

Hilft das?

Herzliche Grüße

Rolf

Hallo Rolf,

vielen Dank für deine Hilfe! Die XSD zu dem Dokument, das noch wesentlich umfangreicher ist, habe ich sogar. Der Hinweis mit dem „complexType“ war wichtig. Danke. Allerdings habe ich jetzt ein anderes Framework eingesetzt, das nicht auf Serialisierung arbeitet, sondern direkt mit XPath. Klappt auch und ist nicht so klassenlastig :smile:

Viele Grüße,
Robert

Hallo Stefan,

vielen Dank für deine Hilfe! Allerdings habe ich jetzt ein anderes Framework eingesetzt, das nicht auf Serialisierung arbeitet, sondern direkt mit XPath. Klappt auch und ist nicht so klassenlastig :smile:

Viele Grüße,
Robert

Ich denke ich würde nicht ApiError selbst vererben, sondern
mehr oder weniger dem klassischen Modell eines „Elements“
folgen, das dann vererbt wird und eine Eigenschaft „ApiError“
hat. Beim Lesen des Elements kannst du dann diese Eigenschaft
setzen, sofern sie vorhanden ist. Dem ApiError selbst verpasst
du eine Eigenschaft „Parent“, die du dann sozusagen rekursiv
mit dem Element befüllst, das den ApiError enthält und somit
sollte auch das Verweisproblem behoben sein.

Hoffe das hilft ein wenig.

Beste Grüße
Stefan

Hallo Benny,

vielen Dank für deine Hilfe! Allerdings habe ich jetzt ein anderes Framework eingesetzt, das nicht auf Serialisierung arbeitet, sondern direkt mit XPath. Klappt auch und ist nicht so klassenlastig :smile:

Viele Grüße,
Robert

Hi, Robert

ja, denke, das ist besser so, wie du es machst. Auch ich setze schon für das Parsen einfacher XML-Dateien ein Framework ein:

xmlbeans von Apache. Damit kannst du aus einem Schema direkt Java-Klassen zum Lesen und Schreiben erzeugen. Viel einfacher zu handhaben, als SAX-Events. Ich denke SAX-Events stammt aus Zeiten, als Daten(banken) noch wesentlich größer waren, als der verfügbare Hauptspeicher. Das ist nicht mehr der Fall. Sämtliche Daten passen in den Speicher. Möglicherweise muss man der JVM -Xmx1G oder -Xmx512M mitgeben, damit es passt.

erstmal erscheint dein ansatz korrekt. wenn jede klasse einen ApiError beinhalten kann, macht es sinn diese klassen von ApiError abzuleiten.

durch die vererbung erben die klassen ja nur die variablen und die get/set funktionen, aber sind trotzdem eigenständige instanzen der jeweiligen klassen z.b. Ebene1, etc. daher kannst du anhand des klassen namens bzw. typs sehr wohl unterscheiden wo dieser fehler aufgetreten ist.

du kannst auch in der ApiError klasse noch eine „source“ variable einführen:

protected String source;

welche du in den jeweiligen konstruktoren mit einem eindeutigen wert belegst:

this.source = „ApiError“;

this.source = „Ebene1 Fehler“;

this.source = „Ebene2.Fehler“;

etc.