W3C home > Mailing lists > Public > xmlschema-dev@w3.org > October 2001

Re: constraining an element to be either simple or complex content

From: Jeni Tennison <jeni@jenitennison.com>
Date: Fri, 19 Oct 2001 16:55:39 +0100
Message-ID: <17722773085.20011019165539@jenitennison.com>
To: "Dolan, Kieran" <DolanK@logica.com>
CC: xmlschema-dev@w3.org
Hi Kieran,

> Is there any way in XML schema to specify that an element contains
> either simple content or complex content but not both?.

Basically, no.

> For example: <X>23</X> is valid and <X><Y>45</Y></X> is also valid
> but not <X>23<Y>45</Y></X>. Use of a "mixed" content model permits
> the first two cases but does not exclude the last one.

You could go this route and add a schema adjunct (some RELAX NG or
Schematron elements in xs:appinfo) that went on to define more tightly
that the X element can either have text or a Y element as a child. Of
course you would have to pull out these extra constraints yourself in
order to test them, but they'd be there in the schema for
documentation purposes.

> I have tried to extend a complex type containing complex content
> from a complex type containing simple content. XML Spy version 4.0
> allows this but I understand from previous postings in this group
> that this is not a correct XML schema construct.

That's right - you're not allowed to extend a simple type with a
complex type (Clause 1 of Schema Representation Constraint: Complex
Type Definition Representation OK at
http://www.w3.org/TR/xmlschema-1/#src-ct).

Cheers,

Jeni

P.S.

The only other thing that I can think of would be to use xsi:type
on the instance document to indicate what type the X element should
be. In the schema, define it as being xs:anyType:

<xs:element name="X" type="xs:anyType" />

and define types in your schema for the simple and complex types that
you want, e.g.:

<xs:simpleType name="simpleType">
  <xs:restriction base="xs:integer" />
</xs:simpleType>

<xs:complexType name="complexType">
  <xs:sequence>
    <xs:element name="Y" type="xs:integer" />
  </xs:sequence>
</xs:complexType>

and then use xsi:type to indicate the type of a particular X within
the instance document:

  <X xsi:type="simpleType">23</X>
  <X xsi:type="complexType"><Y>45</Y></X>

Unfortunately, this method isn't really much help unless you're able
to define your own abstract type (so that the author of the instance
is forced to use xsi:type) from which the types that you want to
permit both derive. I don't think you can do this in this situation,
though perhaps someone else can find a way.

---
Jeni Tennison
http://www.jenitennison.com/
Received on Friday, 19 October 2001 11:55:42 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 11 January 2011 00:14:24 GMT