开发者

@XmlElements and @XmlJavaTypeAdapter not working together

开发者 https://www.devze.com 2023-02-22 17:46 出处:网络
I\'m having a small problem with JAXB unmarshalling in that my input XML can be wrapped by one of two elements, for example:

I'm having a small problem with JAXB unmarshalling in that my input XML can be wrapped by one of two elements, for example:

<Output>
  <Update>
      <Channel>
          <id>1</id>
      </Channel>
      <Channel>
          <id>2</id>
      </Channel>
  开发者_开发百科</Update>
</Output>

or

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

My root class is unmarshalling the Channels to a HashMap using an @XmlJavaTypeAdapter and the code below works as expected.

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

where Channels class is:

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

and the Channel is:

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

and finally the ChannelAdapter is:

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) { ... }
}

However I thought I could just replace @XmlElement(name="Update") with

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

but that results in an empty map.

Hard-coding to either @XmlElement(name="Update") or @XmlElement(name="Erase") works with one or other the input XML documents but I need something that will work with either of the wrapper elements. I tried using a @XmlElementWrapper but that can only be used on a collection or array property which will not work since allChannels is a HashMap.

Could I please get an explain of what am I misunderstanding about the @XmlElements annotation and also a way to get this working? Thanks!


As far as I know, JAXB forces you to have a bidirectional data model; you cannot merge two children of a node into one without breaking this convention. So, you need to have two lists, one for Updates and one for Erases.

Because I've never used @XmlElements annotation, take my comment with care.


Try to change your XSDs to something that let's Output incorporate a choice allowing the XML to use either of the elements but never ever both at the same time.

I don't know, however, how to annotate this via XmlElements. Try to build an XSD first an then generate the classes for looking up the annotations ;).

0

精彩评论

暂无评论...
验证码 换一张
取 消