我有来自供应商的以下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>
如何为外部List
绑定文件中的每种类型指定单独的Set
或.xjb
?
如果我不能这样做,如何在<jaxb:annotation/>
文件中添加.xsd
,为每种类型指定单独的List
或Set
?
我不关心订购,在这种特殊情况下订单并不重要。
注意: 我更喜欢外部.xjb
解决方案,我不希望针对供应商提供的每个新版本区分自定义.xsd,太多了。
答案 0 :(得分:2)
如承诺的那样,请与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的快照发布。
答案 1 :(得分:0)
据我所知,目前你不能(与JAXB RI的XJC合作)。从理论上讲,它必须能够编写一个改变XJC模型的插件。
但您必须注意,两个单独的同构属性debug
和navitem
不等于一个异构属性navitemOrDebug
。即如果你解组并编组同一个对象,你将获得不同的元素排序。
然而,在许多情况下,这可能是有道理的。请提交问题here,我会考虑实施。