(这本来是@hugh jadick 的回答中的附加评论,但对于这样的评论来说太长了。)
您的初始设计中存在两个问题,这使结构变得复杂:
- 你有一些可以被视为共现约束的东西,因为
<subType>
仅当出现<mainType>
存在
- element declarations are inconsistent because you have
- ...在相同的背景下(孩子
<type>
)
- ...具有相同名称的元素(
<mainType>
)
- ...但是具有不同的类型(不同的值和相关的
<subType>
元素)。
在 XML Schema 1.0 中,虽然在某些情况下和/或通过某些方法可以实现这些功能,但没有通用的方法来实现这些功能。对于不明确的类型问题,一种可能的解决方法是使用xsi:type
实例文档中的属性来确定所使用的模式类型(示例 1)。
我建议您不要使用一些可能的解决方法来解决这些问题,而是遵循 @hugh jadick 的answer https://stackoverflow.com/questions/6653120/how-to-group-types-subtypes-in-xsd/6655677#6655677并为所有主要类型创建具有不同名称的元素,这些元素对于不同的子类型也将具有不同的元素。如果您不喜欢将类型名称作为元素名称(或者它对于 XML 元素名称无效),您可以将其放入属性中,可能使用默认值或固定值(<myType1 typeName="Type 1 name">
)(示例2)。如果子类型是互斥的,您也可以将它们放入属性中(<myType1 subType="subType2">
)。如果您确实想在元素内容中包含类型名称(<mainType1>Type 1 name</mainType1>
),那么最好有<subType>
元素为以下兄弟姐妹而不是孩子<mainType1>
因为这会导致混合内容,很容易导致空格和文本节点位置相关的问题(示例 3)。
是的,替换组也可以与@hugh jadick 的答案一起使用。你会有一个摘要<mainType>
元素和所有主要类型元素定义都有substitutionGroup="mainType"
属性。您仍然需要为不同的主类型元素使用不同的名称,因为它们允许不同的允许元素/值集。这些元素的类型必须从抽象的类型派生<mainType>
他们替换的元素(示例 4)。
代码示例
实施例1
<xs:element name="type">
<xs:complexType>
<xs:choice>
<xs:element name="mainType" type="mainType1"/>
<xs:element name="mainType" type="mainType2"/>
<xs:element name="mainType" type="mainType3"/>
</xs:choice>
</xs:complexType>
</xs:element>
<type>
<mainType xsi:type="mainType1"/>
</type>
实施例2
<xs:element name="mainType1">
<xs:complexType>
<xs:choice>
<xs:element ref="subType1"/>
<xs:element ref="subType2"/>
<xs:element ref="subType3"/>
</xs:choice>
<xs:attribute name="typeName" type="xs:string"/>
</xs:complexType>
</xs:element>
实施例3
<xs:element name="type">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="mainType" type="mainType1"/>
<xs:choice>
<xs:element ref="subType1"/>
<xs:element ref="subType2"/>
<xs:element ref="subType3"/>
</xs:choice>
</xs:sequence>
<!-- repeat similarily for other main types -->
<xs:sequence>
<!-- ... -->
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
实施例4
<xs:element name="type">
<xs:complexType>
<xs:sequence>
<xs:element ref="mainType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="mainType" type="mainType" abstract="true"/>
<xs:element name="mainType1" type="typeForMainType1" substitutionGroup="mainType"/>
<xs:element name="mainType2" type="typeForMainType2" substitutionGroup="mainType"/>
<xs:complexType name="mainType">
<!-- definition for mainType -->
</xs:complexType>
<xs:complexType name="typeForMainType1">
<xs:complexContent>
<xs:restriction base="mainType">
<!-- definition for mainType1 -->
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="typeForMainType2">
<xs:complexContent>
<xs:restriction base="mainType">
<!-- definition for mainType1 -->
</xs:restriction>
</xs:complexContent>
</xs:complexType>