joedotnot
joedotnot

Reputation: 5133

XML Schema (XSD) - How to specify parent element to contain at least one child element?

I have an XML schema (XSD) that defines an element as mandatory (call it the parent); this parent has, lets say, five child elements, which can all be optional, BUT AT LEAST ONE child element must occur.

How can i specify this in the xsd?

To clarify: The children are different elements and optional. For example.

<Parent>
   <Child1>contents are different to other siblings and arbitrary</Child1>
   <Child2>can be text, a simple element, or another complex element</Child2>
   <Child3>etc.. etc</Child3> 
</Parent>

<xs:complexType name="Parent">
  <xs:sequence>
    <xs:element minOccurs="0" name="Child1" type="xs:string"/>
    <xs:element minOccurs="0" name="Child2" />
    <xs:element minOccurs="0" name="Child3" />
  </xs:sequence>
</xs:complexType>

Even though every child is optional, the parent needs to have at least one child.

Upvotes: 7

Views: 8913

Answers (5)

TroudhuK
TroudhuK

Reputation: 11

<xs:complexType name="Parent">
  <xs:choice maxOccurs="unbounded">
    <xs:element name="Child1" type="xs:string"/>
    <xs:element name="Child2" />
    <xs:element name="Child3" />
  </xs:sequence>
</xs:complexType>

Putting the maxOccurs="unbounded" to the choice (minOccurs=1 by default => at least one child)

Upvotes: 1

Max
Max

Reputation: 19994

Using assertions (I think it is only available in XSD 1.1) it is possible to do the following:

<xs:element name="Parent">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Child1" type="xs:string" minOccurs="0"/>
            <xs:element name="Child2" minOccurs="0"/>
            <xs:element name="Child3" minOccurs="0"/>
        </xs:sequence>
        <xs:assert test="count(*)>=1"/>
    </xs:complexType>
</xs:element>

Upvotes: 3

WReach
WReach

Reputation: 18271

There is always the direct approach:

<xs:complexType name="Parent">
  <xs:choice>
    <xs:sequence>
      <xs:element name="Child1"/>
      <xs:element name="Child2" minOccurs="0"/>
      <xs:element name="Child3" minOccurs="0"/>
    </xs:sequence>
    <xs:sequence>
      <xs:element name="Child2"/>
      <xs:element name="Child3" minOccurs="0"/>
    </xs:sequence>
    <xs:sequence>
      <xs:element name="Child3"/>
    </xs:sequence>
  </xs:choice>
</xs:complexType>

Upvotes: 5

swegi
swegi

Reputation: 4102

You can create a substitution group which incorporates all your child elements. For this you use the minOccurs attribute to specify that at least one element of the group must occur in the document.

Upvotes: 0

Ray Lu
Ray Lu

Reputation: 26638

Use minOccurs, e.g.

<xsd:complexType name="Parent">
  <xsd:sequence>
    <xsd:element minOccurs="1" maxOccurs="5" name="Child" type="q10:string"/>
    </xsd:sequence>
</xsd:complexType>

Upvotes: 0

Related Questions