XML Schema Restriction for Complex types : Complete Redefinition

xmlxsd

When adding restrictions to complexTypes in XML Schemas , is it necessary to rewrite all the elements used in the definition of the complexType? If so , Why can't it just reuse the existing element definitions and overwrite the new restricted ones?

For example , In the below ; When I just want to restrict the field country , Should I rewrite all the 3 fields again?

<xs:complexType name="customer">
  <xs:sequence>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
    <xs:element name="country" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="Norwegian_customer">
  <xs:complexContent>
    <xs:restriction base="customer">
      <xs:sequence>
        <xs:element name="firstname" type="xs:string"/>
        <xs:element name="lastname" type="xs:string"/>
        <xs:element name="country" type="xs:string" fixed="Norway"/>
      </xs:sequence>
    </xs:restriction>
  </xs:complexContent>
</xs:complexType> 

So , It is pretty clear from the answer below as to why we have to rewrite the whole type.

Follow Up Question

What's the use of this restriction feature then?

One situation , I can think of ; is when you have to validate instance documents containing restricted types in place of base types in xml schema.

Say , If "B" is the base type and its restricted to "B*". Any instance document containing "B*" at the place where an element of type "B" is expected by the Schema Document would work.We would not have to write separate rules for each restricted type.(The attribute "xsi:type" in the instance document will validate it with the correct type.)Right?

Any Other uses of this feature?

Best Solution

Your first question is "When adding restrictions to complexTypes in XML Schemas, is it necessary to rewrite all the elements used in the definition of the complexType?" No, only the ones you want to be part of the definition of the restricted type. But yes, all of the ones that should be part of the restriction. The content model in the restriction must stand on its own as a complete definition of the content model of the type. (It does not, on the other hand, have to specify all the attributes; they are inherited without change unless otherwise specified.)

Your second question is "Why can't it just reuse the existing element definitions and overwrite the new restricted ones?" It's a reasonable question. The answer is slightly tricky: Consider two arbitrary content models E and F. Now, we want to interpret F as a restriction of E that mentions only the elements and model groups in E that we want to change, and omits any mention of the elements and model groups we want alone. Is this a soluble problem, in the general case? Is it guaranteed to have a unique solution? It may seem obvious to you that the answer is yes in both cases, but it did not seem obvious to the designers of XSD at the time, and it does not seem obvious to me today.

For example, let E be

(a+, b+, c*){2}, (a+, b*, c+){3}

and let F be

a{3,4}

If we assume that everything in F is a restriction of something in E and everything else in E should be left alone, does F mean we want to restrict E to

(a{3,4}, b+, c*){2}, (a+, b*, c+)

or to

(a+, b+, c*){2}, (a{3,4}, b*, c+)

?

Addendum

@nikel asks for an XSD example. The example above is already an XSD example, though, so I suppose "an example in XSD syntax" is meant. I take the proposal to be that syntax like the following should work. First we have the base type, E:

<xs:complexType name="E">
  <xs:sequence>
    <xs:sequence minOccurs="2" maxOccurs="2">
      <xs:element ref="a" maxOccurs="unbounded"/>
      <xs:element ref="b" maxOccurs="unbounded"/>
      <xs:element ref="c" minOccurs="0" 
                          maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:sequence minOccurs="3" maxOccurs="3">
      <xs:element ref="a" maxOccurs="unbounded"/>
      <xs:element ref="b" minOccurs="0" 
                          maxOccurs="unbounded"/>
      <xs:element ref="c" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:sequence>
</xs:complexType>

Now let us imagine that we want type F to be able to restrict E without specifying a full content model. So we write

<xs:complexType name="F">
  <xs:complexContent>
    <xs:restriction base="tns:E">
      <xs:sequence>
        <xs:element ref="a" minOccurs="3" maxOccurs="4"/>          
      </xs:sequence>        
    </xs:restriction>
  </xs:complexContent>
</xs:complexType>

What should the effective content model of F be here?

Followup question

You ask, essentially, "in that case, what's the use of restriction?"

Reasonable question. The answer you suggest is a good one. More generally, sometimes we find it useful to know that every instance of type B* will be an instance of type B; derivation by restriction in XSD is intended to guarantee that invariant. Sometimes it seems helpful to define an abstract type with two or more concrete restrictions; that helps ensure that the various concrete realizations of the abstract base type are nicely related to each other, even if none is a subset or superset of any other.

There could be (no: there are plenty of) ways that derivation by restriction could be made clearer, simpler, and more convenient in XSD; not having to repeat the entire content model would be one of them. But then, that's true for pretty much everything in XSD. Its only real virtue is that it is supported by a lot of tools a lot of people seem to want to use.

Related Question