Re: Multiple Types in XSD?

jeni tennison wrote:-
> Hi Lee,
> 
> > Section 2.2.3 ("Naming Conflicts") of XML Schema Part 0: Primer
> > seems to suggest to me that the only way I can define an element as
> > either one thing or another is by using different namespaces.
> >
> > Am I correct in thinking this or is there a more elegant solution?
> 
> There is a more elegant solution, although it does involve changing
> the XML instances (but then, so would using different namespaces).
> 
> The content and attributes of an element are its type, so what you're
> asking here is about saying that an element can either be one type or
> another type.
> 
> You can do this by creating two, related, complex types; with your
> example, since the name element has to come first, I think that
> easiest way is to create an abstract type that allows both a name
> attribute and a name child element, and then restrict it to make the
> two types that you actually want, as follows:
> 
> <xs:complexType name="abstractListType" abstract="true">
>   <xs:sequence>
>     <xs:element name="name" type="xs:string" minOccurs="0" />
>     <xs:element name="data" type="xs:string" />
>   </xs:sequence>
>   <xs:attribute name="name" type="xs:string" />
> </xs:complexType>
> 
> <xs:complexType name="attributeListType">
>   <xs:complexContent>
>     <xs:restriction base="generalListType">
  			    ^^^^^^^^^^^^^^^^	
      I think,                               it's just a typo. It should be
                            abstractListType.
                            
    Cheers
    
    Gopal
    -----
                             
    
>       <xs:sequence>
>         <xs:element name="data" type="xs:string" />
>       </xs:sequence>
>       <xs:attribute name="name" type="xs:string" use="required" />
>     </xs:restriction>
>   </xs:complexContent>
> </xs:complexType>
> 
> <xs:complexType name="elementListType">
>   <xs:complexContent>
>     <xs:restriction base="generalListType">
>       <xs:sequence>
>         <xs:element name="name" type="xs:string" />
>         <xs:element name="data" type="xs:string" />
>       </xs:sequence>
>       <xs:attribute name="name" type="xs:string" use="prohibited" />
>     </xs:restriction>
>   </xs:complexContent>
> </xs:complexType>
> 
> When you define the list element, give it the abstract type as its
> type:
> 
> <xs:element name="list" type="abstractListType" />
> 
> Now, the list element in the instance cannot actually be of the
> abstract list type because it's abstract, so it must be of one of the
> derived types. For each list element in the instance, you have to
> indicate the type of list it is, using the xsi:type attribute, for
> example:
> 
>         <list xsi:type="elementListType">
>                 <name>foo</name>
>                 <data>bar</data>
>         </list>
> or
>         <list xsi:type="attributeListType" name="foo">
>                 <data>bar</data>
>         </list>
> 
> You could do a similar thing, but changing the names of the elements,
> using substitution groups, but I imagine that that's not an option
> (since if they could have different names there wouldn't be this
> problem anyway).
>         
> If you can't change the instances by adding xsi:type attributes, then
> I don't think that there's a way to articulate the constraint using
> XML Schema. In that case, you should make the abstract type
> non-abstract, and use that as the list type, and write the other
> constraints in another way (e.g. using Schematron rules, a RELAX NG
> grammar or just in natural language documentation as you would with a
> DTD).
> 
> Cheers,
> 
> Jeni
> 
> ---
> Jeni Tennison
> http://www.jenitennison.com/
> 

Received on Monday, 25 February 2002 06:45:39 UTC