有很多类似的问题都集中在要优化的一个方面,但每个解决方案都有一个丑陋的缺点。
假设我想开发一个 XML 模式 (XSD),它允许以下文档并希望使用 XJC 生成类:
<Catalogue>
<Book>...</Book>
<Journal>...</Journal>
<Book>...</Book>
...
</Catalogue>
模式应该对类型层次结构进行建模(Book
并且Journal
是 的子类Publication
)。当然,生成的 Java 类也应该如此。
我尝试了以下方法,它们都有一个主要问题:
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.)使用这里提到的替代组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<Publication>
. 因此,这也不是一个选择。
如何将我的所有目标集中在一起?:
- 对继承进行建模的规范的非冗余模式(例如在2.)或3.)中)
- 从此模式生成的简单而干净的 Java 类,这些类对继承进行建模(如2.)和部分在1.))
- 干净的 XML 文档(不像2.))
- 使用标准 JAXB,最好不要太多绑定元数据
如果没有与所有这些目标相匹配的解决方案,您更喜欢哪一个?