3

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

我的根类使用 @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;
    }
}

其中Channels类是:

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 文档一起工作,但我需要一些可以与任何一个包装器元素一起工作的东西。我尝试使用 a@XmlElementWrapper但它只能用于集合或数组属性,因为allChannels是一个 HashMap,所以它不起作用。

我能否解释一下我对@XmlElements注释的误解以及使其正常工作的方法?谢谢!

4

2 回答 2

1

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

因为我从未使用过@XmlElements 注释,所以请谨慎对待我的评论。

于 2011-04-05T13:29:15.040 回答
1

尝试将您的 XSD 更改为让输出合并一个选项,允许 XML 使用任何一个元素,但永远不要同时使用两者。

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

于 2012-08-30T11:43:42.590 回答