@XmlElements和@XmlJavaTypeAdapter不能一起工作

时间:2011-04-05 11:33:27

标签: java jaxb unmarshalling

我在使用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>    

我的root类使用@XmlJavaTypeAdapter将 Channels 解组为HashMap,下面的代码按预期工作。

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

但我认为我可以用{/ 1>替换@XmlElement(name="Update")

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

但这会产生一张空地图。

@XmlElement(name="Update")@XmlElement(name="Erase")的硬编码适用于一个或另一个输入XML文档,但我需要一些适用于任何一个包装元素的东西。我尝试使用@XmlElementWrapper,但只能在集合或数组属性上使用,因为 allChannels 是HashMap,所以它不起作用。

我能否解释一下我对@XmlElements注释的误解,以及实现这一点的方法?谢谢!

2 个答案:

答案 0 :(得分:1)

据我所知,JAXB强迫您拥有双向数据模型;在不违反此约定的情况下,您无法将节点的两个子节点合并为一个节点。因此,您需要有两个列表,一个用于更新,另一个用于删除。

因为我从未使用@XmlElements注释,所以要小心谨慎。

答案 1 :(得分:1)

尝试将XSD更改为允许输出包含选项的选项,允许XML使用其中任何一个元素,但不能同时使用这两个元素。

但是,我不知道如何通过XmlElements注释它。首先尝试构建一个XSD,然后生成用于查找注释的类;)。