Псевдоним XStream корневых элементов списка

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

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

Решение Вопроса

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

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

@XStreamAlias("coins")
public class Coins{

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

Обратите внимание на аннотации. Список является неявным, и класс 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>

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

 Michael-O10 янв. 2013 г., 15:46
Спасибо, это, к сожалению, единственный способ сделать это. Создание бесполезного класса-обёртки. Там нет варианта для#alias("coins", List<Coins>.class) (псевдокод).

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

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, а затем вообще не использовать никаких имен для самого списка.

 Greg Case29 сент. 2010 г., 21:57
Я только что заметил что-то. Если вы используете Arrays.asList (), как я делал выше, мой подход не сработает. Вместо этого вам нужно всегда передавать ArrayList, или конструктор CoinResponse должен обернуть параметр списка в новый ArrayList ().
@XStreamAlias("coins")
public class Coins {
        @XStreamImplicit(itemFieldName="coin")
        List<String> coins = new ArrayList<String>();
}

Ваш ответ на вопрос