最佳JAXB XJC代码生成与继承最佳的XML模式(Optimal JAXB XJC code ge

2019-09-16 12:26发布

已经有很多其专注于一个方面,优化了类似的问题,但每个解决方案有一个丑陋的缺点。

假设我想开发一个XML模式(XSD),它允许下列文件,想用XJC生成类:

<Catalogue>
    <Book>...</Book>
    <Journal>...</Journal>
    <Book>...</Book>
    ...
</Catalogue>

架构应该模拟的类型层次( BookJournal是的子类Publication )。 当然,这也应该是生成的Java类的情况。

我尝试了以下approches其中都有一个主要问题:

1)建模目录包含一个xsd:choice所有可能的亚型。

<xsd:complexType name="Catalogue">
    <xsd:choice maxOccurs="unbounded">
        <xsd:element ref="Book" />
        <xsd:element ref="Magazine" />
    </xsd:choice>
</xsd:complexType>

<xsd:element name="Publication" abstract="true" type="Publication" />
<xsd:element name="Book" type="Book"/>
<xsd:element name="Magazine" type="Magazine"/>

<xsd:complexType name="Publication">
    <xsd:sequence></xsd:sequence>
</xsd:complexType>

<xsd:complexType name="Book">
    <xsd:complexContent>
        <xsd:extension base="Publication">
        </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>
...

这里的问题是,我不得不提到在所有可能的亚型choice可能是很多在实际应用中的元素。 一个小问题是,虽然该Catalogue属性具有正确的类型List<Publication>它具有难看名称bookAndMagazine 。 由于冗余架构定义的,不是一种选择!

2.)建模目录包含一个xsd:sequence父类的

<xsd:complexType name="Catalogue">
    <xsd:choice maxOccurs="unbounded">
        <xsd:element ref="Publication" maxOccurs="unbounded"/>
    </xsd:choice>
</xsd:complexType>

这如果XML文档,制定不一样才有效<Publication xsi:type="Book"...> 因此,不是一种选择!

3)使用substitutionGroup喜欢这里提到http://www.xfront.com/ElementHierarchy.html

<xsd:complexType name="Catalogue">
    <xsd:choice maxOccurs="unbounded">
        <xsd:element ref="Publication" maxOccurs="unbounded"/>
    </xsd:choice>
</xsd:complexType>

<xsd:element name="Publication" abstract="true" type="Publication" />
<xsd:element name="Book" type="Book" substitutionGroup="Publication"/>
<xsd:element name="Magazine" type="Magazine" substitutionGroup="Publication"/>

<xsd:complexType name="Publication">
    <xsd:sequence></xsd:sequence>
</xsd:complexType>

<xsd:complexType name="Book">
    <xsd:complexContent>
        <xsd:extension base="Publication">
        </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>
...

在这里,代码生成是问题的原因是内部元件Catalogue映射到List<JaxbElement<? extends Publication>> List<JaxbElement<? extends Publication>>而不是List<Publication> 。 因此,也这是不是一种选择。

如何把我所有的目标一起?:

  • 规范的,非冗余的模式模型,其继承(例如在2)3))
  • 从这个模式和模型继承(像2)生成的简单干净的Java类和部分1))
  • 干净的XML文档(在第2不喜欢))
  • 标准JAXB和优选不多结合的元数据的使用

如果没有解决,所有这些目标相匹配,你更喜欢哪一个?

Answer 1:

因为我从来没有见过一个更清洁的解决这个问题,我建议使用类似于您的第一选择的东西。

XSD

<xs:element name="Publications" minOccurs="0">
  <xs:complexType>
    <xs:sequence>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="Magazine" type="magazine"/>
        <xs:element name="Book" type="book"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>
</xs:element>

 <xs:complexType name="magazine">
  <xs:complexContent>
   <xs:extension base="publication">
    <xs:sequence>
      <xs:element name="issueName" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:extension>
 </xs:complexContent>
</xs:complexType>

<xs:complexType name="publication">
  <xs:sequence>
    <xs:element name="name" type="xs:string" minOccurs="0"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="book">
  <xs:complexContent>
    <xs:extension base="publication">
      <xs:sequence>
        <xs:element name="title" type="xs:string" minOccurs="0"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

JAVA这是我用来产生上述XSD的Java代码。

@XmlElements({
  @XmlElement(name="Magazine", type=Magazine.class),
  @XmlElement(name="Book", type=Book.class)
})
@XmlElementWrapper(name="Publications")
public List<Publication> publications;


Answer 2:

如果你可以从代码(而不是XSD)开始,并使用MOXY看看这个OK 博客文章 。 它使用方法三无的JAXBElement包装。 我喜欢的方式来做到这一点首先是XSD,但我还没有找到它。



文章来源: Optimal JAXB XJC code generation and optimal XML schema with inheritance