ZVON > Tutorials > XML Schema and Relax NG Tutorial
Index | >> Example 1 / 8 << | Prev | Next |
Contents > Substitutions > Abstract element, substitutionGroup

Abstract element, substitutionGroup

  1. XML Schema
  2. Relax NG
XML Schema keys: abstract, substitutionGroup

1. XML Schema

The schema below defines an abstract element named "myAbstract" (attribute "abstract" is set to "true"). This element cannot appear in the document (because it is abstract). Then we define elements "odd" and "even", which can substitute the "myAbstract" element (see the attribute "substitutionGroup").

Valid document


<root xsi:noNamespaceSchemaLocation="correct_0.xsd" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <odd>7</odd>
</root>

Valid document


<root xsi:noNamespaceSchemaLocation="correct_0.xsd" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <even>4</even>
</root>

Invalid document
Document is not valid, because the element "odd" must contain number 1, 3, 5, 7, or 9.


<root xsi:noNamespaceSchemaLocation="correct_0.xsd" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <odd>2</odd>
</root>

Invalid document
Document is not valid, because the element "even" must contain number 2, 4, 6, 8.


<root xsi:noNamespaceSchemaLocation="correct_0.xsd" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <even>5</even>
</root>

Invalid document
Element "myAbstract" is defined as "abstract" and thus cannot appear in the document.


<root xsi:noNamespaceSchemaLocation="correct_0.xsd" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <myAbstract>2</myAbstract>
</root>

Correct XML Schema (correct_0.xsd)


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

  <xsd:element name="root">
    <xsd:complexType>
      <xsd:sequence minOccurs="1">
        <xsd:element ref="myAbstract"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="myAbstract" type="AAA" abstract="true"/>

  <xsd:simpleType name="AAA">
    <xsd:restriction base="xsd:integer">
      <xsd:minInclusive value="1"/>
      <xsd:maxInclusive value="9"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:element name="odd" substitutionGroup="myAbstract">
    <xsd:simpleType>
      <xsd:restriction base="AAA">
        <xsd:enumeration value="1"/>
        <xsd:enumeration value="3"/>
        <xsd:enumeration value="5"/>
        <xsd:enumeration value="7"/>
        <xsd:enumeration value="9"/>
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

  <xsd:element name="even" substitutionGroup="myAbstract">
    <xsd:simpleType>
      <xsd:restriction base="AAA">
        <xsd:enumeration value="2"/>
        <xsd:enumeration value="4"/>
        <xsd:enumeration value="6"/>
        <xsd:enumeration value="8"/>
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>
</xsd:schema>

2. Relax NG

Although Relax NG does not contain such features, we can achieve the same effect with a Relax NG schema below.

Valid document


<root xmlns="">
  <odd>7</odd>
</root>

Valid document


<root xmlns="">
  <even>4</even>
</root>

Invalid document
Document is not valid, because the element "odd" must contain number 1, 3, 5, 7, or 9.


<root xmlns="">
  <odd>2</odd>
</root>

Invalid document
Document is not valid, because the element "even" must contain number 2, 4, 6, 8.


<root xmlns="">
  <even>5</even>
</root>

Correct Relax NG schema (correctRelax_0.rng)


<grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" ns="" xmlns="http://relaxng.org/ns/structure/1.0" >

  <start>
    <element name="root">
      <ref name="myAbstract"/>
    </element>
  </start>

  <define name="myAbstract">
    <choice>
      <ref name="def_odd"/>
      <ref name="def_even"/>
    </choice>
  </define>

  <define name="def_odd">
    <element name="odd">
      <choice>
        <value>1</value>
        <value>3</value>
        <value>5</value>
        <value>7</value>
        <value>9</value>
      </choice>
    </element>
  </define>

  <define name="def_even">
    <element name="even">
      <choice>
        <value>2</value>
        <value>4</value>
        <value>6</value>
        <value>8</value>
      </choice>
    </element>
  </define>
</grammar>