【发布时间】:2012-04-24 22:33:54
【问题描述】:
有很多类似的问题都集中在一个方面进行优化,但每个解决方案都有一个丑陋的缺点。
假设我想开发一个 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,最好不要太多绑定元数据
如果没有与所有这些目标相匹配的解决方案,您更喜欢哪一个?
【问题讨论】:
-
您能否详细说明为什么选项 3) 不好,以及为什么
List<JaxbElement<? extends Publication>>不适合您?它实际上很优雅:不仅您有一个 JAXB 对象,而且 JAXBElement 包装器还为您提供了完全限定的元素名称。 xml信息 -
1.) 我想在其他应用程序部分中使用生成的类层次结构作为一种域模型,我不喜欢让它们依赖于 JaxB 类型。 2) 我正在应用 XJC 插件 jaxb-visitor,它丰富了访问者模式的生成类。 JaxbElement 属性打破了遍历文档树的自然方式。
-
我也觉得选项 3 很丑。我更喜欢与 pojo 保持接近,并且在这种情况下永远不需要 JAXBElement 提供的东西,因为它都是一个模式。
标签: inheritance xsd jaxb code-generation xjc