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