Inheritance JAXB-XJC代码的优化生成和带继承的XML模式的优化

Inheritance JAXB-XJC代码的优化生成和带继承的XML模式的优化,inheritance,xsd,jaxb,code-generation,xjc,Inheritance,Xsd,Jaxb,Code Generation,Xjc,有很多类似的问题都集中在一个方面进行优化,但每个解决方案都有一个丑陋的缺点 假设我想开发一个XML模式(XSD),它允许以下文档,并希望使用XJC生成类: <Catalogue> <Book>...</Book> <Journal>...</Journal> <Book>...</Book> ... </Catalogue> 这里的问题是,我必须提到choice元素中

有很多类似的问题都集中在一个方面进行优化,但每个解决方案都有一个丑陋的缺点

假设我想开发一个XML模式(XSD),它允许以下文档,并希望使用XJC生成类:

<Catalogue>
    <Book>...</Book>
    <Journal>...</Journal>
    <Book>...</Book>
    ...
</Catalogue>
这里的问题是,我必须提到
choice
元素中所有可能的子类型,这在实际应用程序中可能非常多。 一个小问题是,尽管
catalog
属性具有正确的类型
List
,但它有一个丑陋的名称
bookAndMagazine
。 因为冗余的模式定义,不是一个选项

2.)包含父类的
xsd:sequence
的建模目录

<xsd:complexType name="Catalogue">
    <xsd:choice maxOccurs="unbounded">
        <xsd:element ref="Publication" maxOccurs="unbounded"/>
    </xsd:choice>
</xsd:complexType>

只有当XML文档的格式类似于
时,这才起作用。因此,这不是一个选择

3.)使用此处提到的替换组


...

在这里,代码生成是一个问题,因为
目录
的内部元素映射到
列表我建议使用类似于您的第一个选项的内容,因为我从未见过更干净的解决方案

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;
@XmlElements({
@XmlElement(name=“Magazine”,type=Magazine.class),
@XmlElement(name=“Book”,type=Book.class)
})
@XmlElementWrapper(name=“出版物”)
公开出版物清单;

如果您可以从代码(而不是XSD)开始,并且可以使用MOXY,请检查此项。它使用方法3而不使用JAXBElement包装器。我很想从XSD开始做这件事,但我还没有找到它。

你能详细解释一下为什么选项3)不好,为什么
List1。)我想在其他应用程序部分使用生成的类层次结构作为一种域模型,我不想让它们依赖于JaxB类型。2) 我正在应用XJC插件jaxb visitor,它丰富了为visitor模式生成的类。JaxbElement属性打破了遍历文档树的自然方式。我更喜欢与pojo保持密切联系,并且永远不需要JAXBELENT在本例中提供的东西,因为它都是一个模式。谢谢。事实上,我也决定了。然而,在您的示例中,您正在实现Java类型,包括一些注释,并从中生成XSD。我正试着倒过来。开发XSD并生成代码。有趣的是,看到的XSD等于解决方案1。)我建议你考虑的一件事是,用选项1,你会被这两个子类型卡住,并且必须在将来支持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>
@XmlElements({
  @XmlElement(name="Magazine", type=Magazine.class),
  @XmlElement(name="Book", type=Book.class)
})
@XmlElementWrapper(name="Publications")
public List<Publication> publications;