@XmlElements и @XmlJavaTypeAdapter не работают вместе - PullRequest
3 голосов
/ 05 апреля 2011

У меня небольшая проблема с демаршированием JAXB в том, что мой входной XML может быть обернут одним из двух элементов, например:

<Output>
  <Update>
      <Channel>
          <id>1</id>
      </Channel>
      <Channel>
          <id>2</id>
      </Channel>
  </Update>
</Output>

или

<Output>
  <Erase>
      <Channel>
          <id>1</id>
      </Channel>
  </Erase>
</Output>    

Мой корневой класс распаковывает Channels в HashMap, используя @XmlJavaTypeAdapter, и приведенный ниже код работает как положено.

@XmlRootElement(name="Output")
public class Output{
    @XmlElement(name="Update")
    @XmlJavaTypeAdapter(ChannelAdapter.class)
    private HashMap<Long, Channel> allChannels;
    public Map getChannels() {
        return allChannels;
    }
}

где Каналы класс:

public class Channels {
    @XmlElement(name="Channel")
    public Channel[] channels;
}

и Канал :

@XmlAccessorType(XmlAccessType.FIELD)
public class Channel {
    @XmlPath("id/text()")
    private Long id;
}

и, наконец, ChannelAdapter :

public class ChannelAdapter extends XmlAdapter<Channels, Map<Long, Channel>> {
    @Override
    public Map<Long, Channel> unmarshal(Channels value) { ... }

    @Override
    public Channels marshal(Map<Long, Channel> map) { ... }
}

Однако я думал, что смогу просто заменить @XmlElement(name="Update") на

@XmlElements({
    @XmlElement(name="Update"),
    @XmlElement(name="Erase")
})

но в результате получается пустая карта.

Жесткое кодирование либо @XmlElement(name="Update"), либо @XmlElement(name="Erase") работает с тем или иным входным XML-документом, но мне нужно что-то, что будет работать с любым из элементов-оболочек. Я попытался использовать @XmlElementWrapper, но его можно использовать только для свойства коллекции или массива, которое не будет работать, поскольку allChannels является HashMap.

Могу ли я получить объяснение того, что я неправильно понимаю относительно аннотации @XmlElements, а также способ заставить это работать? Спасибо!

Ответы [ 2 ]

1 голос
/ 30 августа 2012

Попытайтесь изменить ваши XSD на что-то, что позволит Output сделать выбор, позволяющий XML использовать любой из элементов, но никогда не использовать оба одновременно.

Однако я не знаю, каканнотируйте это через XmlElements.Попробуйте сначала создать XSD, а затем сгенерировать классы для поиска аннотаций;).

1 голос
/ 05 апреля 2011

Насколько я знаю, JAXB вынуждает вас иметь двунаправленную модель данных;Вы не можете объединить два дочерних узла в один, не нарушая этого соглашения.Итак, вам нужно иметь два списка, один для обновлений и один для стирания.

Поскольку я никогда не использовал аннотацию @XmlElements, внимательно отнеситесь к моему комментарию.

...