ref属性を使ったスキーマ定義

前回の記事で使用したXML Schemaサンプル(下記)ではbook要素の取り決めをbooks要素の取り決めの中に記述していました。

<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="books">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="book">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="title" type="xsd:string" />
              <xsd:element name="price" type="xsd:decimal" />
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

このような記述でも問題ありませんが、このままではインデント(字下げ)が深くなりやすく、読みにくい文書になってしまいます。XML Schemaはその特性からただでさえインデントが深くなりやすいのに、階層が深くなるようなXML文書を取り決めようとした場合、読みにくいといったレベルではなくなってしまうこともあるでしょう。

そこで、「book」要素の取り決めを「books」要素の取り決めの外側に書くようにします。

ref属性で要素を参照

ref属性を使用して親となる要素の外側に、子となる要素の取り決めを書くことができます。

<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="books">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="book" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  
  <xsd:element name="book">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="title" type="xsd:string" />
        <xsd:element name="price" type="xsd:decimal" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

</xsd:schema>

7行目では、book要素のname属性を使用せずにref属性を使用しています。上記サンプルのように、ref属性を記述した場合、その要素の取り決めを別の場所で記述することができます。

この記述方法を知っておくと、要素の数が多く階層が深くなる場合でもわかりやすくて見やすいXML Schemaを書くことができます。