ZVON > Tutorials > XML Schema and Relax NG Tutorial
Index | >> Example 8 / 9 << | Prev | Next |
Contents > Simple tasks > Element which contains two "patterns" (sequences), in any order

Element which contains two "patterns" (sequences), in any order

  1. XML Schema
  2. Relax NG
XML Schema keys: group, sequence, choice
Relax NG keys: choice, group

1. XML Schema

We want to have the root element to be named "AAA", from null namespace and contains two patterns in any order. The first pattern is a sequence of "BBB" and "CCC" elements, the second one is a sequence of "XXX" and "YYY" element. The element "choice" allows one of the cases: either the sequence "myFirstSequence"-"mySecondSequence" or "mySecondSequence"-"myFirstSequence".

Valid document


<AAA xsi:noNamespaceSchemaLocation="correct_0.xsd" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <BBB>111</BBB>
  <CCC>xxx</CCC>
  <XXX>1</XXX>
  <YYY>2</YYY>
</AAA>

Valid document


<AAA xsi:noNamespaceSchemaLocation="correct_0.xsd" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <XXX>1</XXX>
  <YYY>2</YYY>
  <BBB>111</BBB>
  <CCC>xxx</CCC>
</AAA>

Correct XML Schema (correct_0.xsd)


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

  <xsd:element name="AAA">
    <xsd:complexType mixed="false">
      <xsd:choice>
        <xsd:sequence>
          <xsd:group ref="myFirstSequence" minOccurs="1" maxOccurs="1"/>
          <xsd:group ref="mySecondSequence" minOccurs="1" maxOccurs="1"/>
        </xsd:sequence>
        <xsd:sequence>
          <xsd:group ref="mySecondSequence" minOccurs="1" maxOccurs="1"/>
          <xsd:group ref="myFirstSequence" minOccurs="1" maxOccurs="1"/>
        </xsd:sequence>
      </xsd:choice>
    </xsd:complexType>
  </xsd:element>

  <xsd:group name="myFirstSequence">
    <xsd:sequence>
      <xsd:element name="BBB" type="xsd:string" minOccurs="1"/>
      <xsd:element name="CCC" type="xsd:string" minOccurs="1"/>
    </xsd:sequence>
  </xsd:group>

  <xsd:group name="mySecondSequence">
    <xsd:sequence>
      <xsd:element name="XXX" type="xsd:string" minOccurs="1"/>
      <xsd:element name="YYY" type="xsd:string" minOccurs="1"/>
    </xsd:sequence>
  </xsd:group>
</xsd:schema>

2. Relax NG

The element "choice" allows one of the cases: either the sequence "myFirstSequence"-"mySecondSequence" or "mySecondSequence"-"myFirstSequence".

Valid document


<AAA xmlns="">
  <BBB>111</BBB>
  <CCC>xxx</CCC>
  <XXX>1</XXX>
  <YYY>2</YYY>
</AAA>

Valid document


<AAA xmlns="">
  <XXX>1</XXX>
  <YYY>2</YYY>
  <BBB>111</BBB>
  <CCC>xxx</CCC>
</AAA>

Invalid document


<AAA xmlns="">
  <BBB>111</BBB>
</AAA>

Invalid document


<AAA xmlns=""/>

Invalid document


<AAA xmlns="">
  <BBB>111</BBB>
  <XXX>1</XXX>
  <CCC>aaa</CCC>
  <YYY>2</YYY>
</AAA>

Correct Relax NG schema (correctRelax_0.rng)


<grammar xmlns="http://relaxng.org/ns/structure/1.0" >

  <start>
    <element>
      <name ns="">AAA</name>
      <choice>
        <group>
          <ref name="myFirstSequence"/>
          <ref name="mySecondSequence"/>
        </group>
        <group>
          <ref name="mySecondSequence"/>
          <ref name="myFirstSequence"/>
        </group>
      </choice>
    </element>
  </start>

  <define name="myFirstSequence">
    <group>
      <element>
        <name>BBB</name>
        <text/>
      </element>
      <element>
        <name>CCC</name>
        <text/>
      </element>
    </group>
  </define>

  <define name="mySecondSequence">
    <group>
      <element>
        <name>XXX</name>
        <text/>
      </element>
      <element>
        <name>YYY</name>
        <text/>
      </element>
    </group>
  </define>
</grammar>