RE: Use of Substitution Groups

Take 2.  

Is this right?

Another scenario is that a type author wishes any extensions to conform
to certain constraints.  In our Name example, the author wishes to
ensure that an xml:lang attribute is always present.  Wildcards do not
permit this kind of constraint.  Instead, the author uses substitution
groups.  This style can be considered use of substitution groups "at the
bottom" because the substitution group is on each of the contents of the
type.  Family, given then middle are of the same type
(namens:personNameContentType).  Only PersonNameContent elements are
allowed as extensions, and it is abstract and constrained to be of type
namens:personNameContentType.  PersonNameContentType has a constraint
that xml:lang is required.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:namens="http://www.example.org/name/1"
targetNamespace="http://www.example.org/name/1">
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/xml.xsd"/>

	<xs:element name="personName" type="namens:nameType" />
	<xs:complexType name="nameType">
		<xs:sequence minOccurs="0" maxOccurs="unbounded">
			<xs:choice>
				<xs:element
ref="namens:PersonNameContent" minOccurs="0"/>
				<xs:element ref="namens:family"
minOccurs="1"/>
				<xs:element ref="namens:given"
minOccurs="1"/>
			</xs:choice>
		</xs:sequence>
		<xs:anyAttribute namespace="##any"
processContents="strict"/>
	</xs:complexType>
	
	<xs:element name="PersonNameContent" abstract="true"
type="namens:PersonNameContentType"/>
	<xs:element name="given" type="namens:PersonNameContentType"/>
	<xs:element name="family" type="namens:PersonNameContentType"/>

	<xs:complexType name="PersonNameContentType">
	    <xs:simpleContent>
		  <xs:extension base="xs:string">
			<xs:attribute ref="xml:lang"  use="required"/>
		 	<xs:anyAttribute namespace="##any"
processContents="strict"/>
		  </xs:extension>
		</xs:simpleContent>
	</xs:complexType>
	
	<xs:element name="personNameWithMiddle"
type="namens:nameWithMiddleType"/>
	<xs:complexType name="nameWithMiddleType">
		<xs:sequence minOccurs="0" maxOccurs="unbounded">
			<xs:choice>
				<xs:element
ref="namens:PersonNameContent" minOccurs="0"/>
				<xs:element ref="namens:given"
minOccurs="1"/>
				<xs:element ref="namens:family"
minOccurs="1"/>
				<xs:element ref="namens:middle"
minOccurs="0"/>
			</xs:choice>
		</xs:sequence>
		<xs:anyAttribute namespace="##any"
processContents="strict"/>
	</xs:complexType>

	<xs:element name="middle" type="namens:PersonNameContentType"/>
	
</xs:schema>

As with the use of extension, the consumer must know about the new type
when processing personNameWithMiddle elements.  As with wildcards, the
producer could use the personName elements to contain middle elements by
identifying the middle element with
xsi:type="namens:PersonNameContentType".  This gives the producer of
middle elements the option of either reusing the personName (and using
xsi:type) or using the new personNameWithMiddle element.

Cheers,
Dave 

> -----Original Message-----
> From: www-tag-request@w3.org [mailto:www-tag-request@w3.org] 
> On Behalf Of David Orchard
> Sent: Monday, April 23, 2007 12:57 PM
> To: www-tag@w3.org
> Subject: Use of Substitution Groups
> 
> 
> Henry, Dan, etc.,
> 
> Is this the scenario that you are talking about?
> 
> personName and personNameWithMiddle are of 2 different types 
> that are in the substitution group for AbstractPersonName.  
> It's more interesting when the personNameWithMiddle is in a 
> different schema doc and namespace, but this is the heart of it.  
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
>       targetNamespace="http://www.example.org/name/1" 
>       xmlns:namens="http://www.example.org/name/1"> 
> 
>  <xs:element name="AbstractPersonName" abstract="true"/>  
> <xs:element name="personName" type="namens:nameType"
> substitutionGroup="namens:AbstractPersonName"/>
>   
>  <xs:complexType name="nameType">
> 	 <xs:sequence minOccurs="0" maxOccurs="unbounded">
> 		 <xs:choice>
> 			 <xs:element ref="namens:given" /> 
> 			 <xs:element ref="namens:family" /> 
> 		  </xs:choice>
> 	  </xs:sequence>
> 	  <xs:anyAttribute namespace="##any" processContents="strict" />
> 
>   </xs:complexType>
>   
>   <xs:element name="given" type="xs:string"/>
>   <xs:element name="family" type="xs:string"/>
>   
>  <xs:complexType name="nameWithMiddleType">
> 	 <xs:sequence minOccurs="0" maxOccurs="unbounded">
> 		 <xs:choice>
> 		   <xs:element ref="namens:given" /> 
> 		   <xs:element ref="namens:family" /> 
> 		   <xs:element ref="namens:middle" minOccurs="0"/>
> 		 </xs:choice>
> 	 </xs:sequence>
>      <xs:anyAttribute namespace="##any" processContents="strict" />
>   </xs:complexType>
>   
>   <xs:element name="middle" type="xs:string"/>
>   <xs:element name="personNameWithMiddle"
> type="namens:nameWithMiddleType"
> substitutionGroup="namens:AbstractPersonName"/>
>   
> </xs:schema>
> 
> Cheers,
> Dave
> 
> 

Received on Wednesday, 2 May 2007 21:42:51 UTC