Подтвердить что ты не робот

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

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

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

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

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

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

EDIT: я должен указать, я пытаюсь сериализовать объекты в xml. Я использую Spring 3 MVC как мою веб-инфраструктуру.

4b9b3361

Ответ 1

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

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

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

@XStreamAlias("coins")
public class Coins{

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

Обратите внимание на аннотации. Список неявный, а класс монет будет показан как "монеты".

Выход будет:

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

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

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

Вы также можете показать атрибуты Coin как атрибуты 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>

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

Ответ 2

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

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

Ответ 3

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