Search code examples
inheritancexsdextendderivedredefinition

How to add a key into a derived schema?


Here is a simplified example of the problem:

base.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

    <xs:element name="root" type="root" />
    <xs:complexType name="root">
        <xs:sequence>
            <xs:element name="items" minOccurs="0" />
        </xs:sequence>
    </xs:complexType>

    <xs:element name="items" type="items" />
    <xs:complexType name="items">
        <xs:sequence>
            <xs:element name="item" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

</xs:schema>

derived.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:redefine schemaLocation="base.xsd">
        <!-- redefining types from base.xsd ... -->
    </xs:redefine>
</xs:schema>    

I would like to define a key on items in derived.xsd, but not in base.xsd. So the behavior of the base schema should not change, but in the derived schema, it should behave by the following definition:

<xs:element name="root">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="items" minOccurs="0">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="item" minOccurs="0" maxOccurs="unbounded" />
                    </xs:sequence>
                </xs:complexType>
                <xs:key name="itemKey">
                    <xs:selector xpath="item" />
                    <xs:field xpath="." />
                </xs:key>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Still, I derived.xsd should stay derived from base.xsd, because there are other elements in my real schema which I need to inherit.


Solution

  • The following worked for me.

    derived.xsd

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
        <xs:redefine schemaLocation="base.xsd">
            <xs:complexType name="root">
                <xs:complexContent>
                    <xs:restriction base="root">
                        <xs:sequence>
                            <xs:element name="items" type="items" minOccurs="0">
                                <xs:key name="itemKey">
                                    <xs:selector xpath="item" />
                                    <xs:field xpath="." />
                                </xs:key>
                            </xs:element>
                        </xs:sequence>
                    </xs:restriction>
                </xs:complexContent>
            </xs:complexType>
        </xs:redefine>
    </xs:schema>