W3C home > Mailing lists > Public > xmlschema-dev@w3.org > March 2002

Re: [RESEND] Derivation by restriction

From: Roger L. Costello <costello@mitre.org>
Date: Thu, 28 Mar 2002 08:20:09 -0500
Message-ID: <3CA31889.42D77DE4@mitre.org>
To: xmlschema-dev@w3.org, Simon.Cox@csiro.au
CC: costello@mitre.org
> 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).  

As I read it, your example is defeating the whole purpose of
substitution groups.  You have declared an abstract element _Head1 and
then declared an element Member1 to be in the substitution group with
_Head1.  Fine.  Then you created a complexType ContainHead1Type which
contains _Head1.  Fine.  That's all you need!  Go no further!  Suppose
an element, foo, is declared to be of type ContainHead1Type.  Then, **in
an instance document** the content of <foo> must be any element declared
to be in the substitution group with _Head1. That's what you want to
happen. The philosophy of substutition groups is that the schema defines
a bunch of components that an **instance document author** may utilize. 
Thus, substitution groups empower the instance document author with the
ability to choose among "off the shelf components".  This is a very
powerful design pattern.

On the other hand, what your example is doing is something very
different.  It is creating a second type, ContainMember1Type, which
attempts to declare what element should substitute for the abstract
_Head element.  Why?  If you really want Member1 to be the element then
simply declare a complexType to contain a Member1 element.  I see no
benefit to going through your indirection.  Further, I have serious
doubts that this is even legal (although to be certain I need to consult
the spec).  In general, in a restriction type you must retype everything
in the parent type **verbatim**.  The only differences you may make are
in the number of occurrences and/or the value space of parent elements. 
In your example you are trying to insert a totally new element in the
child type.  It doesn't surprise me that MSXML gives an error with this.

For more info on this topic see the section on variable content
containers using abstract elements in:

http://www.xfront.com/VariableContentContainers.pdf

/Roger

> *** However, both the cases here run afowl of the MSXML parser. ***
> ("Invalid particle derivation by restriction").
> Is MSXML wrong here, or am I missing something else?

I had a look at your schemas and they both seem perfectly fine with me
so my
guess would be a bug in the MSXML parser. I see that Dare Obasanjo from
Microsoft was sent this email as well so he'll probably check this out.
If
not, you can try to submit a bug on the MSXML newsgroup
(microsoft.public.xml.msxml-webrelease) which is monitored by the MSXML
team.

Cheers,
/Eddie

> N.B. In the first case Member1Type is a restriction of Head1Type
> by having a defined content model *** compared with an anyType ***.
> In the second case Member2Type is a restriction of Head2Type
> by restricting the cardinality of the content.
>
> ============
>
> <?xml version="1.0" encoding="UTF-8"?>
> <schema targetNamespace="http://xmml.ned.dem.csiro.au/my"
> xmlns:my="http://xmml.ned.dem.csiro.au/my"
> xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
> attributeFormDefault="unqualified">
>   <!-- -->
>   <element name="_Head1" abstract="true"/>
>   <!-- -->
>   <complexType name="Member1Type">
>     <sequence>
>       <element name="foo" type="string"/>
>     </sequence>
>   </complexType>
>   <!-- -->
>   <element name="Member1" type="my:Member1Type"
> substitutionGroup="my:_Head1"/>
>   <!-- -->
>   <complexType name="ContainHead1Type" abstract="true">
>     <sequence>
>       <element ref="my:_Head1"/>
>     </sequence>
>   </complexType>
>   <!-- -->
>   <complexType name="ContainMember1Type">
>     <complexContent>
>       <restriction base="my:ContainHead1Type">
>         <sequence>
>           <element ref="my:Member1"/>
>         </sequence>
>       </restriction>
>     </complexContent>
>   </complexType>
> </schema>
Received on Thursday, 28 March 2002 08:20:47 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 11 January 2011 00:14:30 GMT