2010-09-29 10 views
11

Desidero essere in grado di alias l'elemento dell'elenco radice in base al tipo di oggetti contenuti nell'elenco. Ad esempio, questo è il mio uscita in corrente:Alias ​​XStream degli elementi radice dell'elenco

<list> 
<coin>Gold</coin> 
<coin>Silver</coin> 
<coin>Bronze</coin> 
</list> 

E questo è quello che voglio farlo sembrare come:

<coins> 
<coin>Gold</coin> 
<coin>Silver</coin> 
<coin>Bronze</coin> 
</coins> 

posso fare questo a livello globale dicendo tutte le liste dovrebbero essere alias per monete, ma ho un sacco di liste diverse e questo non funzionerà. Qualche idea su come fare questo? Sembra che dovrebbe essere semplice, ma ovviamente non lo è.

EDIT: dovrei specificare, sto provando a serializzare gli oggetti su xml. Sto usando Spring 3 MVC come il mio framework web.

risposta

23

Diciamo che avere una classe Coin con un attributo di tipo, come segue:

@XStreamAlias("coin") 
public class Coin { 
    String type; 
} 

E di avere una classe Monete che constains un elenco di Coin:

@XStreamAlias("coins") 
public class Coins{ 

    @XStreamImplicit 
    List<Coin> coins = new ArrayList<Coin>(); 
} 

Attenzione alla annotazioni. L'elenco è implicito e la classe delle monete verrà visualizzata come "monete".

L'output sarà:

<coins> 
    <coin> 
    <type>Gold</type> 
    </coin> 
    <coin> 
    <type>Silver</type> 
    </coin> 
    <coin> 
    <type>Bronze</type> 
    </coin> 
</coins> 

Non è lo stesso che hai chiesto, ma c'è una ragione.

All'inizio, le monete hanno un solo attributo, ma non siamo sicuri che tutti gli oggetti che vuoi mostrare abbiano anche un solo attributo. Quindi, dobbiamo dire di quale attributo dell'oggetto stiamo parlando.

È inoltre possibile visualizzare gli attributi Coin come attributi XML, non campi. Come segue:

@XStreamAlias("coin") 
public class Coin { 
    @XStreamAsAttribute 
    String type; 

    Coin(String type) { 
     this.type = type; 
    } 
} 

Ecco l'output:

<coins> 
    <coin type="Gold"/> 
    <coin type="Silver"/> 
    <coin type="Bronze"/> 
</coins> 

Speranza che aiuta.

+0

Grazie, questo è purtroppo l'unico modo per farlo. Creazione di una classe wrapper inutile. Non c'è alcuna opzione per '#alias (" coins ", List .class)' (pseudo codice). –

5

Questa non è una soluzione ideale, in quanto richiede una classe wrapper separato, ma si potrebbe fare qualcosa di simile:

public class CoinResponse { 

    private List<Coin> coinList; 

    public CoinResponse(List<Coin> coinList) { 
     this.coinList = coinList; 
    } 

    public List<Coin> getCoins() { 
     return this.coinList; 
    } 
} 

Ed ecco la parte brutta:

List<Coin> coins = Arrays.asList(new Coin(), new Coin(), new Coin()); 
CoinResponse response = new CoinResponse(coins); 

XStream xstream = new XStream(); 
xstream.alias("coins", CoinResponse.class); 
xstream.addImplicitCollection(CoinResponse.class, "coinList"); 

System.out.println(xstream.toXML(response)); 

In sostanza, questo sta dicendo a Xstream di usare "monete" durante la conversione di CoinResponse, e quindi di non usare alcun nome per la lista stessa.

+0

Ho appena notato qualcosa. Se usi Arrays.asList() come ho fatto sopra, il mio approccio non funzionerà. Invece, è necessario passare sempre un ArrayList, oppure il costruttore CoinResponse dovrebbe includere il parametro list in un nuovo ArrayList(). –

4
@XStreamAlias("coins") 
public class Coins { 
     @XStreamImplicit(itemFieldName="coin") 
     List<String> coins = new ArrayList<String>(); 
} 
Problemi correlati