【问题标题】:Restrict attribute from parent while extending with new attributes在使用新属性扩展时限制来自父级的属性
【发布时间】:2015-01-27 18:58:01
【问题描述】:

我有复杂类型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>

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

【问题讨论】:

    标签: xml xsd


    【解决方案1】:

    已编辑:答案完全从头开始编写,因为第一个不正确(请参阅 cmets)。

    我知道这样做的两种方法:

    选项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: 使用具有通用内容和属性的“接口”,然后制作从该接口扩展的两种类型(Section 和 History),添加新的内容。这是我更喜欢的选项,因为您可以轻松地将新属性添加到两个元素或仅添加到一个元素。

    <!-- 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>
    

    【讨论】:

    • 啊,是的,这是有道理的。不幸的是,您必须创建一个新类型来执行此操作,而不是能够在同一类型上同时使用 xs:restrictionxs:extension。谢谢!
    • 虽然这个解决方案很有意义,但我尝试过,现在History 类型不再接受子元素:“元素历史记录不能包含子元素 X,因为父元素的内容模型为空。”尽管父级的内容模型不是为空 - 好像限制也破坏了内容模型?
    • 我错了。似乎在限制元素时仅继承属性。如果您还想继承组(序列),则必须将其也包含在受限类型中。来源在 this question 。我更新了定义两种新方法的问题,我更喜欢第二种方法,也许另一个用户知道更好的答案,因为我认为这变得过于复杂了。
    猜你喜欢
    • 2021-12-18
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-17
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多