- From: Roger L. Costello <costello@mitre.org>
- Date: Fri, 29 Mar 2002 08:23:27 -0500
- To: Jeni Tennison <jeni@jenitennison.com>
- CC: xmlschema-dev@w3.org, Simon.Cox@csiro.au, costello@mitre.org
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