java – 如何使用JAXB将子元素分隔为单独的Collection属性?

我有来自供应商的以下XSD片段,我无法更改它的指定方式:

<xsd:element name="navmap">
  <xsd:complexType>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="navitem"/>
      <xsd:element ref="debug"/>
    </xsd:choice>
    <xsd:attribute name="focus" type="xsd:string" use="optional"/>
  </xsd:complexType>
</xsd:element>

现在没有自定义它会生成以下代码

@XmlElements({
        @XmlElement(name = "navitem", type = Navitem.class),
        @XmlElement(name = "debug", type = Debug.class)
    })
    protected List<Object> navitemOrDebug;

我宁愿为每种类型生成一个单独的列表,如下所示

@XmlElements({
        @XmlElement(name = "navitem", type = Navitem.class)
    })
    protected List<Navitem> navitems;

@XmlElements({
        @XmlElement(name = "debug", type = Debug.class)
    })
    protected List<Debug> debugs;

我的.xjb文件中有以下内容重命名整个List但我无法弄清楚如何拆分它们.

<jxb:bindings node="//xsd:element[@name='navmap']//xsd:complexType//xsd:choice">
  <jxb:property name="contents" />
</jxb:bindings>

如何为外部.xjb绑定文件中的每个类型指定我需要单独的List或Set?

如果我不能这样做,我如何添加< jaxb:annotation />到.xsd文件为每种类型指定一个单独的List或Set?

我不关心订购,在这种特殊情况下订单并不重要.

注意:我更喜欢外部.xjb解决方案,我不想对供应商提供的每个新版本区分自定义.xsd,它们太多了.

最佳答案 如承诺,请满足
Simplify Plugin.

该插件允许简化“复杂”属性.这些属性通常是从可重复的选择中生成的,如下所示:

<xs:complexType name="typeWithReferencesProperty">
    <xs:choice maxOccurs="unbounded">
        <xs:element name="a" type="someType"/>
        <xs:element name="b" type="someType"/>
    </xs:choice> 
</xs:complexType>

<xs:complexType name="typeWithElementsProperty">
    <xs:choice maxOccurs="unbounded">
        <xs:element name="a" type="xs:string"/>
        <xs:element name="b" type="xs:int"/>
    </xs:choice> 
</xs:complexType>

默认情况下,XJC将复合属性,将多个引用或元素建模在一个中.

@XmlElementRefs({
    @XmlElementRef(name = "a", type = JAXBElement.class),
    @XmlElementRef(name = "b", type = JAXBElement.class)
})
protected List<JAXBElement<SomeType>> aOrB;

@XmlElements({
    @XmlElement(name = "a", type = String.class)
    @XmlElement(name = "b", type = Integer.class),
})
protected List<Serializable> aOrB;

需要这些复杂属性来充分地模拟XML模式的复杂内容,即维持可重复选择中元素的顺序.
不幸的是,它们不像bean属性那样惯用.这些属性是“异构的”(从某种意义上说它们存储了不同的类型),这使得它们难以使用.

但是,如果元素的顺序不重要 – 也就是说,你可以忍受它将在重新编组后改变的事实,这些属性的结构可以简化:复杂的属性可以分成几个简单的属性.

Simplify插件实现此任务.它允许您简化复杂的属性.该插件将删除复杂属性并插入几个更简单的属性,而不是原始(复杂)属性.所以你可以得到类似的东西:

@XmlElement(name = "a", type = String.class)
protected List<String> a;
@XmlElement(name = "b", type = Integer.class)
protected List<Integer> b;

要么:

@XmlElement(name = "a")
protected List<SomeType> a;
@XmlElement(name = "b")
protected List<SomeType> b;

要么:

@XmlElementRef(name = "a", type = JAXBElement.class)
protected List<JAXBElement<SomeType>> a;
@XmlElementRef(name = "b", type = JAXBElement.class)
protected List<JAXBElement<SomeType>> b;

取决于定制.

该插件将于JAXB2 Basics发布0.6.3,现在可以作为this repository的快照发布.

点赞