使用新属性扩展时,从父级限制属性

时间:2015-01-27 18:58:02

标签: xml xsd

我有复杂的类型History,它应该扩展我的复杂类型Section,同时禁止一个继承的属性(Title)。我怎样才能做到这一点?

示例

<xs:complexType name="Section">
    <xs:sequence minOccurs="1" maxOccurs="1">
        <xs:choice minOccurs="1" maxOccurs="unbounded">
            <!-- ... -->
        </xs:choice>

        <xs:element name="Section" type="Section" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>

    <xs:attribute name="Key" type="xs:string"/>
    <xs:attribute name="Title" type="xs:string"/>
</xs:complexType>

<xs:complexType name="History">
    <xs:complexContent>
        <xs:extension base="Section">
            <!-- Prohibit/remove "Title" attribute from parent. -->
            <xs:attribute name="Title" use="prohibited"/>

            <!-- Add more attributes. -->
            <xs:attribute name="StartDate" type="xs:date" use="required"/>
            <xs:attribute name="EndDate" type="xs:date"/>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

已编辑:回答完全从头开始写,因为第一个不正确(见评论)。

我知道两种方法:

选项1: 同时使用xs:restriction(为了禁止属性)和xs:extension(为了添加更多内容)

<xs:group name="baseGroup">
    <xs:sequence>
        <xs:choice minOccurs="1" maxOccurs="unbounded">
            <!-- ... -->
        </xs:choice>

        <xs:element name="Section" type="Section" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:group>

<xs:complexType name="Section">
    <xs:group ref="baseGroup"></xs:group>
    <xs:attribute name="Key" type="xs:string"/>
    <xs:attribute name="Title" type="xs:string"/>
</xs:complexType>

<xs:complexType name="HistoryWithoutTitle">
    <xs:complexContent>
        <xs:restriction base="Section">
            <!-- Inherit the group (only attributes are inherited) -->
            <xs:group ref="baseGroup"></xs:group>
            <!-- Prohibit/remove "Title" attribute from parent. -->
            <xs:attribute name="Title" type="xs:string" use="prohibited"/>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>    

<xs:complexType name="History">
    <xs:complexContent>
        <xs:extension base="HistoryWithoutTitle">
            <!-- Add more attributes. -->
            <xs:attribute name="StartDate" type="xs:date" use="required"/>
            <xs:attribute name="EndDate" type="xs:date"/>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

选项2: 使用带有公共内容和属性的“接口”,然后制作两个类型(部分和历史),从该接口扩展添加新的内容。这是我更喜欢的选项,因为您可以轻松地将新属性添加到两个元素或仅添加到一个元素。

<!-- This is what both Section and History have in common (similar to an interface) -->
<xs:complexType name="common">
    <!-- Content in both Section and History -->
    <xs:sequence>
        <xs:choice minOccurs="1" maxOccurs="unbounded">
            <!-- ... -->
        </xs:choice>

        <xs:element name="Section" type="Section" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <!-- Attributes in both Section and History -->
    <xs:attribute name="Key" type="xs:string"/>        
</xs:complexType>

<xs:complexType name="Section">
    <xs:complexContent>
        <xs:extension base="common">
            <!-- New attributes -->
            <xs:attribute name="Title" type="xs:string"/>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="History">
    <xs:complexContent>
        <xs:extension base="common">
            <!-- New attributes -->                
            <xs:attribute name="StartDate" type="xs:date" use="required"/>
            <xs:attribute name="EndDate" type="xs:date"/>
        </xs:extension>
    </xs:complexContent>        
</xs:complexType>