XStream Alias of List root elements

2019-01-17 22:56发布

问题:

I want to be able to alias the root list element depending upon what type of objects are contained in the list. For example, this is my current output:

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

And this is what I want it to look like:

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

I can do this at a global level by saying all lists should be aliased to coins, but I have a lot of different lists and this won't work. Any ideas on how to do this? Seems like it should be simple, but of course, it isn't.

EDIT: I should specify, I am trying to serialize objects to xml. I am using Spring 3 MVC as my web framework.

回答1:

Let's say you have a Coin class with a type attribute, as follows:

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

And you have a Coins class that constains a List of Coin:

@XStreamAlias("coins")
public class Coins{

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

Pay attention to the annotations. The List is Implicit and the Coins class will be shown as "coins".

The output will be:

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

It's not the same you asked for, but there is a reason.

At first, coin have only one attribute, but we are not sure if all objects you want to show do have only one attribute too. So, we need to tell which object attribute we are talking about.

You can also show the Coin attributes as XML Attributes, not fields. As follows:

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

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

Here is the output:

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

Hope it helps.



回答2:

This isn't an ideal solution, as it requires a separate wrapper class, but you could do something like this:

public class CoinResponse {

   private List<Coin> coinList;

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

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

And here's the ugly part:

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

Basically, this is telling Xstream to use "coins" when converting the CoinResponse, and then don't use any name at all for the list itself.



回答3:

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