2010-11-11 15 views
14

Qui è il caso d'uso:Perché il mio ArrayList non è gestito con JAXB?

@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")); 
    } 
} 

Poi, sto facendo:

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

Questo è quello che vedo:

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

Dove sono i miei libri? :)

+0

Non è possibile eseguire il marshalling 'ArrayList' (poiché altri linguaggi non conoscono ArrayList) ma è possibile eseguire il marshall' List'. –

+0

The Elite Gentleman - Non sono sicuro di cosa intendi. A differenza di altre librerie di binding e serializzazione XML, JAXB non include nulla di specifico XML nell'output. –

+0

Vincenzo - È necessario avere Books estendere ArrayList? L'approccio comune è che la classe Books abbia una proprietà ArrayList. –

risposta

12

Gli elementi siano radunate deve essere pubblico o avere l'annotazione XMLElement. La classe ArrayList e la tua classe Libri non corrispondono a nessuna di queste regole. Devi definire un metodo per offrire i valori del libro e anotizzarlo.

sul vostro codice, cambiando solo la classe Books aggiunta di un metodo di "auto getter":

@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; 
    } 
} 

quando si esegue il codice di smistamento si otterrà:

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

(ho aggiunto un interruzione di riga per scuotimento della chiarezza)

+0

La mia classe 'Books' ha' @ XmlRootElement', quindi "corrisponde alle regole" ... – yegor256

+0

Sì, ma non presenta un attributo pubblico o un metodo annotato per ottenere i valori.Dovrai quindi creare un nuovo metodo, anotarlo o scrivere una classe wrapper. Prova il codice che ti ho proposto. Genera il tuo XML previsto. Come puoi vedere, ho mantenuto le tue anotations di livello di classe (che sono giuste) e ho aggiunto un metodo getBooks (che restituisce la stessa istanza di lista) con un'anotazione @XMLElement. –

2

Non penso che sia possibile effettuare il marshalling di uno List così com'è. Considerare l'utilizzo di un'altra classe per avvolgere la lista nei seguenti lavori:.

@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(); 
} 

Usato come la seguente:

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

produce questo risultato:

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

Beh, questo non è esattamente quello che mi aspetto di ottenere. Puoi cambiare il tuo esempio per produrre " ...'? – yegor256

+0

@Vincenzo: l'ho modificato di conseguenza. Vedo che hai già accettato l'altra risposta. È un po 'più breve ma a mio avviso un po' strano. Un documento XML ha sempre un singolo elemento radice. Effettuare il marshalling di un 'List' direttamente è un po 'contrario a quello che mi aspetterei. – musiKk

0

Come hanno sottolineato @Blaise e @musiKk, sarebbe meglio avere semplicemente un elenco di libri nei libri e consentire ai libri di essere il vero elemento principale. Non considererei l'estensione di ArrayList una procedura accettabile nel mio codice.

Problemi correlati