Question

I have a XSD schema that I use to validate XML files.

In the XSD schema, I created a complex type containing an attributes group and a choice, itself containg "_output", a recurring element.

My complex type :

<xs:complexType name="base_action">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="_output" minOccurs="0" maxOccurs="unbounded"/>
    </xs:choice>
    <xs:attributeGroup ref="action"/>
</xs:complexType>

I also have other elements (with child elements of their own) inheriting from that complex type.

An exemple of such inheriting element :

<xs:element name="ex_elem" minOccurs="0">
    <xs:complexType>
        <xs:complexContent>
            <xs:extension base="cockpit_base_action">
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="to" minOccurs="0"/>
                    <xs:element name="from" minOccurs="0"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
</xs:element>

Now, in the XML, this will work :

<ex_elem>
    <_output/>
    <from>0</from>
    <to>1</to>
</ex_elem>

But not this :

<ex_elem>
    <from>0</from>
    <_output/>
    <to>1</to>
</ex_elem>

Or this :

<ex_elem>
    <from>0</from>
    <to>1</to>
    <_output/>
</ex_elem>

From what I understand, the choice from the complex type can't mix with the choice of the inheriting element. This is a problem for me, because there are sitations where I would want to put _output somewhere else than at the top.

I would want to be able to use the element without having to bother about the sequence. Is there a way to do so?

Was it helpful?

Solution

In XSD 1.0, any extension of a base type creates a sequence whose first member is the old content model and whose second member is the top of the extension's addition to the content model. So the effective content model of your extension of cockpit_base_action is

<xs:sequence>
  <xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:element name="_output" 
                minOccurs="0" 
                maxOccurs="unbounded"/>
  </xs:choice> 
  <xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:element name="to" minOccurs="0"/>
    <xs:element name="from" minOccurs="0"/>
  </xs:choice>
</xs:sequence>

In XSD 1.1, you can change the base type to use xs:all, and use xs:all in the extension, to get the effect you want.

Or (in either 1.0 or 1.1), you can change the extension to accept the language you want. Something like this should have the effect you seem to desire:

<xs:extension base="cockpit_base_action">
  <xs:sequence minOccurs="0">
    <xs:choice>
      <xs:element name="to">
      <xs:element name="from"/>
    </xs:choice>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="_output"/>
      <xs:element name="to">
      <xs:element name="from"/>
    </xs:choice>
  </xs:sequence>
</xs:extension>

I've omitted the occurrence indicators on the children of the choice elements, since they have no effect on the language accepted: they are necessarily optional when the containing choice (or the sequence containing it) is optional; they can necessarily repeat without bound, when the containing choice can do so.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top