Individuelles Wrapper-Element um Collection mit JAXB

Nexus6

Mitglied
Hallo liebe Java-Gemeinde,

ich war bisher seit einigen Wochen passiver Leser und suche nun Hilfe bei einem Problem, welches ich schon etwas laenger habe.
Bisher im Netz, auch bei den Sun-Blogs, aber nichts brauchbares gefunden habe.


Zu meinem Problem:
Ich habe ein Listenelement welches verschiedene Arten Objekten (über ein gemeinsames Interface Fahrzeug) aufnehmen kann, aber immer nur vom gleichen Typ zu einem Zeitpunkt.
Beispielhaft moechte ich zur Veranschaulichung das Problem mit Fahrzeugen vom Typ Auto und Motorrad erklaeren.
Also etwa so (in der Liste befinden sich zunaechst Fahrzeuge vom Typ Auto):
<Autos>
<Fahrzeug name="BMW"/>​
<Fahrzeug name="AUDI"/>​
...
</Autos>​

Zu einem anderem Zeitpunkt können in der Liste Fahrzeuge vom Typ Motorrad sein:
<Motorraeder>
<Fahrzeug name="KAWASKI"/>​
<Fahrzeug name="HONDA"/>​
...
</Motorraeder>​

Mit JAXB kann man die Liste mit Hilfe von Element Referenzen nach folgender Art mappen:
Java:
@XmlElementRefs(value = {
                    @XmlElementRef(type = Auto.class, name = "Fahrzeug", required = false),
                    @XmlElementRef(type = Motorrad.class, name = "Fahrzeug", required = alse)
List<Fahrzeug>fahrzeuge = new ArrayList<Fahrzeug>();

Es gibt die Annotation @XmlElementWrapper, aber diese kann nur einmal über dem Feld "Fahrzeuge"
angegeben werden.

Mir ist klar, dass das Wrapper-Element auch einfach "Fahrzeug" heissen koennte, aber das XSD - Schema gibt es halt so vor, das wenn sich in der Liste Auto-Typen befinden auch das Elternelement "Autos" heisst und bei Motorraedern eben "Motorraeder".

Wünschenswert waere beim Mapping so etwas zu machen (um es nochmal auf den Punkt zu bringen):

Java:
@XmlElementWrappers(value = { 
                               @XmlElementWrapper(type = Auto.class, name = "Autos"), 
                               @XmlElementWrapper(type = Motorrad.class, name = "Motorraeder") })
@XmlElementRefs(value = {
                    @XmlElementRef(type = Auto.class, name = "Fahrzeug", required = false),
                    @XmlElementRef(type = Motorrad.class, name = "Fahrzeug", required = alse) })
List<Fahrzeug>fahrzeuge = new ArrayList<Fahrzeug>();

So eine Annotation gibt es aber nicht.
Ich habe mir z.Z. so geholfen, dass ich neben der Liste "fahrzeuge" noch 2 weitere 'konkrete' Listen halte, in die ich die jeweiligen Elemente aus der Fahrzeug-Liste umkopiere.
Die beiden extra Listen sind mit dem jeweiligen @XmlElementWrapper Annotation versehen, damit das Gewünschte rauskommt.

Das hin- und herkopieren ist aber unschön, denn gearbeitet wird eigentlich nur mit der Fahrzeug-Liste und nur dafür gibt es Zugriffsmethoden.
Fuer das Marschallen und Unmarschallen muss ich also noch extra Aufwand treiben, damit ich dem Schema entspreche (nach Marshall) bzw. die Fahrzeug-Liste gefuellt bekomme (nach Unmaraschall).

Wie schaffe ich es, dass je nach Fahrzeugtypen in der Liste das Wrapper-Element mal "Autos" und mal "Motorraeder" heisst mit JAXB-Mitteln ?

Ich hoffe das war jetzt nicht zu lang, um das Problem zu erklaeren ;)

Vielen Dank schon mal fuer Tipps und Tricks im Voraus.
 

kidsos

Aktives Mitglied
Wie du schon selbst erkannt hast, gibt es eine derartige Annotation nicht (hab auch nichts in der JAXB API gefunden). Deine Fahrzeugliste kann ja Objekte vom Typ Auto und Motorrad aufnehmen. JAXB kann hier aber nicht unterscheiden, ob es sich da um eine reine Autoliste oder eine Motorradliste handelt. Du müsstest also mit 2 Listen arbeiten (für Autos und Motorräder), die Fahrzeugliste bräuchtest du dann nicht mehr.

Besser wüsste ich es jetzt auch nicht.
 

Noctarius

Top Contributor
Wenn es nicht zwangsläufig JAXB sein muss, sondern du die Klassen auch fix selber instanzieren und befüllen kannst könntest du dir Lycia (siehe Link in der Signatur) ansehen.
 

Nexus6

Mitglied
Vielen Dank zunächst mal für die Antworten:)

@kidsos
Ja genau, z.Z. verwende ich sogar 8 "konkrete" Listen in denen ich die jeweiligen Typen ablege.
Der Nachteil ist aber, dass mit diesen Listen nicht gearbeitet wird. D.h. die API User verwenden ausschliesslich Methoden die auf die allgemeine Liste zugreifen.
Ich muss also die jeweiligen Listen für das Java->XML bzw. XML->Java ständig hin- und herkopieren.

@Noctarius
JAXB ist erstmal gesetzt. Die selben POJOs kommen ausserdem noch für JAX-WS zum Einsatz. Dieses Framework setzt ja auch auf JAXB auf.

Vielleicht ist es ja möglich jeweils einen Interceptor zu schreiben, der dann vor dem Marshallen/Unmarschallen noch das jeweilige Element-Tag einbringt.
Immerhin würde das dann autom. im Zuge des JAXB Prozesses erledigt werden und ich kann mir das manuelle Vorgeplenkel sparen.

Grüße.
 

Noctarius

Top Contributor
Es gibt für JAXB die Möglichkeit zusätzliche Steuerinformationen mit in das XML zu schreiben (als Attribute aus dem JAXB-Schema). Wie das aber genau funktioniert weiß ich auch spontan nicht. Einfach mal suchen.
 

donnac

Mitglied
Java:
List<Fahrzeug>fahrzeuge = new ArrayList<Fahrzeug>();

Ist eigentlich eine andere Frage, aber zum Thema:
das funktioniert bei dir?
Ich bin in JAXB leider ziemlich DAU und versuche aktuell, eine ArrayList zu marshallen, wobei sich das Problem ergibt, dass JAXB von sich aus keine ArrayList's kennt:
Code:
javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.
eine jaxb.index Datei habe ich angelegt und wird auch genommen. Allerdings kann ich da ja nicht ArrayList als Klasse reinschreiben.
Gibt's da keine Möglichkeit, ausser einer Wrapper-Klasse, JAXB die ArrayList schmackhaft zu machen?
Bzw. könnte es klappen, falls ich meine
Java:
ArrayList bla = new ArrayList<x>();
durch
Java:
 List bla = new ArrayList<x>();
ersetze, kennt sich da jemand aus?
Ich frage, da es ein ziemlicher Aufwand wäre, das im gesamten Projekt zu ändern und falls jemand bereits Erfahrung hat, wäre ich sehr dankbar, wenn er sie mir mitteilen könnte :).
 

donnac

Mitglied
Egal, hat sich geklärt, habe den Fehler gefunden. :oops:
:D
zum einen funktioniert sowas nicht:
Java:
marshaller.marshal(System.out, writer);
(ich weiß nicht, wie es dazu kam...)

aber soweit kam er auch gar nicht, stattdessen kam die Exception, da ich zum die Ausgabe eines Setters verwendet hatte, anstatt dem Modelelement:
Java:
marshaller.marshal(srcControl.getContent(), writer);
So gehts richtig:
Java:
marshaller.marshal(SourceModel.getInstance(), writer);
Jetzt geht's und ich bin glücklich.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Muss ich bei JAXB immer noch eine zusaetzliche List-Wrapper Klasse erstellen wenn ich mehrere Objekte serialisieren will..? XML & JSON 1
N JAXB: Überflüssiges Wrapper-Tag für Map-Einträge XML & JSON 0
8u3631984 jaxb XML Mapper - Root Element mit Attribut XML & JSON 20
B DOMParser - Element filtern XML & JSON 1
N jdom2 - Referenz auf Nested Element XML & JSON 2
H XML Element `Class` wird nicht gelesen XML & JSON 2
F xml Element ersetzen XML & JSON 5
M Text eines Elements in XML Datei mit JAVA bearbeiten und kompletten Element-Zweig hinzufügen XML & JSON 16
W XML-Element komplett löschen XML & JSON 5
L XML nur ein Element einlesen XML & JSON 2
R XSD in einer choice mehrmals das selbe element möglich XML & JSON 5
S JDom XML ein Element hinzufügen. XML & JSON 1
ARadauer xsd ref auf element oder typen verwenden? XML & JSON 2
R cvc-complex-type.3.2.2: Attribute 'uuid' is not allowed to appear in element 'jasperReport'. XML & JSON 4
F EMF, XSD to ECore mapping, Attribute vs. Element XML & JSON 2
C xml validierung gegen xsd mit jdom: Fehlermeldung Cannot find the declaration of element ... XML & JSON 8
Landei JAXB: Wert von übergeordneten Element XML & JSON 4
N Alle namespaces ins Root Element hinauf ziehen XML & JSON 2
N Alle namespaces ins Root Element hinauf ziehen XML & JSON 2
S Validierung mit JAXB2 ohne root-element XML & JSON 10
E xml Element sortieren XML & JSON 2
T Xpath & JDOM Element Pfad ausgeben XML & JSON 2
Z XML parsen - Element mit Werten XML & JSON 2
enne87 Element-Werte werden falsch ausgelesen XML & JSON 2
M XSD - Child Element möglich, aber nicht zwingend erforderlich XML & JSON 6
W Element mit XPath @id ermitteln wenn nur ein teil der id bekannt ist XML & JSON 2
R Element - Ausgeben von Kommentar XML & JSON 4
L Element manipulieren in einem DOMResult per XPath XML & JSON 10
G mit Transformer.transform ein Element überschreiben XML & JSON 2
G XSL: Element über eine Variable ermitteln XML & JSON 4
sparrow JDom Element.getChild("Name") liefert null obwohl vorhanden XML & JSON 4
B XML-Element als String ausgeben XML & JSON 5
L Element einlesen <Telefon name="Karl">134313 XML & JSON 2
S Cannot find the declaration of element XML & JSON 2
M Jaxb Annotationen, Wert als XML Element XML & JSON 2
O XML Element mit ":" im Namen XML & JSON 23
G Element mit Text und Unterelement XML & JSON 2
S Ampersand im Jdom-Element XML & JSON 2
C jdom.Element nicht vorhanden? XML & JSON 4
W JDOM element ändern funzt nich :( [problem gelöst] XML & JSON 3
M XML einlesen - prüfen ob Element vorhanden XML & JSON 2
F choice-Element mit minOccurs=0" XML & JSON 11
X Xpath, alle Element die mit "user" beginnen auswäh XML & JSON 2
C Mehrere Element_Nodes zusammenfassen zu einem Element XML & JSON 9
K Auf bestimmtes Element im XML zugreifen XML & JSON 3
M JDOM und XPath, zu Element zugehörigen XPath-Ausdruck XML & JSON 5
H Adapter: String->Element bzw. Element->String XML & JSON 6
M JDOM Element ohne Inhalt kopieren ? XML & JSON 3
S String in element casten XML & JSON 2
S Element hinzufügen XML & JSON 2
B Element an bestimmter Stelle einfügen (JDOM) XML & JSON 8
S zum element Attribut xmlns zufügen XML & JSON 6
N bestimmtes Element auslesen - ich verzweifel XML & JSON 3
J [Newbie] [JDOM] Element aus XML entfernen klappt nicht XML & JSON 4
P [Solved] XSL: Element-Variable auslesen XML & JSON 2
Noar XSLT - Element-Wrapping XML & JSON 2
R JDOM Root-Element entfernen aber Rest behalten XML & JSON 10
S Element addContent(Element) gibts nicht XML & JSON 5
R node.getNodeValue() bringt mir komplettes CDATA-Element XML & JSON 3
W Element Liste in Root XML & JSON 5
D Text, String vor einem Root Element einfügen XML & JSON 2
W root element parsen,Hilfe! XML & JSON 5
E Element.setTextContent(String); Ersatz fuer Version 1.4? XML & JSON 3
A NullPointerException bei leerem Element XML & JSON 4
D XML: Element section content does not follow the DTD XML & JSON 6
clemson element mit id in jdom löschen XML & JSON 2
A Element an einer bestimmten Stelle einfügen (nicht am Ende) XML & JSON 4
R JDom: XML Code von Element, und: ist Element ein standalone XML & JSON 2

Ähnliche Java Themen

Neue Themen


Oben