XML XSD: Two Definitions for on element

A

Adam dR.

I am not sure if it is possible to create a schema to do what I want.
I would like the element <package-element> to have a different schema
based on the value of it's handler attribute.

This is my XML:

<package-suite>
<timsdata-package name="System Defined Note Categories"
version="32.150">
<package-element handler="db-table-handler">
<table>notecategory</table>
<data>Refund</data>
</package-element>
</timsdata-package>
<timsdata-package name="identifiers" version="33.012">
<package-element handler="identifier-handler">
<file>exe:ident.tbl</file>
</package-element>
</timsdata-package>
</package-suite>

notice the child tags of package-element are different depending on
the value of the handler attribute. Is it possible to do this?

Here was my shot at the XSD file: ( This is invalid because the
timsdata-packagetype defines <xs:element name="package-element"...
twice. This is what I want though. Is there another way to
accomplish this.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:complexType name="db-table-handler-type">
<xs:sequence>
<xs:element name="table" type="xs:string"/>
<xs:element name="data" type="xs:string"/>
</xs:sequence>
<xs:attribute name="handler" type="xs:string" use="required"
fixed="db-table-handler"/>
</xs:complexType>
<xs:complexType name="identity-handler-type">
<xs:sequence>
<xs:element name="file" type="xs:string"/>
</xs:sequence>
<xs:attribute name="handler" type="xs:string" use="required"
fixed="identity-handler"/>
</xs:complexType>
<xs:element name="package-suite">
<xs:complexType>
<xs:sequence>
<xs:element name="timsdata-package" type="timsdata-packageType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="timsdata-packageType">
<xs:sequence>
<xs:element name="package-element" type="db-table-handler-type"/>
<xs:element name="package-element" type="identity-handler-type"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="version" type="xs:decimal" use="required"/>
</xs:complexType>
</xs:schema>

A reference or any help would be appreciated, thanks.
 
G

George Bina

Hi Adam,

What you want is known as co-occurrence constraint and XML Schema does
not support that in its current version, 1.0. The next version of the
XML Schema 1.1 will add more features that will make expressing these
co-occurrence constraints possible.

If you are willing to accept some restrictions then you can use the
special xsi:type attribute in the instance documents to specify the
type of an element and thus you can get a similar behavior as in your
request but instead of handler attribute you will have xsi:type and
instead of some values that you have for that handler attribute you
need to specify types from the schema. You can find a full working
sample below showing this solution.

There is yet another approach to this problem. You can define in the
schema a more relaxed model that accepts both content models and then
enforce the additional constraint either with embedded Schematron
rules or at application level.

Here it is the example with xsi:type.
test.xml
<package-suite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="test.xsd">
<timsdata-package name="System Defined Note Categories"
version="32.150">
<package-element xsi:type="db-table-handler-type">
<table>notecategory</table>
<data>Refund</data>
</package-element>
</timsdata-package>
<timsdata-package name="identifiers" version="33.012">
<package-element xsi:type="identity-handler-type">
<file>exe:ident.tbl</file>
</package-element>
</timsdata-package>
</package-suite>

test.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">

<xs:complexType name="package-element-type" abstract="true"/>
<xs:complexType name="db-table-handler-type">
<xs:complexContent>
<xs:extension base="package-element-type">
<xs:sequence>
<xs:element name="table" type="xs:string"/>
<xs:element name="data" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="identity-handler-type">
<xs:complexContent>
<xs:extension base="package-element-type">
<xs:sequence>
<xs:element name="file" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="package-suite">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="timsdata-package" type="timsdata-
packageType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="timsdata-packageType">
<xs:sequence>
<xs:element name="package-element" type="package-element-type"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="version" type="xs:decimal" use="required"/>
</xs:complexType>
</xs:schema>

Best Regards,
George
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top