属性宣言: 単純型内容を持った複合型の制限(属性の削除など)

2002年9月15日(日)更新


■復習: 単純型と複合型の派生

たけち: まず今までの復習だけれど、単純型を定義するためには3つの派生の方法があったよね。

さらら: え〜と、制限(restriction)とユニオン(union)とリスト(list)よね。

たけち: そして今まで単純型内容をもった複合型を派生させるために、拡張(extension)を使っていたよね。ところで単純型内容をもった複合型を派生させるためには、もう一つの派生方法があるんだよ。つまり、拡張(extension)と、もう一つ、合計2つの派生方法があるんだ。

さらら: え〜。単純型も含めて数えたら、5つも派生方法があるってこと? 覚えるのが大変だわ。

たけち: う〜ん、それがそれほどでもないよ。そのもう一つとは、以前さんざん勉強した制限(restriction)なんだよ

さらら: あ、単純型内容をもった複合型も、単純型みたいに制限(restriction)が使えるのね。

たけち

単純型と複合型の派生

さらら: でも単純型を制限して、「単純型内容をもった複合型」ができるの?

たけち: あ、そうじゃないよ (^ ^; もちろんそんなことは不可能だよね。ここで取り上げたいのは単純型内容をもった複合型を制限して単純型内容をもった複合型を作ることなんだよ。

さらら: あ、なるほどね (^ ^; でも、この制限って、単純型の制限と同じようなものなのかしら。

たけち: そうだね。これは単純型の制限と同じ機能も持っている上に、さらに属性に対して作用する新しい機能も2つ加わっているんだ。以下にまとめてみるね。

たけち

【単純型内容をもった複合型の制限】

  1. 内容に対して制約ファセットを適用(単純型の制限と同じ)
  2. 属性の出現制約を強化
    (デフォルト値や固定値を新たに定めることも含む)
  3. 属性に使用されている単純型の値の範囲を狭める

■内容に対して制約ファセットを適用

たけち: これら3つの機能のどれか、またはどれでもいくつでも組み合わせて使うことができるのが単純型内容をもった複合型の制限(restriction)なんだ。

さらら: 要するに単純型の制限と比べると、属性に対する機能が増えているわけね。

たけち: そういうわけだね。まず最初の内容に対して制約ファセットを適用というのは、単純型とまったく同じだから、もうここでは詳しいことは説明しないよ。例えば次のような書き方だよね。

たけち

    <?xml version="1.0" encoding="Shift_JIS" ?>
    <poem pno="8">
      熟田津に船乗りせむと月待てば
      潮もかなひぬ今は漕ぎ出でな
    </poem>

たけち: というようなXMLデータがあるとするね。で、XMLスキーマの例として、文字数を500文字に制限する例を書いてみると、つぎのようになるね。

■内容に対して制約ファセットを適用した例
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="poem" type="SmallPoemType" />

<xsd:complexType name="SmallPoemType">
<xsd:simpleContent>
    <xsd:restriction base="PoemType">
    <xsd:maxLength value="500" />
    </xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="PoemType">
    <xsd:simpleContent>
    <xsd:extension base="xsd:string">
    <xsd:attribute name="pno" type="xsd:positiveInteger" use="required"/>
    </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

</xsd:schema>


■属性の出現制約を強化

さらら: これは単純型とまったく同じね。でも、2番目の属性の出現制約を強化という意味が全然わからないけれど...

たけち: 例えば前回、属性を追加したよね。これとは逆に結果的に、属性を削除したりするのが属性の出現制約を強化することなんだよ。

さらら: な〜んだ。属性を使っていたのをやめたいことを言うわけね。そうならそうと、簡単に言ってくれればいいのに。

たけち: あ、属性の出現制約を強化というのは、それだけじゃないんだ。基準型でoptional (DTDでいう#IMPLIED)、つまり出現しても良ければ、出現しなくても良い属性を、required (DTDでいう#REQUIRED)、つまり必ず出現しないといけない、というふうに制限するのも属性の出現制約を強化することなんだ。

さらら: へっ?....... (?_?)

たけち: じゃあ、まずは実例を見てみようね。最初は属性を使用禁止にする例だよ。基準型でoptional (DTDでいう#IMPLIED)、つまり出現しても良ければ、出現しなくても良い属性を、prohibited 、つまり使用禁止に制限してみるね。

さらら

■use="prohibited"で属性制約を強化する例
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="poem" type="PoemType" />

<xsd:complexType name="PoemType">
<xsd:simpleContent>
    <xsd:restriction base="SeasonPoemType">
    <xsd:attribute name="season" use="prohibited" />
    </xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="SeasonPoemType">
    <xsd:simpleContent>
    <xsd:extension base="xsd:string">
    <xsd:attribute name="pno" type="xsd:positiveInteger" use="required"/>
    <xsd:attribute name="season" type="xsd:string" use="optional" />
    </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

</xsd:schema>

たけち: ここではoptional指定となっているseason属性を、prohibited指定に変更して、season属性の使用を禁止しているんだよ。ちなみに使用禁止にしたい場合には、その属性がどういうデータ型であるかは関係ないから、type属性は省略できるね。それからpno属性は変更がないから、派生型の定義の方では、これを書くのを省略しているよ。

さらら: そっかぁ〜。use="prohibited"って変な書き方と思っていたけれど、こういう場合に使うのね。

さらら


■optionalをrequiredに制限する例

たけち: そうだね。次にoptionalをrequiredに制限する例を見てみようね。

■optionalをrequiredに制限する例
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="poem" type="PoemType" />

<xsd:complexType name="PoemType">
<xsd:simpleContent>
    <xsd:restriction base="SeasonPoemType">
    <xsd:attribute name="season" use="required" />
    </xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="SeasonPoemType">
    <xsd:simpleContent>
    <xsd:extension base="xsd:string">
    <xsd:attribute name="pno" type="xsd:positiveInteger" use="required"/>
    <xsd:attribute name="season" type="xsd:string" use="optional" />
    </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

</xsd:schema>

さらら: これってすごく不思議。。。。なんだかすっきりしないわ。

たけち: えっ、どこが?

さらら: だって、requiredとoptionalとprohibitedの関係って、つぎのような感じじゃないのかしら。

さらら

requiredとoptionalとprohibitedの関係 by さらら

さらら: requiredからoptionalへ制限されるというのならわかるわ。でもその逆にoptionalをrequiredに制限するって、おかしいわ。

たけち: う〜ん、そういうふうに考えちゃったのか〜。でも、よく考えるとそうじゃないことがわかるよ。

さらら: じゃあ、どういうふうに考えたらいいの?

たけち: それぞれのuse属性の指定で、属性の出現回数がどういう値をとるかを考えてみようね。

たけち

use属性の指定との属性出現回数


■出現制約の強化: とりうる値の範囲を狭める

たけち: つまり、

  • required : 1
  • optional : 0,1
  • prohibited : 0
 というのが、属性の出現回数がとりうる値なんだよね。ここまではわかるよね。

さらら: えぇ。

たけち: 出現制約の強化というのは、この出現回数がとりうる値の範囲を狭めることなんだよ。

たけち

use属性による出現制約の強化の関係

たけち: つまり、0と1の2個ある状態を1だけに制限するのが「optional→required」という制限だし、0と1の2個ある状態を0だけに制限するのが「optional→prohibited」という制限なんだ。これで「optional→required」というのが、制限の一種であることがわかってくれたかな?

さらら: えぇ。どう考えればいいのかは分かったわ。

さらら


■出現制約の強化: 属性のデフォルト値や固定値を新たに定める

たけち: この「出現制約の強化」という考え方は、後で「複合型内容をもった複合型」で、要素の出現を制限したいときにまた重要になってくるから、よく考えてみてね(^^)
 それから広い意味で、属性のデフォルト値や固定値を新たに定めるということも一種の出現制約の強化になるんだよ。これは、たとえばこんな感じで書けるんだよ。

■属性のデフォルト値を指定する例
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="poem" type="PoemType"/>

<xsd:complexType name="PoemType">
<xsd:simpleContent>
    <xsd:restriction base="PrePoemType">
    <xsd:attribute name="season" type="xsd:string" use="optional" default="春" />
    </xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="PrePoemType">
<xsd:simpleContent>
    <xsd:extension base="xsd:string">
    <xsd:attribute name="pno" type="xsd:positiveInteger" use="required" />
    <xsd:attribute name="season" type="xsd:string" use="optional" />
    </xsd:extension>
</xsd:simpleContent>
</xsd:complexType>

</xsd:schema>

さらら: こんなこともできるのね。

たけち: 次に属性に使用されている単純型の値の範囲を狭めるについて説明するね。例えば、次のような感じで使うんだよ。

■属性に使用されている単純型の値の範囲を狭める例
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="poem" type="PoemType"/>

<xsd:complexType name="PoemType">
<xsd:simpleContent>
    <xsd:restriction base="PrePoemType">
    <xsd:attribute name="pno" type="xsd:positiveInteger" use="required" />
    </xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="PrePoemType">
<xsd:simpleContent>
    <xsd:extension base="xsd:string">
    <xsd:attribute name="pno" type="xsd:integer" use="required" />
    <xsd:attribute name="season" type="xsd:string" use="optional" />
    </xsd:extension>
</xsd:simpleContent>
</xsd:complexType>

</xsd:schema>

たけち: ここではpno属性がinteger型だったけれど、それが制限された派生型であるpositiveInteger型に変更しているんだよ。

さらら: あ、なるほど。

たけち: これはビルトインデータ型の範囲での制限だけれど、もちろんユーザ派生型でもいいんだよ。つぎに例を載せておくね。

■ユーザ派生型を使って属性を制限する例
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="poem" type="PoemType"/>

<xsd:complexType name="PoemType">
<xsd:simpleContent>
    <xsd:restriction base="PrePoemType">
    <xsd:attribute name="pno" type="Int1To4516Type" use="required" />
    </xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="PrePoemType">
<xsd:simpleContent>
    <xsd:extension base="xsd:string">
    <xsd:attribute name="pno" type="xsd:positiveInteger" use="required" />
    <xsd:attribute name="season" type="xsd:string" use="optional" />
    </xsd:extension>
</xsd:simpleContent>
</xsd:complexType>

<xsd:simpleType name="Int1To4516Type">
    <xsd:restriction base="xsd:positiveInteger">
    <xsd:minInclusive value="1" />
    <xsd:maxInclusive value="4516" />
    </xsd:restriction>
</xsd:simpleType>

</xsd:schema>

さらら: ふ〜ん、こういうこともできるのね。

たけち: そして今まで一つ一つを説明するために、それぞれの例をあげてきたけれど、実際にはこれらを複数併せて一度にしてしまっていいんだよ。例えば以下の例みたいにできるね。

■単純型内容を持った複合型の制限の例(まとめ)
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="poem" type="PoemType"/>

<xsd:complexType name="PoemType">
<xsd:simpleContent>
    <xsd:restriction base="PrePoemType">
    <xsd:maxLength value="500" />
    <xsd:attribute name="pno" type="xsd:positiveInteger" use="required" />
    <xsd:attribute name="season" type="xsd:NMTOKEN" use="optional" default="春" />
    </xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="PrePoemType">
<xsd:simpleContent>
    <xsd:extension base="xsd:string">
    <xsd:attribute name="pno" type="xsd:integer" use="optional" />
    <xsd:attribute name="season" type="xsd:string" use="optional" />
    </xsd:extension>
</xsd:simpleContent>
</xsd:complexType>

</xsd:schema>

たけち: ただこういう書き方をする際に気をつけないといけないのは、内容を決める制約ファセットは、必ず属性宣言よりも前に書かないといけないということだよ。内容は属性よりも優先する、というふうにでも覚えておこうね。

さらら: こうしてみると「単純型内容をもった複合型」の制限って、単純型の制限よりもたくさんのことが指定できるのね。

たけち: そうだね。属性に関する機能が増えた形になるよね。この属性に対する制限(restriction)の機能は、「複合型内容をもった複合型」でも同じことになるんだよ。
 さて、これで「単純型内容をもった複合型」はおしまい。それで次回「複合型内容をもった複合型」を勉強しようかと思ったんだけれど...

さらら: えっ、なに?... (^ ^;

たけち

たけち: 属性のデフォルト値の話なんかが出てきたから、この際、要素のデフォルト値の話を次回はしてみることにするね。ちょっと横道にそれるけれどね。

さらら: 要素のデフォルト値? なに、それ?? そんなもの、あるの?

たけち: うん、そういうことから次回はしてみるね。今回はこれでおしまい。

さらら: は〜い。

次回は、要素のデフォルト値と固定値です 。。。。 (^ ^)v


XMLスキーマのコーナーは、TAKABEさま(XSLTの遊び部屋)の全面的なご協力をいただいて作成しています。