2

我有以下 XSD(为了问这个问题):

  <xsd:complexType name="BaseType" abstract="true">
    <xsd:sequence>
      <xsd:element name="field1" type="xsd:string"/>
      <xsd:element name="field2" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="ExtendedType">
    <xsd:complexContent>
      <xsd:extension base="tns:BaseType">
        <xsd:sequence>
          <xsd:element name="fieldA" type="xsd:string"/>
          <xsd:element name="fieldB" type="xsd:string"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="extendedType" type="tns:ExtendedType"/>

这允许 XML 文件如下:

<extendedType>
  <field1>hello</field1>
  <field2>world</field2>
  <fieldA>aaa</fieldA>
  <fieldB>bbb</fieldB>
</extendedType>

即在BaseType的底部添加了两个新闻字段fieldA和fieldB。

有没有办法扩展BaseType,但在顶部插入fieldA,在底部插入fieldB?这样可以吗?

<extendedType>
  <fieldA>aaa</fieldA>
  <field1>hello</field1>
  <field2>world</field2>
  <fieldB>bbb</fieldB>
</extendedType>

以及如何使 JAXB 按预期工作?

4

2 回答 2

4

http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#Complex_Type_Definition

扩展另一个复杂类型的方法是在另一个定义的内容模型末尾添加额外的内容模型粒子,或通过额外的属性声明,或两者兼而有之。

  • 注意:本规范只允许附加,不允许其他类型的扩展。此决定简化了将实例从派生类型转换为基本类型所需的应用程序处理。未来的版本可能允许更多种类的扩展,需要更复杂的转换来实现强制转换。

因此,在扩展类型时,仅在底部添加字段。

一个技巧:扩展类型的字段出现在顶部。即添加到扩展类型的字段被添加到顶部。因此,您可以具有三个级别的类型:顶级“虚拟”级别(用于顶部字段)、带有您要继承的字段的中间级别和底部级别(用于底部字段)。导入它的模式将定义底层 - 和redefine顶层。这将使您能够在顶部和底部添加字段。这样做的最大 问题是它还将重新定义扩展它的所有其他类型的顶层......所以这些额外的字段将出现在所有地方,这可能不是你想要的。

其他替代方案包括:避免扩展机制,而是使用substitution groups(但这些需要不同的元素名称);或者在元素中创建自己的多态性<choice><group ref="..."/>xsi:type

编辑我看到另一个答案已经涵盖了这一点我已经输入了所有这些,并且还有一些额外的建议,所以我不妨保留它。

于 2012-12-03T14:07:46.047 回答
2

更新

以下是 XML Schema 规范中的相关声明:

2.2.1.3 复杂类型定义http://www.w3.org/TR/xmlschema-1/#Complex_Type_Definition

扩展另一个复杂类型的方法是在另一个定义的内容模型末尾添加额外的内容模型粒子,或通过额外的属性声明,或两者兼而有之。


为了对 XML 模式有效,扩展字段需要出现在继承字段之后。未编组时,元素可以按任何顺序排列。如果您从 POJO 开始,您可以标记父类@XmlTransient,以便将父类属性视为子类的一部分,以便它们可以包含在子类的propOrder.

了解更多信息

于 2012-12-03T11:12:14.620 回答