2010-09-29 4 views
11

Je souhaite pouvoir aliaser l'élément de la liste racine en fonction du type d'objet contenu dans la liste. Par exemple, voici ma sortie de courant:XStream Alias ​​des éléments racine de la liste

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

Et ce que je veux ressembler:

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

Je peux le faire au niveau mondial en disant toutes les listes doivent être aliasées à pièces de monnaie, mais j'ai beaucoup de listes différentes et cela ne fonctionnera pas. auriez vous des idées pour faire ça? On dirait que cela devrait être simple, mais bien sûr, ce n'est pas le cas.

EDIT: Je devrais spécifier, j'essaye de sérialiser des objets au xml. J'utilise Spring 3 MVC comme mon framework web.

Répondre

23

Disons que vous avez une classe Coin avec un attribut de type, comme suit:

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

Et vous avez une classe pièces qui constains une liste de Coin:

@XStreamAlias("coins") 
public class Coins{ 

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

attention à la annotations. La liste est implicite et la classe de pièces apparaîtra comme "pièces de monnaie".

La sortie sera:

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

Ce n'est pas la même que vous avez demandé, mais il y a une raison.

Au début, la pièce n'a qu'un seul attribut, mais nous ne sommes pas sûrs si tous les objets que vous voulez montrer n'ont qu'un seul attribut. Donc, nous devons dire de quel attribut d'objet nous parlons.

Vous pouvez également afficher les attributs Coin en tant qu'attributs XML, et non en tant que champs. Comme suit:

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

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

Voici la sortie:

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

Hope it helps.

+0

Merci, c'est malheureusement le seul moyen de le faire. Créer une classe wrapper inutile. Il n'y a pas d'option pour '#alias (" pièces ", Liste .class)' (pseudo code). –

5

Ce n'est pas une solution idéale, car elle nécessite une classe enveloppe séparée, mais vous pouvez faire quelque chose comme ceci:

public class CoinResponse { 

    private List<Coin> coinList; 

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

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

Et voici la partie laide:

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

Fondamentalement, cela indique à Xstream d'utiliser des "pièces de monnaie" lors de la conversion de CoinResponse, puis n'utilise aucun nom pour la liste elle-même.

+0

Je viens de remarquer quelque chose. Si vous utilisez Arrays.asList() comme je l'ai fait ci-dessus, mon approche ne fonctionnera pas. Au lieu de cela, vous devez toujours passer dans une ArrayList, ou le constructeur CoinResponse doit envelopper le paramètre list dans une nouvelle ArrayList(). –

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