You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-dev@xerces.apache.org by ta...@ca.ibm.com on 2000/10/13 21:23:35 UTC

Expressing Mutual Exclusive Attributes in XML Schema

Hello Schema Gurus,

In the following example, how can I express in XML Schema that for the
"item" element the attributes "class" and "file" are
mutually exclusive and at least one of them is required.

  <example>
   <item type="one" class="Foo.class">Some Description</item>
   <item type="two" file="Foo.txt">Some Description</item>
  </example>

Cheers,


Tammam


Re: Expressing Mutual Exclusive Attributes in XML Schema

Posted by Andy Clark <an...@apache.org>.
talhamwy@ca.ibm.com wrote:
> In the following example, how can I express in XML Schema that 
> for the "item" element the attributes "class" and "file" are
> mutually exclusive and at least one of them is required.

What you are asking is not possible but the reason is XML syntax,
not Schema. This is one of the things that I don't like about the
Schema grammar itself, you cannot validate a Schema grammar based
on the grammar for Schema itself. Does that make sense?

If you need to have mutually exclusive attributes, it's generally
better to have two separate elements in your grammar. Otherwise,
you'll have to perform a secondary validation step in your
application because the parser won't be able to do that.

Specifically, I would make your grammar such that your sample
becomes the following:

  <example>
   <class-item type="one" class="Foo.class">Some
Description</class-item>
   <file-item type="two" file="Foo.txt">Some Description</file-item>
  </example>

-- 
Andy Clark * IBM, JTC - Silicon Valley * andyc@apache.org

Re: Expressing Mutual Exclusive Attributes in XML Schema

Posted by Ramesh Gupta <ra...@eNode.com>.
on 10/13/00 1:45 PM, Ramesh Gupta at ramesh@enode.com wrote:

> 3.  Or, try equivalence. With this, you can code you entire schema using
> "item", but allow elements "classItem" or "fileItem" to appear anywhere
> "item" may appear. This will give you two attributes per "item", but the
> tradeoff is that the tag itself becomes the discriminator:
> 
> <element    name="item" type="my:ItemType"/>
> <!-- where my: is bound to the target namespace -->
> 
> <complexType    name="ItemType" base="string" derivedBy="extension">
>   <!-- whatever else, plus: -->
>   <attribute  name="type" type="string" use="required"/>
> </complexType>
> 
> <element    name="classItem"    equivClass="my:item">
>   <complexType    base="my:item"  derivedBy="extension">
>       <attribute name="class" type="string" use="required"/>
>   </complexType>
> </element>
> 
> <element    name="fileItem"    equivClass="my:item">
>   <complexType    base="my:item"  derivedBy="extension">
>       <attribute name="file" type="string" use="required"/>
>   </complexType>
> </element>

If you adopt this approach, beware that Xerces 1.2.0 doesn't support
"abstract" yet, so you can't mark item as an abstract type (for now). Until
that is done, it is possible for an instance creator to use "item" which has
neither the class attribute nor the file attribute!

Ramesh


Re: Expressing Mutual Exclusive Attributes in XML Schema

Posted by Ramesh Gupta <ra...@eNode.com>.
on 10/13/00 12:23 PM, talhamwy@ca.ibm.com at talhamwy@ca.ibm.com wrote:

> In the following example, how can I express in XML Schema that for the
> "item" element the attributes "class" and "file" are
> mutually exclusive and at least one of them is required.
> 
> <example>
> <item type="one" class="Foo.class">Some Description</item>
> <item type="two" file="Foo.txt">Some Description</item>
> </example>

You can't.

However, you have some other options:

1.  The cheapest solution: Collapse class and file into a single required
attribute (say "name") and add another required attribute as a discriminator
which takes values from an enumeration (class | file). With this, all item
elements will have 3 attributes instead of the two that you are looking for:

<element    name="item">
    <complexType    base="string"   derivedBy="extension">
        <!-- whatever else, plus: -->
        <attribute  name="type" type="string"   use="required"/>
        <attribute  name="name" type="string"   use="required"/>
        <attribute  name="discriminator"        use="required">
            <simpleType>
                <enumeration    value="class"/>
                <enumeration    value="file"/>
            </simpleType>
        </attribute>
    </complexType>
</element>

2.  Define item as having a mixed content model, and put class and file as
child elements within a choice group. This will probably be too unwieldy.

3.  Or, try equivalence. With this, you can code you entire schema using
"item", but allow elements "classItem" or "fileItem" to appear anywhere
"item" may appear. This will give you two attributes per "item", but the
tradeoff is that the tag itself becomes the discriminator:

<element    name="item" type="my:ItemType"/>
    <!-- where my: is bound to the target namespace -->

<complexType    name="ItemType" base="string" derivedBy="extension">
    <!-- whatever else, plus: -->
    <attribute  name="type" type="string" use="required"/>
</complexType>


<element    name="classItem"    equivClass="my:item">
    <complexType    base="my:item"  derivedBy="extension">
        <attribute name="class" type="string" use="required"/>
    </complexType>
</element>

<element    name="fileItem"    equivClass="my:item">
    <complexType    base="my:item"  derivedBy="extension">
        <attribute name="file" type="string" use="required"/>
    </complexType>
</element>

Hope this helps (even though I know it doesn't meet your requirements
exactly).

Ramesh