有很多类似的问题集中在一个方面进行优化,但每个解决方案都有一个丑陋的缺点. 假设我想开发一个XML模式(XSD),它允许以下文档并希望使用XJC生成类: Catalogue Book.../Book Journal.../Journal
假设我想开发一个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;