複合型内容をもった複合型の制限(1)

2002年10月28日(日)更新


■制限(restriction)のしかた

たけち: 前回は「複合型内容をもった複合型」の「拡張(extension)」を勉強したから、今回は制限(restriction)を勉強してみることにするね。まずは復習からだけれど、「制限(restriction)」という派生の方法は、単純型でも、「単純型内容をもった複合型」でも活躍したよね。それぞれどういう機能を持っていたか、覚えているかい?

さらら: えっと、えっと、以前の勉強したノートを見直さなくっちゃ、 え〜と、こうだったかしら.....(^ ^;

さらら

制限(restriction)

たけち: そうだね。単純型と「単純型内容をもった複合型」が同じなのは、どちらもその内容がテキストだということだよね。だから内容であるテキストに対しては、制約ファセットを適用できるという意味で同じになるんだ。それに対してこの両者の相違点は、「単純型内容をもった複合型」には属性が存在するので、その属性に対する制限の機能も加わっている、ということだね。

さらら: そうね。

たけち: ところで、「単純型内容をもった複合型」と「複合型内容をもった複合型」の似ている点はどこかな? というか、単純型と複合型で確実に違う点はどこになるかな?

さらら: え?

たけち: 単純型には絶対に属性は存在しないけれど、複合型は属性を持ちうるということだよね。

さらら: あ、な〜んだ、そういうことね...(^ ^;


■属性に対する制限

たけち: それでここで推理してもらいたいんだけれど「単純型内容をもった複合型」は絶対属性を持っているし、「複合型内容をもった複合型」も必ず属性を持つとは限らないけれども、属性を持っているものもあるよね。ということは、属性に対する制限の機能

  • 属性の出現制約を強化
  • 属性に使用されている単純型の値の範囲を狭める
 という機能を持つことについては、「単純型内容をもった複合型」も「複合型内容をもった複合型」も変わらないと思わないかい?

さらら: そう言われればそうよね。


■複合型内容をもった複合型の内容に対する制限

たけち: 実際そうなんだよ。「複合型内容をもった複合型」では属性に対する制限の機能は「単純型内容をもった複合型」と変わらないこの2つの機能を持っているんだ。じゃ、今度は逆に「単純型内容をもった複合型」と「複合型内容をもった複合型」の大きな違いって何だろうか?

さらら: それはもう文字通り、「単純型内容」つまりテキストを内容としているのか、それとも、内容が空なのか、それとも要素をさらに含んでいるかの違いよね。この程度ならわかるわ(^^)

たけち: そうだね。「複合型内容をもった複合型」では内容はテキストじゃないんだから、当然、制約ファセットなどは使えない。その代わり含まれている要素を何らかの形で制限するわけなんだよね。どういうことをするかわかるかい。

さらら: そう言われれば、確か「複合型内容をもった複合型」を説明する最初で、含まれている要素を削除していたわよね。ああいうことをするのよね。

たけち: そうだね。ただ「削除」というのは制限による一つの結果にすぎなくて、要素が含まれているからといって、必ずその要素を削除できるように制限できる、というものでもないんだよ。

さらら: (? ?; じゃあ、「複合型内容をもった複合型」の内容に対する制限ってどんなことをするの?

たけち: うん、実はこんなことをするんだ。

複合型内容をもった複合型の内容に対する制限

さらら: えっ〜。。。。なんかずる〜い! (^ ^; いろいろもったいぶった言い方をして、要するにさっきの属性の制限について述べたことについて、「属性」という言葉を「要素」という言葉に置き換えただけじゃないの! (^ ^;

たけち: あ、別にずるくなんかないよ(^^:) 以前「要素のデフォルト値」について説明したときに、「XML Schemaでは要素と属性が比較的平等に扱われている」という話をしたよね。結局、制限(restriction)についても、要素と属性を平等に扱っているだけなんだ。

さらら: う〜ん、そう言われればそうだけど......

たけち: というわけで、まとめるとつぎのようになるね。属性に対する機能は、「単純型内容をもった複合型」で説明した属性の制限の機能とまったく同じだから、ここではもうこれ以上説明することはやめておくね。

複合型内容を持つ複合型の制限(restriction)


■制限の機能についてまとめ

さらら: 制限って、いろいろな使われ方をするのね。

たけち: そうだね。今までデータ型の違いによる制限の機能を見てきたけれど、逆に制限のいろいろな機能の中で、データ型の違いでどの機能が使われるか、ということをまとめると、以下の図のようになるよ。

W3C XML Schemaにおける制限(restriction)の機能


■単純型の値の範囲を狭める例

さらら: ふーん、そうなのね。でもこの
・要素に使用されている単純型の値の範囲を狭める
 というのは、何となくわかる気がするけれど......
・要素の出現制約を強化
 という言葉が、どういう意味なのかピンと来ないんだけれど。。。。。。

たけち: そうだね。じゃあまずは「何となくわかる」方の、要素に使用されている単純型の値の範囲を狭めるということから説明することにするよ。本当はこれはまだ「ローカル要素宣言」というものがわかっていないとできないんだけれど、それに対する説明は省いて、ちょっとサワリだけ見てみることにするね。つぎのXMLデータを見て。ここでenvoyというのは「反歌」の意味だよ。

たけち

※反歌を伴う長歌の例
<?xml version="1.0" encoding="Shift_JIS" ?>
<poem>
<pno>4089</pno>
<envoy>4090</envoy>
<envoy>4091</envoy>
<envoy>4092</envoy>
<poet>大伴家持</poet>
<yomi>高御座 天の日継と すめろきの 神の命の 聞こしをす 国のまほらに 山をしも さはに多みと 百鳥の 来居て鳴く声 春されば 聞きのかなしも いづれをか 別きて偲はむ 卯の花の 咲く月立てば めづらしく 鳴く霍公鳥 あやめぐさ 玉貫くまでに 昼暮らし 夜わたし聞けど 聞くごとに 心つごきて うち嘆き あはれの鳥と 言はぬ時なし</yomi>
</poem>

さらら: これって、4089番の長歌に、4090, 4091, 4092の反歌があるってことよね。

たけち: あっ、そうそう。じゃ、まずDTDからみていこう。

※反歌を伴う長歌のDTD
<!ELEMENT poem (pno, envoy*, poet?, yomi)>
<!ELEMENT pno (#PCDATA)>
<!ELEMENT envoy (#PCDATA)>
<!ELEMENT poet (#PCDATA)>
<!ELEMENT yomi (#PCDATA)>

たけち: DTDでは表現できない部分として、pnoやenvoyはpositiveInteger型にしたいし、またenvoyの出現回数の最大値は10回までにしておこう。そう考えたとき、これのXML Schemaをさららは書けるかな (^ ^*

さらら: えっ ... (^ ^; でも、これくらいならなんとか・・・

※反歌を伴う長歌のXML Schema
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

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

<xsd:complexType name="PrePoemType">
<xsd:sequence>
<xsd:element ref="pno" />
<xsd:element ref="envoy" minOccurs="0" maxOccurs="10" />
<xsd:element ref="poet" minOccurs="0"/>
<xsd:element ref="yomi" />
</xsd:sequence>
</xsd:complexType>

<xsd:element name="pno" type="xsd:positiveInteger" />
<xsd:element name="envoy" type="xsd:positiveInteger" />
<xsd:element name="poet" type="xsd:string" />
<xsd:element name="yomi" type="xsd:string" />

</xsd:schema>

たけち: そうだね、こんな感じだね。ところでこのpnoとenvoyを「ローカル要素宣言」というものに換えると、こういう書き方ができるんだよ。

※反歌を伴う長歌のXML Schema(ローカル要素宣言を使用)
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

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

<xsd:complexType name="PrePoemType">
<xsd:sequence>
<xsd:element name="pno" type="xsd:positiveInteger" />
<xsd:element name="envoy" type="xsd:positiveInteger" minOccurs="0" maxOccurs="10" />

<xsd:element ref="poet" minOccurs="0"/>
<xsd:element ref="yomi" />
</xsd:sequence>
</xsd:complexType>

<xsd:element name="poet" type="xsd:string" />
<xsd:element name="yomi" type="xsd:string" />

</xsd:schema>

さらら: な、なに、これ!? PrePoemType内の要素 のpnoとenvoyが、参照ではなくて、属性の宣言みたいにname属性とtype属性を使って宣言しているわ!?

たけち: これがローカル要素宣言の仕方なんだ。まあこれがいったいどういう意味、意義を持っているかということは、もっと後で詳しく説明するから、ここでは詮索しないで、こういう要素の宣言の仕方がある、ということだけ知っておいてね。
さて、このpnoとenvoyはpositiveInteger型、つまり正の整数なんだけれど、これを1から4516までの整数に制限することにするね。これは次のように書くことができるんだよ。

たけち

※反歌を伴う長歌のXML 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:sequence>
<xsd:element name="pno" type="Int1To4516Type" />
<xsd:element name="envoy" type="Int1To4516Type" minOccurs="0" maxOccurs="10" />

<xsd:element ref="poet" minOccurs="0"/>
<xsd:element ref="yomi" />
</xsd:sequence>
</xsd:complexType>

<xsd:element name="poet" type="xsd:string" />
<xsd:element name="yomi" type="xsd:string" />

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


</xsd:schema>

さらら: これって以前、属性でしたことと同じだわ。

たけち: そうだね。ただここで注意してほしいことなんだけれど... 属性の場合は、値の範囲を制限したい属性だけをxsd:restrictionの内容にすれば良かったね。でも、「複合型内容をもった複合型」の内容モデルを制限したい場合には、「制限された結果どうなるか」ということを書かないといけないって言ったよね。だから、基準型と派生型のそれぞれの内容モデルを見比べてほしいけれど、次のように、変わらないところも含めてすべて制限された結果どうなるかということを書かないといけないということなんだ。

※基準型 [PrePoemType]
<xsd:sequence>
<xsd:element name="pno" type="xsd:positiveInteger" />
<xsd:element name="envoy" type="xsd:positiveInteger" minOccurs="0" maxOccurs="10" />
<xsd:element ref="poet" minOccurs="0"/>
<xsd:element ref="yomi" />
</xsd:sequence>

※派生型 [PoemType]
<xsd:sequence>
<xsd:element name="pno" type="Int1To4516Type" />
<xsd:element name="envoy" type="Int1To4516Type" minOccurs="0" maxOccurs="10" />
<xsd:element ref="poet" minOccurs="0"/>
<xsd:element ref="yomi" />
</xsd:sequence>

さらら: 変わらないところまで含めて、全部書かないといけないなんて何か面倒くさいわ。例えば10個の要素の参照なり宣言なりがされていて、その中の一つでも値の範囲が制限されるなら、残りの変わらない9個も含めて全部同じように書かないといけないわけなの!?

たけち: うん。そのとおり (^ ^;

さらら: それって、やっぱり面倒くさいぃ〜。(^ ^;

たけち: 実際こういう点もXML Schemaが批判される点の一つになっているんだ。だけど内容モデルを制限しようと思ったら、変わらないところも含めてすべて「制限された結果どうなるか」ということを書く方法以外に、良い方法が見つからなかったんだね。。きっと...(^ ^;)
さて次は、もう一つの機能「要素の出現制約を強化」について説明したいけれど、もうここまで来たところで疲れちゃったよね (^ ^;) この話は次回にしようね。

さらら: は〜い。(^ ^*

次は、複合型内容をもった複合型の制限(2)です 。。。。 (^ ^*


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