有很多类似的问题集中在一个方面进行优化,但每个解决方案都有一个丑陋的缺点.
假设我想开发一个XML模式(XSD),它允许以下文档并希望使用XJC生成类:
<Catalogue>
<Book>...</Book>
<Journal>...</Journal>
<Book>...</Book>
...
</Catalogue>
模式应该为类型层次结构建模(Book和Journal是Publication的子类).当然,这也应该
是生成的Java类的情况.
我尝试了以下approches,这些都有一个重大问题:
1.)建模目录包含xsd:所有可能的子类型的选择.
<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>
...
这里的问题是我必须在选择元素中提到所有可能的子类型,这在实际应用中可能很多.
一个小问题是,尽管Catalog属性具有正确的类型List< Publication>它有一本丑陋的名字书和杂志.
由于冗余架构定义,不是一个选项!
2.)建模目录包含父类的xsd:序列
<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>
...
这里,代码生成是个问题,因为Catalog的内部元素被映射到List< JaxbElement<?扩展出版物>>而不是
列表与LT;公开> .因此,这也不是一种选择.
如何将我的所有目标结合在一起?:
>规范继承的规范,非冗余模式(例如2.)或3.))
>从这个模式生成的简单而干净的Java类,以及哪些模型继承(如2.)和部分在1.))
>干净的XML文档(不像2.)
>标准JAXB的使用,并且最好没有多少绑定元数据
如果没有符合所有这些目标的解决方案,您更喜欢哪一个?
最佳答案 我建议使用类似于你的第一个选项,因为我从未见过这个问题的清洁解决方案.
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;