Re: using xsd:choice + element value

Hi Matt,

> The primary issue is that a schema needs to implement a 'choice' based
> on a prior element 'value'.   The animal schema below illustrates the
> point that the qualifier value of "dog | cat" cannot qualify the choice
> elements (dogName | catName).  In other words the schema is valid with
>
>         <animalType>cat</animal>
>         <dogName>Scooby</dogName>
>
> which is not the intent and therefore is not properly communicated.  Is
> this simply not possible???

Not with W3C XML Schema alone but if you don't mind extending the schema
with embedded Schematron rules you can do this fairly easy. The example
below illustrates how this can be done by embedding Schematron rules in the
appinfo for the animal element declaration. For more info on how to process
this schema see my article at [1].

<xsd:simpleType name="qualifier">
    <xsd:enumeration value="dog"/>
    <xsd:enumeration value="cat"/>
</xsd:simpleType>

<xsd:element name="animal" type="animalType">
    <xsd:annotation>
        <xsd:appinfo>
            <sch:pattern name="Test animal type"
xmlns:sch="http://www.ascc.net/xml/schematron">
                <sch:rule context="animal[animalQualifier = 'dog']">
                    <sch:assert test="dogName">If the animal is a dog you
must have a dogName.</sch:assert>
                </sch:rule>
                <sch:rule context="animal[animalQualifier = 'cat']">
                    <sch:assert test="catName">If the animal is a dog you
must have a dogName.</sch:assert>
                </sch:rule>
            </sch:pattern>
        </xsd:appinfo>
    </xsd:annotation>
</xsd:element>

<xsd:complexType name="animalType">
    <xsd:sequence>
        <xsd:element name="animalQualifier" type="qualifier"/>
        <xsd:choice>
            <xsd:element name="dogName" type="xsd:string"/>
            <xsd:element name="catName" type="xsd:string"/>
        </xsd:choice>
    </xsd:sequence>
</xsd:complexType>

Cheers,
/Eddie

[1] http://www.topologi.com/public/Schtrn_XSD/Paper.html


>
>
> <xsd:simpleType name="qualifier">
>         <xsd:enumeration value="dog"/>
>         <xsd:enumeration value="cat"/>
> </xsd:simpleType>
>
> <xsd:element name="animal" type="animalType"/>
>
> <xsd:complexType name="animalType">
>         <xsd:sequence>
>                 <xsd:element name="animalQualifier" type="qualifier"/>
>                 <xsd:choice>
>                         <xsd:element name="dogName" type="xsd:string"/>
>                         <xsd:element name="catName" type="xsd:string"/>
>                 </xsd:choice>
>         </xsd:sequence>
> </xsd:complexType>
>
> > -----Original Message-----
> > From: Eddie Robertsson [mailto:erobertsson@allette.com.au]
> > Sent: Sunday, May 26, 2002 7:11 PM
> > To: mlong@phalanxsys.com
> > Cc: xmlschema-dev@w3.org
> > Subject: Re: using xsd:choice + element value
> >
> > Hi Matt,
> >
> > No, you can't do that using the design you have in your schema.
> However,
> > if I understand your problem correct I think you can use the technique
> > of using xsi:type in the instance document to specify which type an
> > element should use from the instance document. Here is a modified
> > version of your schema where complexTypes are used instead of groups:
> >
> > <xsd:element name=”whatIsIt” type=”baseType”/>
> >
> > <!-- Empty type that is used as a common base for personType and
> > placeType -->
> > <xsd:complexType name="baseType"/>
> >
> > <!-- Type defining the person -->
> > <xsd:complexType name=”personType”>
> >     <xsd:complexContent>
> >         <xsd:extension base="baseType">
> >             <xsd:sequence>
> >                 <xsd:element name=”firstName” type=”xsd:string”/>
> >                 <xsd:element name=”lastName” type=”xsd:string”/>
> >             </xsd:sequence>
> >         </xsd:extension>
> >     </xsd:complexContent>
> > </xsd:complexType>
> >
> > <!-- Type defining the place -->
> > <xsd:complexType name=”placeType”>
> >     <xsd:complexContent>
> >         <xsd:extension base="baseType">
> >             <xsd:sequence>
> >                 <xsd:element name=”country” type=”xsd:string”/>
> >                 <xsd:element name=”city” type=”xsd:string”/>
> >             </xsd:sequence>
> >         </xsd:extension>
> >     </xsd:complexContent>
> > </xsd:complexType>
> >
> > Note that the whatIsIt element have the type baseType. Also, I have
> > removed you qualifier element because instead of using an element to
> > qualify which type is used we're going to use xsi:type in the instance
> > to specify which of the derived types the whatIsIt element has. E.g.
> >
> > <whatIsIt xsi:type="personType">
> >     <firstName>aaa</firstName>
> >     <lastName>bbb</lastName>
> > </whatIsIt>
> >
> > This will only validate the whatIsIt element if it has subelements
> > matching the personType. The same applies for the placeType:
> >
> > <whatIsIt xsi:type="placeType">
> >     <country>aaa</country>
> >     <city>bbb</city>
> > </whatIsIt>
> >
> > Is this something that would fit your requirement?
> >
> > Cheers,
> > /Eddie
> >
> >
> > > Is it possible to utilize ‘choice’ from an element value (not purely
> > > the existence of the element name)
> > >
> > > Example: a schema with a qualifier (1=person, 2=place)…so the
> question
> > > is how can one determine the group ref from the element value of
> > > ‘qualifier’ element (or is it simply not possible)?
> > >
> > > -Matt Long
> > >
> > > Phalanx Systems, LLC
> > >
> > > <xsd:element name=”whatIsIt” type=”z:infoType”/>
> > >
> > > <xsd:complexType name=”infoType”>
> > >
> > > <xsd:sequence>
> > >
> > > <xsd:element name=”qualifier” type=”z:myQualType”/>
> > >
> > > <!—how can ‘qualifier’ qualify the choice of group reference à
> > >
> > > <xsd:choice>
> > >
> > > <xsd:group ref=”z:personGroup”/>
> > >
> > > <xsd:group ref=”z:placeGroup”/>
> > >
> > > </xsd:choice>
> > >
> > > </xsd:sequence>
> > >
> > > </xsd:complexType>
> > >
> > > <xsd:group name=”personGroup”>
> > >
> > > <xsd:sequence>
> > >
> > > <xsd:element name=”firstName” type=”xsd:string”/>
> > >
> > > <xsd:element name=”lastName” type=”xsd:string”/>
> > >
> > > </xsd:sequence>
> > >
> > > </xsd:group>
> > >
> > > <xsd:group name=”placeGroup”>
> > >
> > > <xsd:sequence>
> > >
> > > <xsd:element name=”country” type=”xsd:string”/>
> > >
> > > <xsd:element name=”city” type=”xsd:string”/>
> > >
> > > </xsd:sequence>
> > >
> > > </xsd:group>
> > >
> > > <xsd:simpleType name=”myQualType”>
> > >
> > > <xsd:restriction base=”xsd:string”>
> > >
> > > <xsd:enumeration value=”1”/>
> > >
> > > <xsd:enumeration value=”2”/>
> > >
> > > </xsd:restriction>
> > >
> > > </xsd:simpleType>
> > >

Received on Monday, 27 May 2002 20:03:45 UTC