Re: [RESEND] Derivation by restriction

Thanks for keeping me honest Jeni.  I am eager to learn how to use this
design pattern!  I learn best when I can see a concrete example, so how
about considering this example:

1. I have an abstract Publication element.
2. I then create two elements, Book and Magazine, which are
substitutable for Publication.
3. I have an element Catalogue whose contents is Publication.

Here's are the declarations for the above:

<xsd:element name="Publication" abstract="true" 
             type="PublicationType"/>

<xsd:element name="Book" substitutionGroup="Publication" 
             type="BookType"/>
<xsd:element name="Magazine" substitutionGroup="Publication" 
             type="MagazineType"/>

<xsd:element name="Catalogue">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:element ref="Publication" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

[I have omitted the complexType declarations for PublicationType,
BookType, and MagazineType.  Assume the later two derive from the
former.]

As we know, given the above declarations an instance document author is
empowered to populate <Catalogue> with any element that is in the
substitution group with Publication, e.g.,

<Catalogue>
    <Book> ... </Book>
    <Magazine> ... </Magazine>
    <Book> ... </Book>
</Catalogue>

Further, we know that this design pattern is very extensible - new
elements may be added to the substitution group.

Now let's examine the new design pattern.  As I understand it, the first
step is to embed the abstract element within a complexType, e.g.,

<xsd:complexType name="PublicationContainer">
    <xsd:sequence>
        <xsd:element ref="Publication"/>
    </xsd:sequence>
</xsd:complexType>

And then other complexTypes are created which restrict this type, by
replacing the abstract element with a substitution group element, e.g.,

<xsd:complexType name="BookContainer">
    <xsd:complexContent>
        <xsd:restriction base="PublicationContainer">
            <xsd:sequence>
                <xsd:element ref="Book/>
            </xsd:sequence>
        </xsd:restriction>
    <xsd:complexContent>
</xsd:complexType>

As the next step I assume you would then declare Catalogue to be of type
PublicationContainer:

<xsd:element name="Catalogue" type="PublicationContainer"/>

Correct?

What benefit is attained by doing this?  As I see it, in an instance
document the contents of <Catalogue> must be elements that are
substitutable for the abstract Publication element:

<Catalogue>
    <Book> ... </Book>
    <Magazine> ... </Magazine>
    <Book> ... </Book>
</Catalogue>

This is exactly what we had above, but achieved at a cost of an
indirection.  Obviously there is some benefit that I am not seeing. Can
you explain the benefit that is gained by embedding the elements (e.g.,
Publication, Book) within a complexType?  Thanks!  /Roger



Jeni Tennison wrote:
> 
> Hi Roger,
> 
> >> In our schemas we have a /lot/ of cases following a general
> >> pattern:
> >>
> >> 1.  Declare an element to act as head of substitition group;
> >> 2.  Declare non-abstract elements in the substitution group,
> >> with a type derived from the type of the head by restriction;
> >> 3.  Define a complex type which contains the abstract head element;
> >> 4.  Define a restriction of the container which specifies that
> >> a particular concrete member element is present.
> >>
> >> This appears to be pretty much how substitution groups were
> >> designed to be used.
> >
> > Simon, I respectfully disagree. That is NOT how substitution groups
> > were designed to be used. The intended purpose of substitution
> > groups is to enable substitutability in **instance documents**. You
> > are attempting to perform substitution in the **schema**, which in
> > the least is bad practice, if not outright incorrect (I need to
> > check the spec on this).
> 
> It certainly isn't *incorrect*. When a validator checks whether a
> derivation by restriction is valid, it substitutes any particles that
> are head elements of substitution groups with a choice model group
> containing the head and members of the substitution group [1]. The
> restriction is legal as long as it would have been a legal restriction
> if that choice group had been defined originally.
> 
> I don't know whether using substitution groups as Simon is was
> *intended* or not, but it certainly seems to be a growing pattern of
> use. As I see it, when you define the content model for a type, you
> can set constraints on the elements in the content at three levels:
> 
>  - constrain their namespace (using xs:any)
>  - constrain their type (using substitution groups)
>  - constrain their name (using normal element particles)
> 
> All of these are potentially useful types of constraints. And as I see
> it, the constraints or lack of them can be useful both in the instance
> (as you describe) and in the type hierarchy within the schema (as
> Simon described).
> 
> Putting it another way: when you define a common type, to act as an
> ancestor for a number of types, the commonality between the types
> might be of several kinds:
> 
>   - they might contain the same element(s)
>   - they might have the same attribute(s)
>   - they might be used by the same element(s)
>   - they might contain element(s) that have the same type
> 
> Using substitution groups as Simon is reflects the latter kind of
> commonality, where two types contain elements of the same type,
> usually used in the same way.
> 
> Can you explain more about why you think that it's bad practice?
> 
> Cheers,
> 
> Jeni
> 
> [1] http://www.w3.org/TR/xmlschema-1/#cos-particle-restrict
> 
> ---
> Jeni Tennison
> http://www.jenitennison.com/

Received on Friday, 29 March 2002 08:24:44 UTC