Question

I have tried all the <xs:all>, <xs:choice>, and <xs:sequence>

Neither of these helps my case satisfactorily.

Does anybody know how would you validate something like this.

<Menu>  
   <SubMenu>
      <MenuItem .. />  
      <MenuItem .. />  
      <MenuItem .. />  
   </SubMenu>  
   <MenuItem .. >  
   <MenuItem .. >  
</Menu>

Where, Under the <Menu> tag <SubMenu> and/or <MenuItem> can occur any number of times(0-n) in any order. But atleast one of them must occur atleast once.

Ignoring validations inside SubMenu tags.

Would appreciate any help in this matter.

Was it helpful?

Solution

If I've understood your requirement correctly then you could phrase the model as "one of SubMenu or MenuItem followed by zero or more SubMenu or MenuItem elements". That can be expressed quite easily as a sequence of two choices:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <!-- whatever your element needs to be modelled as here -->
    <xs:element name="MenuItem">
        <xs:complexType>
            <xs:attribute name="text"/>
        </xs:complexType>
    </xs:element>

   <!-- only modelling the structure of the child elements here -->
    <xs:element name="SubMenu">
        <xs:complexType>
            <xs:sequence>
                <xs:choice minOccurs="1" maxOccurs="1">
                    <xs:element ref="MenuItem"/>
                    <xs:element ref="SubMenu"/>
                </xs:choice>
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element ref="MenuItem"/>
                    <xs:element ref="SubMenu"/>
                </xs:choice>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="Menu">
        <xs:complexType>
            <xs:sequence>
                <xs:choice minOccurs="1" maxOccurs="1">
                    <xs:element ref="MenuItem"/>
                    <xs:element ref="SubMenu"/>
                </xs:choice>
                <xs:choice minOccurs="1" maxOccurs="unbounded">
                    <xs:element ref="MenuItem"/>
                    <xs:element ref="SubMenu"/>
                </xs:choice>
            </xs:sequence>          
        </xs:complexType>
    </xs:element>
</xs:schema>

You could model this more cleanly using a shared global type for Menu and SubMenu but this way is relatively obvious I hope.

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