繁体   English   中英

我如何分开<xsd:choice />使用 JAXB 将子元素放入单独的集合属性中?

[英]How do I separate the <xsd:choice/> sub-elements into individual Collection properties using JAXB?

我有以下来自供应商的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绑定文件中的每个类型指定一个单独的ListSet

如果我不能这样做,如何将<jaxb:annotation/>添加到.xsd文件中,以便为每种类型指定单独的ListSet

我不在乎订购,在这种特殊情况下顺序并不重要。

注意:我更喜欢外部.xjb解决方案,我不想将 custom.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 Plugin 实现了这个任务。 它允许您简化复杂的属性。 该插件将删除复杂属性并插入几个更简单的属性而不是原始(复杂)属性。 所以你可以得到类似的东西:

@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 中发布,现在可作为此存储库中的快照使用。

据我所知,目前你不能(使用来自 JAXB RI 的 XJC)。 从理论上讲,必须可以编写一个插件来更改 XJC model。

但是您必须注意,两个单独的同质属性debugnavitem不等于一个异质属性navitemOrDebug 即,如果您解组和编组相同的 object,您将获得不同的元素顺序。

但是,在许多情况下,这可能是有道理的。 在此处提出问题,我会考虑实施它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM