Re: xs:all - why is minOccurs, maxOccurs restricted to "0" or "1" for child xs:element ?

Hi Gary,

> If I'm not mistaken, this restriction on xs:all means it is
> impossible to write an XML-Schema for XHTML. Try to define the
> <body> element for example... There is a group working on modular
> definitions, supposedly to permit more flexibility as the XHTML spec
> evolves, but I also suspect because there is no other way to do it.
> I'd be happy if somebody could prove me wrong.

It's never *impossible* to write a schema for any markup language. For
example, you could just do:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:html="http://www.w3.org/1999/xhtml"
           targetNamespace="http://www.w3.org/1999/xhtml"
           elementFormDefault="qualified">

<xs:complexType name="anything">
  <xs:sequence>
    <xs:any namespace="##targetNamespace" />
  </xs:sequence>
</xs:complexType>
           
<xs:element name="html" type="html:anything" />
<xs:element name="head" type="html:anything" />
<xs:element name="body" type="html:anything" />
... and so on ...
           
</xs:schema>

The schema isn't very *good* - it doesn't catch all the cases that
we'd consider invalid - but it's still a schema for XHTML.

You could say that it's impossible to write a *good* schema for XHTML,
but even then I don't think that's actually true. XHTML has a
perfectly good DTD, and any constraint that you can represent in a DTD
you can represent in an XML Schema schema. Taking the definition of
body, which you mentioned:

<!ELEMENT body %Block;>

You could create:

<xs:element name="body">
  <xs:complexType>
    <xs:group ref="html:Block" />
  </xs:complexType>
</xs:element>

The definition of %Block; is:

<!ENTITY % Block "(%block; | form | %misc;)*">

Which can be translated to:

<xs:group name="Block">
  <xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:group ref="html:block" />
    <xs:element ref="html:form" />
    <xs:group ref="html:misc" />
  </xs:choice>
</xs:group>

and so on.

There are certainly places in the original HTML DTD that used the SGML
& connector, I believe, for example the content of the head element,
which has to contain a title element, and can contain a maximum of 1
base element, as well as various other elements. This would be a good
place for xs:all, but it can't be used because of the restrictions on
it. But that doesn't mean we can't use the same solution as was used
for the XHTML DTD:

<!ELEMENT head (%head.misc;,
     ((title, %head.misc;, (base, %head.misc;)?) |
      (base, %head.misc;, (title, %head.misc;))))>

In schema, you could similarly do:

<xs:element name="head">
  <xs:sequence>
    <xs:group ref="html:head.misc"
              minOccurs="0" maxOccurs="unbounded" />
    <xs:choice>
      <xs:sequence>
        <xs:element ref="html:title" />
        <xs:group ref="html:head.misc"
                  minOccurs="0" maxOccurs="unbounded" />
        <xs:sequence minOccurs="0">
          <xs:element ref="html:base" />
          <xs:group ref="html:head.misc"
                    minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
      </xs:sequence>
      <xs:sequence>
        <xs:element ref="html:base" />
        <xs:group ref="html:head.misc"
                  minOccurs="0" maxOccurs="unbounded" />
        <xs:element ref="html:title" />
        <xs:group ref="html:head.misc"
                  minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:choice>
  </xs:sequence>
</xs:element>

Was there somewhere else in XHTML where you thought xs:all would be
useful if it wasn't for the constraints on what it can contain?

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

Received on Monday, 1 April 2002 11:06:23 UTC