Псевдоним XStream корневых элементов списка - PullRequest
11 голосов
/ 29 сентября 2010

Я хочу иметь возможность создавать псевдоним корневого элемента списка в зависимости от того, какой тип объектов содержится в списке.Например, это мой текущий вывод:

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

И вот как я хочу, чтобы он выглядел так:

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

Я могу сделать это на глобальном уровне, говоря все спискинадо связать с монетами, но у меня много разных списков, и это не сработает.Есть идеи, как это сделать?Кажется, это должно быть просто, но, конечно, это не так.

РЕДАКТИРОВАТЬ: я должен указать, я пытаюсь сериализовать объекты в XML.Я использую Spring 3 MVC в качестве веб-фреймворка.

Ответы [ 3 ]

23 голосов
/ 30 сентября 2010

Допустим, у вас есть класс Coin с атрибутом типа следующим образом:

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

И у вас есть класс Coins, который содержит список монет:

@XStreamAlias("coins")
public class Coins{

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

Payвнимание на аннотации.Список неявный, и класс Coins будет показан как «монеты».

Вывод будет:

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

Это не то, что вы просили, но есть причина.

Сначала у монеты есть только один атрибут, но мы не уверены, что все объекты, которые вы хотите показать, имеют только один атрибут.Итак, нам нужно указать, о каком атрибуте объекта мы говорим.

Вы также можете показывать атрибуты монет как атрибуты XML, а не поля.Следующее:

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

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

Вот вывод:

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

Надеюсь, это поможет.

5 голосов
/ 29 сентября 2010

Это не идеальное решение, так как для него требуется отдельный класс-обертка, но вы можете сделать что-то вроде этого:

public class CoinResponse {

   private List<Coin> coinList;

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

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

А вот и уродливая часть:

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

По сути, это говорит Xstream использовать «монеты» при конвертации CoinResponse, а затем вообще не использовать никаких имен для самого списка.

4 голосов
/ 04 мая 2012
@XStreamAlias("coins")
public class Coins {
        @XStreamImplicit(itemFieldName="coin")
        List<String> coins = new ArrayList<String>();
}
...