2010-09-29 19 views
11

Quiero ser capaz de alias el elemento de lista raíz dependiendo de qué tipo de objetos están contenidos en la lista. Por ejemplo, este es mi corriente de salida:XStream Alias ​​de elementos de raíz de lista

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

Y esto es lo que quiero que se vea como:

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

que puedo hacer esto a nivel mundial diciendo todas las listas deben tener sobrenombres a monedas, pero tengo muchas listas diferentes y esto no funcionará. ¿Alguna idea sobre cómo hacer esto? Parece que debería ser simple, pero por supuesto, no lo es.

EDITAR: Debería especificar, estoy intentando serializar objetos a xml. Estoy usando Spring 3 MVC como mi marco web.

Respuesta

23

Digamos que usted tiene una clase de moneda con un atributo de tipo, de la siguiente manera:

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

y tiene una clase de monedas que constains una lista de monedas:

@XStreamAlias("coins") 
public class Coins{ 

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

Tenga en cuenta el anotaciones La lista es implícita y la clase Monedas se mostrará como "monedas".

La salida será:

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

No es el mismo que solicitó, pero hay una razón.

Al principio, la moneda tiene solo un atributo, pero no estamos seguros de si todos los objetos que desea mostrar tienen solo un atributo también. Entonces, necesitamos decir de qué atributo de objeto estamos hablando.

También puede mostrar los atributos Coin como atributos XML, no como campos. En la siguiente manera:

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

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

Aquí está la salida:

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

espero que ayude.

+0

Gracias, esta es lamentablemente la única manera de hacer esto. Creando una clase de contenedor inútil. No hay opción para '#alias (" coins ", List .class)' (pseudocódigo). –

5

Esto no es una solución ideal, ya que requiere una clase de contenedor separado, pero se puede hacer algo como esto:

public class CoinResponse { 

    private List<Coin> coinList; 

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

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

Y aquí está la parte fea:

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)); 

Básicamente, esto le está diciendo a Xstream que use "monedas" al convertir CoinResponse, y luego no use ningún nombre para la lista en sí.

+0

Acabo de notar algo. Si usa Arrays.asList() como hice anteriormente, mi enfoque no funcionará. En su lugar, siempre debe pasar una ArrayList, o el constructor CoinResponse debe ajustar el parámetro list en una nueva ArrayList(). –

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