最佳JAXB XJC代码生成和具有继承的最佳XML模式 [英] Optimal JAXB XJC code generation and optimal XML schema with inheritance

查看:75
本文介绍了最佳JAXB XJC代码生成和具有继承的最佳XML模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有很多类似的问题集中在一个方面进行优化,但每个解决方案都有一个丑陋的缺点。

There have been a lot of similar questions which focus on one aspect to optimize but each solution had an ugly downside.

假设我想开发一个XML模式( XSD)允许以下文档并希望使用XJC生成类:

Suppose I want to develop an XML schema (XSD) which allows the following documents and want to generate classes using XJC:

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

架构应该为类型层次结构建模( Book Journal Publication 的子类。当然,这也应该是生成的Java类的

The schema should model the type hierarchy (Book and Journal are subclasses of Publication). Naturally, this should also be the case for the generated Java classes.

我尝试了以下的方法,这些方法都有一个重大问题:

I tried the following approches which all have a major issue:

1。)建模目录包含所有可能子类型的 xsd:choice

1.) modeling Catalogue to contain a xsd:choice of all possible subtypes.

<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 元素在实际应用程序中可能很多。
一个小问题是,虽然目录属性具有正确的类型列表< Publication> 但它有一个丑陋的名字 bookAndMagazine
由于冗余架构定义,不是一个选项!

The problem here is that I have to mention all possible subtypes in the choice element which could be a lot in a real application. A minor issue is that, although the Catalogue attribute has the correct type List<Publication> it has an ugly name bookAndMagazine. Because of the redundant schema definition, not an option!

2。)建模目录包含 xsd:sequence父类的

2.) modeling Catalogue to contain a xsd:sequence of the parent class

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

这仅适用于XML文档的制定,如< Publication xsi :type =Book...> 。因此,不是一个选项!

This does only work if the XML documents are formulated like <Publication xsi:type="Book"...> . Thus, not an option!

3。)使用像这里提到的substitutionGroup http://www.xfront.com/ElementHierarchy.html

3.) Use substitutionGroup like mentioned here 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>
...

这里,代码生成是问题,因为目录映射到列表< JaxbElement<?扩展出版物>> 而非
列出< Publication> 。因此,这也不是一个选择。

Here, the code generation is the issue because the inner element of Catalogue is mapped to List<JaxbElement<? extends Publication>> rather than List<Publication> . Hence, also this isn't an option.

如何将我的所有目标整合在一起?:

How to bring all my objectives together?:


  • 规范继承的规范非冗余模式(例如 2。) 3。)

  • 从这个模式生成的简单而干净的Java类以及模型继承的模型(如 2。),部分在 1中。)

  • 清理XML文档(不像 2中那样。)

  • 标准JAXB的使用,最好没有多少绑定元数据

  • canonical, non-redundant schema which models inheritance (such as in 2.) or 3.))
  • simple and clean Java classes generated from this schema and which models inheritance (like in 2.) and partly in 1.) )
  • clean XML documents (not like in 2.) )
  • usage of standard JAXB and preferable not much binding metadata

如果没有符合所有这些目标的解决方案,您更喜欢哪一个?

And if there is no solution which matches all these objectives, which one would you prefer?

推荐答案

我建议使用与你的第一个选项类似的东西,因为我从未见过这个问题的清洁解决方案。

I would suggest using something similar to your first option as I have never seen a cleaner solution to this problem.

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
这是我用来生成的Java代码上面的XSD。

JAVA This is the Java code I used to generate the above XSD.

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

这篇关于最佳JAXB XJC代码生成和具有继承的最佳XML模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆