複合型内容を持つ複合型の定義の基本-1/2

2002年9月29日(日)更新


■データ型と派生

たけち: 今回から、ついにスキーマらしいスキーマである複合型内容を持つ複合型の話に入るね。

さらら: は〜い (^ ^)

たけち: まずは今までの復習なんだけれど、単純型単純型内容を持つ複合型では、どういうふうに派生の方法があったか覚えてる?

さらら: え〜と。。。単純型は、制限(restriction)とユニオン(union)とリスト(list)の3種類だったわよね。それと単純型内容を持つ複合型は制限(restriction)と拡張(extension)だったわ。

たけち: そうだね。それで複合型内容を持つ複合型の派生のさせ方なんだけれど、これも制限(restriction)と拡張(extension)の2種類があるんだよ。図にするとこういう感じだね。この図はすごく大事だから、まずはこれをしっかり覚えてね。

たけち

データ型と派生のさせ方


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

さらら: あら、よく見たら、単純型内容を持つ複合型複合型内容を持つ複合型も、どちらも制限と拡張しかないのね。結局「複合型」には「制限」と「拡張」の2種類があると覚えてしまえば、それでいいんじゃないの?

たけち: うん。この図だけ見ると、一見そういうふうに見えるよね。でも、実はそこに落とし穴があるんだよね。

さらら: え? 落とし穴?

たけち: 単純型にしても「単純型内容を持つ複合型」にしても、その「内容」については、制限(restriction)を使う際には、制約ファセットという形で、元になるデータ型をどう制限したいかということを定義していたよね。

さらら: えぇ。。

たけち: ところが、複合型内容を持つ複合型における制限(restriction)というのは、その「内容」については「どう制限したいか」ではなくて、制限された結果どうなるかを定義するんだよ。

さらら: はにぁ????

たけち: 確かにこんな話じゃわからないよね (^ ^; 実際に実例を見てみよう。

さらら

■複数の要素を子要素にもつXMLドキュメントの例
<poem pno="8">
    <poet>額田王</poet>
    <kana>
    熟田津尓 船乗世武登 月待者 潮毛可奈比沼 今者許藝乞菜
    </kana>
    <yomi>
    熟田津に船乗りせむと月待てば潮もかなひぬ今は漕ぎ出でな
    </yomi>
</poem>

たけち: このようなXMLドキュメントのスキーマを考えてみよう。 でも、その前にまずこれのDTDを書いてみようか、ねっ、さらら。ちなみに歌の作者(poet)は分からないこともあるから、出現してもしなくてもいいオプション扱いにしておこうね。

さらら: え〜っ (^ ^; う〜んと・・・・こっ、こうかしら。。 (^ ^;

さらら

■DTD by さらら
<!ELEMENT poem (poet?, kana, yomi)>
<!ATTLIST poem pno CDATA #REQUIRED>
<!ELEMENT poet (#PCDATA)>
<!ELEMENT kana (#PCDATA)>
<!ELEMENT yomi (#PCDATA)>

たけち: そう、こうだよね。さてこれからXML Schemaを書こうと思うけれど、XML Schemaには、
自分でXMLスキーマのデータ型を定義したければ、必ず他の何らかのデータ型を基準型として、そこから派生させるという形をとらない限り、自分でデータ型を定義することはできない
という基本原則があることを以前説明したよね。

さらら: そうだったわね。(^ ^;

たけち: じゃあ、上記のような構造を持ったデータ型を定義しようと思ったら、どういう基準型を使えば定義できるんだろうね?

さらら


■xsd:anyTypeを基準型にして制限(restriction)

さらら: え〜っ、皆目検討がつかないわ。こんな風に要素がたくさんあるデータ型って知らないもの。。。。

たけち: そうだよね。ちょっと普通思い浮かばないよね (^ ^; そこでXML Schemaを策定した人達が考えたことなんだけれど... xsd:anyTypeというビルトインデータ型を覚えているかい? 単純型だろうが複合型だろうが、どんなデータ型でもマッチするという、何でもありのデータ型だよ。

さらら: そういえば、そういうものがあったわね。

たけち: この例では、この何でもありのxsd:anyTypeを基準型にして、それを制限(restriction)するんだよ。

さらら: はぁ??? ... (?.?)

たけち: うん。。。まずは、例をみてみようね。

たけち

■poem例の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:complexContent>
    <xsd:restriction base="xsd:anyType">
    <xsd:sequence>
    <xsd:element ref="poet" minOccurs="0"/>
    <xsd:element ref="kana" />
    <xsd:element ref="yomi" />
    </xsd:sequence>
    <xsd:attribute name="pno" type="xsd:positiveInteger" use="required" />

   </xsd:restriction>
</xsd:complexContent>
</xsd:complexType>

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

</xsd:schema>

たけち: この中で、次の個所が、基準型であるxsd:anyTypeを制限した結果どうなるか、ということを示している部分だよ。

■xsd:anyTypeを制限した結果を示す部分
<xsd:sequence>
<xsd:element ref="poet" minOccurs="0"/>
<xsd:element ref="kana" />
<xsd:element ref="yomi" />
</xsd:sequence>
<xsd:attribute name="pno" type="xsd:positiveInteger" use="required" />

たけち: <xsd:attribute name="pno" type="xsd:positiveInteger"/>
 は前回勉強した属性の制限だから、これはひとまずおいておいておこうね。で、「内容」の方を見てみよう。この部分は、さららが書いてくれたDTDの
    (poet?, kana, yomi)
の部分に相当する部分なんだよ。

さらら: へ〜っ、そうなの。でも、sequenceとか知らない言葉が出てきているわ。これが内容を表すの?

たけち: あっ、そうだね。じゃ、まずは基本的な言葉について紹介しておくね。


■内容モデルとモデルグループ

たけち: この複合型の内容をもつ複合型の、内容がどんな要素やテキストで構成されているかを示す部分を内容モデルっていうんだ。

さらら: この例では、sequenceの個所のこと?

たけち: そうだね。で、その内容モデルを構成する部品として要素の出現の仕方を指定するものをモデルグループっていうんだ。つまり、モデルグループを使って内容モデルを規定するんだね。

さらら: どんな風に決めるの?

たけち: モデルグループには、sequence, choice, allという3種類が使えるんだ。この例では、sequenceを使っているね。

さらら: どういう意味なの?

たけち: sequenceは、一連の、一続きの、順番に、とかいった意味だよ。だから、さっき言ったように、DTDの
    (poet?, kana, yomi)
の部分に相当する部分、というわけなんだよ。ちょっと図にしておくね。

たけち

内容モデルとモデルグループ

たけち: このsequenceだとかminOccurs="0"だとかいった、その他詳しいことは、次回に説明するから今は無視してね。今回はあくまで複合型内容をもった複合型の定義の基本をわかってもらいたいだけだから。

さらら: う〜ん、それにしてもxsd:anyTypeを制限した結果としてこんな書き方するなんて..........

たけち: そう、restriction要素の内容は制限された結果どうなるかを表しているんだ。それで、ここでだいぶ先走ってしまうけれど、このPrePoemTypeからpoet要素を省くようにさらに制限してみようね。

さらら: えっ、.......... (・・)

たけち: DTDでいうと
    <!ELEMENT poem (poet?, kana, yomi)>
    <!ATTLIST poem pno CDATA #REQUIRED>
    <!ELEMENT poet (#PCDATA)>
    <!ELEMENT kana (#PCDATA)>
    <!ELEMENT yomi (#PCDATA)>
 の形から、
    <!ELEMENT poem (kana, yomi)>
    <!ATTLIST poem pno CDATA #REQUIRED>
    <!ELEMENT kana (#PCDATA)>
    <!ELEMENT yomi (#PCDATA)>
 の形へと制限することにするね。これのPoemTypeは以下のように書けるんだ。

たけち

■poem例の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:complexContent>
    <xsd:restriction base="PrePoemType">
    <xsd:sequence>
    <xsd:element ref="kana" />
    <xsd:element ref="yomi" />
    </xsd:sequence>

   </xsd:restriction>
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="PrePoemType">
<xsd:complexContent>
    <xsd:restriction base="xsd:anyType">
    <xsd:sequence>
    <xsd:element ref="poet" minOccurs="0"/>
    <xsd:element ref="kana" />
    <xsd:element ref="yomi" />
    </xsd:sequence>
    <xsd:attribute name="pno" type="xsd:positiveInteger" use="required" />
   </xsd:restriction>
</xsd:complexContent>
</xsd:complexType>

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

</xsd:schema>

たけち: これを見てわかるように属性の宣言については、派生型であるPoemTypeの定義の中には書いていないよね。前回も勉強したように、属性は制限する際に何も変更することがなければ、何も書かなくてもいいことになっているからなんだ。これに対して「内容」である「内容モデル」については制限された結果どうなるかということを必ず書かないといけない。このために
    <xsd:sequence>
    <xsd:element ref="kana" />
    <xsd:element ref="yomi" />
    </xsd:sequence>

という書き方をしているんだ。

さらら: .......... (・・)

たけち: あっ、図で確認しておこうね。

たけち

内容モデルの制限の例

たけち: こんなふうに制限する場合は、制限された結果どうなるかということを書かないといけないんだよ。

さらら: ..........


■空要素の書き方

たけち: そして以前説明したことだけれど、単純型や「単純型内容を持つ複合型」は、制限の「内容」として、「どう制限したいか」ということを書くことになっているから、そこに何も書かなければ、基準型と何も変わらないという意味になる。
ところが、先程も説明したように、「複合型内容を持つ複合型」定義の制限における「内容モデル」は「制限された結果どうなるか」を表している。だから、そこに何も書かなければ、何も存在しない。つまりDTDでいうEMPTYと同じ意味になるんだ。
この2つを比べてわかるように、「基準型と何も変わらない」のか「何も存在しない」のか、というのはまったく意味が違うよね。この点は同じ制限だと言っても、中に何も書かないことの意味が全然違ってくるから、極めて注意すべき点なんだよ。
 そしてこれを利用して空要素の書き方を示してみるね。

さらら: ..........

たけち: <kara />
というXMLデータ、DTDでいうと
    <!ELEMENT kara EMPTY>
 なんだけれど、これはXML Schemaでは次のように書けるんだ。

■空要素のXML Schema
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="kara" type="KaraType"/>

<xsd:complexType name="KaraType">
<xsd:complexContent>
    <xsd:restriction base="xsd:anyType">
</xsd:complexContent>
</xsd:complexType>

</xsd:schema>

さらら: たけち・・・・

たけち: えっ?

さらら: あのぉ・・・さっきから話を聞いていて、ものすごく違和感があるんだけれど・・・・(- -;

たけち: えっ、なっ、なに? (^ ^;

気まずい雰囲気の中、
複合型内容を持つ複合型の定義の基本-2/2
つづきます 。。。。 (;^ ^A

さらら


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