无法在子元素中抑制父元素的属性(xsd限制)

时间:2011-02-14 03:02:41

标签: xsd

我想在子元素 CombinedConsumerSubjectResponseType 中压制 subjectIdentifier 属性(在父元素 ConsumerSubjectResponseType 中声明)。我认为不重复子元素中的属性声明就足够了,但显然不是。这可以在xsd中完成吗?

<xs:complexType name="ConsumerSubjectResponseType">
    <xs:sequence>
        <xs:element name="CustomerReferenceNumber" type="xs:string" minOccurs="0"/>
        <xs:element name="Sources" type="xs:string" minOccurs="0"/>
        <xs:element name="AdditionalOutputData" type="xs:string" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="subjectIdentifier" type="xs:string" use="required"/>
</xs:complexType>

<xs:complexType name="CombinedConsumerSubjectResponseType">
    <xs:complexContent>
        <xs:restriction base="ConsumerSubjectResponseType">
            <xs:sequence>
                <xs:element name="Sources" type="xs:string" minOccurs="0"/>
                <xs:element name="AdditionalOutputData" type="xs:string" minOccurs="0"/>
            </xs:sequence>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>

<xs:element name="Test">
    <xs:complexType><xs:sequence>
        <xs:element name="A" type="ConsumerSubjectResponseType"></xs:element>
        <xs:element name="B" type="CombinedConsumerSubjectResponseType"></xs:element>
    </xs:sequence></xs:complexType>
</xs:element>

1 个答案:

答案 0 :(得分:4)

  

这可以在xsd中完成吗?

在你的例子中:不,或不是这样。

通过限制派生的类型必须重复所有粒子组件,但属性不需要在派生类型定义中重复,它们是从基类型继承的。无法从受限制的类型中删除必需的属性。您可以为所需属性指定某个固定(可能为空)的值,并使用use="prohibited"指定可选属性。

一般来说,你要做的是向后退一步,因为“A类的成员,其定义是对另一种类型B的定义的限制,也是B类的成员”和“A”复杂类型定义允许元素或属性内容以及另一个指定类型定义允许的内容被称为扩展名“(引自W3C模式定义12)。

解决方案1,使用xs:extension代替

创建ConsumerSubjectResponseType作为基本类型,并通过扩展名从中派生CombinedConsumerSubjectResponseType

<xs:complexType name="CombinedConsumerSubjectResponseType-base">
    <xs:sequence>
        <xs:element minOccurs="0" name="Sources" type="xs:string" />
        <xs:element minOccurs="0" name="AdditionalOutputData" type="xs:string" />
    </xs:sequence>
</xs:complexType>

<xs:complexType name="ConsumerSubjectResponseType-extension">
    <xs:complexContent>
        <xs:extension base="CombinedConsumerSubjectResponseType-base">
            <xs:sequence>
                <xs:element minOccurs="0" name="CustomerReferenceNumber" type="xs:string" />
            </xs:sequence>
            <xs:attribute name="subjectIdentifier" type="xs:string" use="required" />
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

此解决方案的问题在于,与原始类型定义相比,扩展类型中元素的顺序发生了更改。元素<Sources><AdditionalOutputData>出现在元素<CustomerReferenceNumber>之前。原因是基类型和其他定义被视为顺序组的两个子类,并且首先添加基类型。

解决方案2,使用包含公共元素的xs:group

CombinedConsumerSubjectResponseType中的序列定义为一个组。然后,您只需引用该组即可创建类型CombinedConsumerSubjectResponseType。在ConsumerSubjectResponseType中,您可以在正确的位置添加所需的新元素和属性,还可以参考此组。

<xs:group name="CombinedConsumerSubjectResponse-group">
    <xs:sequence>
        <xs:element minOccurs="0" name="Sources" type="xs:string" />
        <xs:element minOccurs="0" name="AdditionalOutputData" type="xs:string" />
    </xs:sequence>
</xs:group>

<xs:complexType name="ConsumerSubjectResponseType-group">
    <xs:sequence>
        <xs:element minOccurs="0" name="CustomerReferenceNumber" type="xs:string" />
        <xs:group ref="CombinedConsumerSubjectResponse-group" />
    </xs:sequence>
    <xs:attribute name="subjectIdentifier" type="xs:string" use="required" />
</xs:complexType>

<xs:complexType name="CombinedConsumerSubjectResponseType-group">
    <xs:group ref="CombinedConsumerSubjectResponse-group" />
</xs:complexType>

在这种情况下,影响两种类型的更改应该在组上完成,而不是在类型上完成。