views:

131

answers:

1

Say I have two sets of XML elements:

<One/>
<Two/>
<Three/>

And

<A/>
<B/>
<C/>

And I want to have them as children of a bucket element:

<Bucket>
   <A/>
   <One/>
</Bucket>

Or

<Bucket>
   <C/>
   <Two/>
</Bucket>

But I don't want to allow more than one element from either set of elements. I.e:

<Bucket>
   <A/>
   <B/>
   <One/>
</Bucket>

and

<Bucket>
   <A/>
   <One/>
   <Two/>
</Bucket>

would be invalid. How might I express this in my XML Schema?

I thought to try xs:unique but that prevents name() and local-name() usage in the field or selector.

UPDATE

The full solution is:

<xs:element name="Bucket">
  <xs:complexType>
    <xs:sequence>
      <xs:choice minOccurs="0">
        <xs:element name="A"/>
        <xs:element name="B"/>
        <xs:element name="C"/>
      </xs:choice>
      <xs:choice minOccurs="0">
        <xs:element name="One"/>
        <xs:element name="Two"/>
        <xs:element name="Three"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>
</xs:element>
+2  A: 

I'd go with something like,

<xs:element name="Bucket">
  <xs:complexType>
    <xs:sequence>
      <xs:choice>
        <xs:element name="A"/>
        <xs:element name="B"/>
        <xs:element name="C"/>
      </xs:choice>
      <xs:choice>
        <xs:element name="One"/>
        <xs:element name="Two"/>
        <xs:element name="Three"/>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>
</xs:element>

But probably with better types defined to represent the choices instead of having them inline like that. But the general idea is the same.

By default, minOccurs and maxOccurs are set to 1, so by default this doesn't permit multiples of each type to be present. It also means they aren't optional. If you want either group to be optional, you should add minOccurs='0' to the <xs:choice> element.

Welbog
Hmm...This does not seem to be valid. One `xs:choice` is allowed, but two (without a container) is not. I also tried nesting choices, but neither seems to be valid in my editor (vs2010).
ee
ah..looks like wrapping in `xs:sequence` does the trick. testing...
ee
Yeah...I think i was making it harder than it was. Thanks for the suggestion.
ee
@ee: I tossed in the sequence for you. Sorry about that, but I was too busy at the time to test the code myself. Thanks for the heads up.
Welbog