2010-11-11 7 views
14

Hier ist der Anwendungsfall:Warum wird meine ArrayList nicht mit JAXB gemarshallt?

@XmlRootElement 
public class Book { 
    public String title; 
    public Book(String t) { 
    this.title = t; 
    } 
} 
@XmlRootElement 
@XmlSeeAlso({Book.class}) 
public class Books extends ArrayList<Book> { 
    public Books() { 
    this.add(new Book("The Sign of the Four")); 
    } 
} 

Dann ich tue:

JAXBContext ctx = JAXBContext.newInstance(Books.class); 
Marshaller msh = ctx.createMarshaller(); 
msh.marshal(new Books(), System.out); 

Das ist, was ich sehe:

<?xml version="1.0"?> 
<books/> 

Wo sind meine Bücher? :)

+0

Sie können 'ArrayList' nicht marshallen (da andere Sprachen ArrayList nicht kennen), aber Sie können' List' marshallen. –

+0

Der Elite Gentleman - Ich bin mir nicht sicher, was Sie meinen. Im Gegensatz zu anderen XML-Binding- und Serialisierungsbibliotheken enthält JAXB nichts XML-spezifisches in der Ausgabe. –

+0

Vincenzo - Brauchen Sie Bücher, um ArrayList zu erweitern? Der übliche Ansatz besteht darin, dass die Books-Klasse über eine ArrayList-Eigenschaft verfügt. –

Antwort

12

Die Elemente vermarshallten werden muss öffentlich sein oder die XMLElement-Antion haben. Die ArrayList-Klasse und die Klasse Books stimmen nicht mit diesen Regeln überein. Sie müssen eine Methode definieren, um die Buchwerte anzubieten und sie zu ändern.

auf Ihren Code, ändert nur Ihre Bücher Klasse eine "self-Getter" Methode hinzufügen:

@XmlRootElement 
@XmlSeeAlso({Book.class}) 
public class Books extends ArrayList<Book> { 
    public Books() { 
    this.add(new Book("The Sign of the Four")); 
    } 

    @XmlElement(name = "book") 
    public List<Book> getBooks() { 
    return this; 
    } 
} 

, wenn Sie Ihre Rangierung Code ausführen erhalten Sie:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<books><book><title>The Sign of the Four</title></book></books> 

(Ich habe ein Zeilenumbruch für Klarheit Shake)

+0

Meine 'Books' Klasse hat' @ XmlRootElement', also "entspricht den Regeln" ... – yegor256

+0

Ja, aber es gibt kein öffentliches Attribut oder eine annotierte Methode, um die Werte zu erhalten.Sie müssen also eine neue Methode erstellen, sie anotieren oder eine Wrapper-Klasse schreiben. Probieren Sie den Code, den ich Ihnen vorgeschlagen habe. Es wird Ihr erwartetes XML generieren. Wie Sie sehen können, habe ich Ihre Klassenebenenanmerkungen beibehalten (was richtig ist) und eine Methode getBooks (die die gleiche Listeninstanz zurückgibt) mit einer @ XMLElement-Anotation hinzugefügt. –

2

Ich glaube nicht, dass Sie problemlos eine List wie Marshall. Betrachten wir eine andere Klasse mit der Liste wickeln in den folgenden Werken:.

@XmlType 
class Book { 
    public String title; 

    public Book() { 
    } 

    public Book(String t) { 
     this.title = t; 
    } 
} 

@XmlType 
class Books extends ArrayList<Book> { 
    public Books() { 
     this.add(new Book("The Sign of the Four")); 
    } 
} 

@XmlRootElement(name = "books") 
class Wrapper { 
    public Books book = new Books(); 
} 

Gebraucht wie folgt aus:

JAXBContext ctx = JAXBContext.newInstance(Wrapper.class); 
Marshaller msh = ctx.createMarshaller(); 
msh.marshal(new Wrapper(), System.out); 

es produziert dieses Ergebnis:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<books><book><title>The Sign of the Four</title></book></books> 
+0

Nun, das ist nicht genau das, was ich erwarte. Können Sie Ihr Beispiel ändern, um ' ...' 'zu erzeugen? – yegor256

+0

@Vincenzo: Ich habe es entsprechend geändert. Ich sehe, du hast die andere Antwort bereits akzeptiert. Es ist ein bisschen kürzer, aber meiner Meinung nach ein bisschen seltsam. Ein XML-Dokument hat immer ein einzelnes Wurzelelement. Eine "Liste" direkt zu migrieren, ist ein bisschen entgegengesetzt zu dem, was ich erwarten würde. – musiKk

0

Wie @Blaise und @musiKk darauf hingewiesen haben, wäre es besser, einfach eine Liste der Bücher in Büchern zu haben, und Bücher als das wahre Wurzelelement zu ermöglichen. Ich würde die Erweiterung von ArrayList in meinem eigenen Code nicht als akzeptable Prozedur betrachten.

Verwandte Themen