- From: Roger L. Costello <costello@mitre.org>
- Date: Thu, 28 Mar 2002 08:20:09 -0500
- 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 UTC