我有以下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>
也就是说,两个新闻字段fieldA和fieldB被添加到BaseType的底部。
有没有办法扩展BaseType, 但是在顶部插入fieldA,在底部插入fieldB? 这样有效吗?
<extendedType>
<fieldA>aaa</fieldA>
<field1>hello</field1>
<field2>world</field2>
<fieldB>bbb</fieldB>
</extendedType>
以及如何使JAXB按预期工作?
答案 0 :(得分:4)
http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#Complex_Type_Definition
通过在另一个定义的内容模型的末尾添加额外的内容模型粒子,或者通过具有其他属性声明,或两者兼而有之,扩展另一个的复杂类型是这样做的。
- 注意:此规范仅允许附加,而不允许其他类型的扩展。此决定简化了将实例从派生类型转换为基类型所需的应用程序处理。未来版本可能允许更多类型的扩展,需要更复杂的转换才能实现转换。
因此,在扩展类型时,只在底部添加字段。
黑客攻击:扩展类型的字段出现在顶部。即添加到扩展类型的字段添加在顶部。因此,您可以有三种类型的类型:顶部“虚拟”级别(用于顶部字段),中间级别包含要继承的字段,底部级别(用于底部字段)。导入此模式的模式将定义底层 - redefine
顶层。这样您就可以在顶部和底部添加字段。
这个 大 问题是它还将重新定义扩展它的所有其他类型的顶级...所以这些额外的字段将遍布整个地方,这可能不是你想要的。
其他替代方案包括:避免使用扩展机制,而是使用substitution groups
(但这些需要不同的元素名称);或者在元素中创建自己的多态(<choice>
)和继承(<group ref="..."/>
在顶部和底部) - 但请注意,每个选项必须独立开始或违反UPA规则(因为他们赢了'可以通过属性区分,例如xsi:type
)。
编辑我看到另一个答案已经涵盖了这一点我已经输入了所有这些,还有一些额外的建议,所以我不妨保留它。
答案 1 :(得分:2)
<强>更新强>
以下是XML Schema规范中的相关声明:
2.2.1.3复杂类型定义(http://www.w3.org/TR/xmlschema-1/#Complex_Type_Definition)
通过增加另一个来扩展另一个的复杂类型 内容模型粒子在另一个定义的内容的末尾 模型,或通过附加属性声明,或两者兼而有之。
要对XML模式有效,扩展字段需要在继承字段之后发生。在解组时,元素可以是任何顺序。如果您从POJO开始,则可以标记父类@XmlTransient
,以便将父属性视为子项的一部分,以便它们可以包含在子项propOrder
中。
了解更多信息