RE: Need help with any and all

Thank you so much for responding... and responding so quickly!!!

I actually found another option (perseverence is key :):

	<xs:group name="baseGroup">
		<xs:all>
			<xs:element name="A" type="xs:string" minOccurs="1"
maxOccurs="1"/>
			<xs:element name="B" type="xs:string" minOccurs="1"
maxOccurs="1"/>
			<xs:element name="C" type="xs:string" minOccurs="1"
maxOccurs="1"/>
		</xs:all>
	</xs:group >

	<xs:complexType name="extendedType">
		<xs:sequence>
			<xs:group ref="tns:baseGroup"/>
			<xs:any namespace="##other" minOccurs="0"
maxOccurs="unbounded" processContents="skip"/>
		</xs:sequence>
	</xs:complexType>
	
	<xs:element name="TOP" type="tns:extendedType"/>
	
</xs:schema>

Granted, my "extra" elements have to appear at the end but I do have
order-independence among my required elements.  In retrospect, I think I'll
give extra consideration to your third scenario though... 

-----Original Message-----
From: Jeni Tennison [mailto:jeni@jenitennison.com]
Sent: Monday, February 25, 2002 1:26 PM
To: Brenda Bell
Cc: 'xmlschema-dev@w3.org'
Subject: Re: Need help with any and all


Hi Brenda,

> I'm trying to develop a schema that requires element X to:
>
>     have exactly one each of child elements A, B and C in any order
>     allow other child elements from any other namespace
>
> I've been able to develop schemas that meet two of my three
> requirements but not all three. I've also been able to develop a
> schema that appears to meet all three, however validation succeeds
> when any of the required elements are omitted. If anyone else has
> done something similar, I would really appreciate any guidance you
> have to offer.

Yes, if you use xs:all to allow the elements to occur in any order
then you can't use the xs:any wildcard to allow any combination of
elements. If you use substitution groups, you can allow A, B or C in
any order, and use a wildcard, but you can't guarantee that there's
only one each of A, B and C.

So you have three options, I think:

Firstly, you could make the XML Schema enumerate the possible
combinations. This is a bit of a headache - not *too* awful with three
elements, but pretty bad:

  <xs:sequence>
    <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" />
    <xs:choice>
      <xs:sequence>
        <xs:element ref="A" />
        <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" />
        <xs:choice>
          <xs:sequence>
            <xs:element ref="B" />
            <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded"
/>
            <xs:element ref="C" />
            <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded"
/>
          </xs:sequence>
          <xs:sequence>
            <xs:element ref="C" />
            <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded"
/>
            <xs:element ref="B" />
            <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded"
/>
          </xs:sequence>
        </xs:choice>
      </xs:sequence>
      ...
    </xs:choice>

Secondly, you could use a more general content model, and then add any
additional constraints using a schema adjunct, such as Schematron. For
example:

  <xs:choice minOccurs="3" maxOccurs="unbounded">
    <xs:annotation>
      <xs:appinfo>
        <sch:rule context="X">
          <sch:assert test="count(A) = 1">
            There can only be one A element
          </sch:assert>
          <sch:assert test="count(B) = 1">
            There can only be one B element
          </sch:assert>
          <sch:assert test="count(C) = 1">
            There can only be one C element
          </sch:assert>
        </sch:rule>
      </xs:appinfo>
    </xs:annotation>
    <xs:element ref="A" />
    <xs:element ref="B" />
    <xs:element ref="C" />
    <xs:any namespace="##other" />
  </xs:choice>

Thirdly, you could make your markup language easier to represent with
an XML Schema by wrapping the elements in other namespaces within
another element. Then you can use xs:all as follows:

  <xs:all>
    <xs:element ref="A" />
    <xs:element ref="B" />
    <xs:element ref="C" />
    <xs:element name="D">
      <xs:complexType>
        <xs:sequence>
          <xs:any namespace="##other" minOccurs="0"
                                      maxOccurs="unbounded" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  </xs:all>
  
Finally, you could make your markup language easier to represent with
an XML Schema by choosing a canonical representation in which the
order of A, B and C (and the wildcard) is specified. You could
constrain such a content model very easily:

  <xs:sequence>
    <xs:element ref="A" />
    <xs:element ref="B" />
    <xs:element ref="C" />
    <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" />
  </xs:sequence>

You could provide a small script, stylesheet or query to transform
from unordered versions to the canonical ordering for the purpose of
validation.
  
Cheers,

Jeni

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

Received on Monday, 25 February 2002 13:59:27 UTC