如何在 XSD 中对类型和子类型进行分组

2024-01-24

我有这样的 XML:

<type>
    <mainType>...</mainType>
    <subtype>...<subtype>
</type>

mainTypes 是受限的 xs:strings (它们的列表)。每个 mainType 都有一个可能的子类型列表。 IE:
mainTypeA 可能有以下子类型:subtype1、subtype2、subtype3
mainTypeB 可能有以下子类型:subtype4、subtype5

我如何在 XSD 中表示这一点,以便每个子类型枚举都专门链接到它们的主类型? 有没有更好的方法来表示这 2 个字段以使 XSD 更简单?我并不反对更改 XML 文档结构。


(这本来是@hugh jadick 的回答中的附加评论,但对于这样的评论来说太长了。)

您的初始设计中存在两个问题,这使结构变得复杂:

  1. 你有一些可以被视为共现约束的东西,因为<subType>仅当出现<mainType>存在
  2. 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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 XSD 中对类型和子类型进行分组 的相关文章

随机推荐