最佳JAXB XJC代码生成和具有继承的最佳XML模式 [英] Optimal JAXB XJC code generation and optimal XML schema with inheritance
问题描述
有很多类似的问题集中在一个方面进行优化,但每个解决方案都有一个丑陋的缺点。
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屋!