抽象的なデータ型、抽象要素

2002年11月10日(日)更新


■派生について(復習です)

たけち: さっそくだけど、以前、子要素の多い例として、こんな例を出したよね。

万葉歌のクラス図(sample)

さらら: えっ、えぇ。。。(^ ^;

たけち: ここでわかるようにPoemTypeを基準型としてMiscellaneousPoemTypeを派生させ、そのMiscellaneousPoemTypeというデータ型をもとに、miscellaneousPoemという要素を宣言したんだよね。今まで出してきた例と少し違うけれど、このXML Scehmaを元に次のようなXMLデータとXML Schemaとして書くことができるね。

※万葉歌(sample)
<?xml version="1.0" encoding="Shift_JIS" ?>
<miscellaneousPoem>
    <pno>1419</pno>
    <date>未詳</date>
    <poet>鏡王女</poet>
    <yomi>神なびの石瀬の社の呼子鳥いたくな鳴きそ我が恋まさる</yomi>
    <situation>橘諸兄宅宴席</situation>
    <season>春</season>
    <district>斑鳩</district>
    <emotion>恋愛</emotion>
</miscellaneousPoem>

※万葉歌(sample)のXML Schema
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="miscellaneousPoem" type="MiscellaneousPoemType" />
<xsd:element name="elegy" type="ElegyType" />
<xsd:element name="lovePoem" type="LovePoemType" />
<xsd:element name="metaphoricalPoem" type="MetaphoricalPoemType" />

<xsd:complexType name="PoemType">
<xsd:sequence>
    <xsd:element ref="pno" />
    <xsd:element ref="date" />
    <xsd:element ref="poet" />
    <xsd:element ref="yomi" />
    <xsd:element ref="situation" minOccurs="0" />
    <xsd:element ref="season" minOccurs="0" />
    <xsd:element ref="district" minOccurs="0" />
    <xsd:element ref="source" minOccurs="0" />
    <xsd:element ref="emotion" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="MiscellaneousPoemType">
<xsd:complexContent>
<xsd:extension base="PoemType" />
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="ElegyType">
<xsd:complexContent>
<xsd:extension base="PoemType">
<xsd:sequence>
    <xsd:element ref="on" />
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="LovePoemType">
<xsd:complexContent>
<xsd:extension base="PoemType">
<xsd:sequence>
    <xsd:element ref="sendTo" />
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="MetaphoricalPoemType">
<xsd:complexContent>
<xsd:extension base="LovePoemType" />
</xsd:complexContent>
</xsd:complexType>

<xsd:element name="pno" type="xsd:positiveInteger" />
<xsd:element name="date" type="xsd:string" />
<xsd:element name="poet" type="xsd:string" />
<xsd:element name="yomi" type="xsd:string" />
<xsd:element name="situation" type="xsd:string" />
<xsd:element name="season" type="SeasonType" />
<xsd:element name="district" type="xsd:string" />
<xsd:element name="source" type="xsd:string" />
<xsd:element name="emotion" type="xsd:string" />
<xsd:element name="sendTo" type="xsd:string" />
<xsd:element name="on" type="xsd:string" />

<xsd:simpleType name="SeasonType">
<xsd:restriction base="xsd:string">
    <xsd:enumeration value="春" />
    <xsd:enumeration value="夏" />
    <xsd:enumeration value="秋" />
    <xsd:enumeration value="冬" />
</xsd:restriction>
</xsd:simpleType>

</xsd:schema>

さらら: そういえばこんな感じの例を見てきたのよね。

たけち: うん。そこで考えて欲しいことがあるんだ。このXML Schemaでは次のように左のデータ型から右の要素を宣言しているよね。

MiscellaneousPoemType miscellaneousPoem
ElegyType elegy
LovePoemType lovePoem
MetaphoricalPoemType metaphoricalPoem

たけち: でも、

PoemType poem

という宣言はここではしてなかったよね。

たけち

さらら: あっ、そうね。ここでは、PoemTypeはMiscellaneousPoemType、ElegyType、LovePoemTypeの3つの派生型の基準型になっただけで、これ自身は要素の宣言には使われていないわね。

たけち: そう。ここで見てもらいたいのは、LovePoemTypeはMetaphoricalPoemTypeの基準型だけれど、lovePoemという要素の宣言に使われてるよね。それに対してPoemTypeという基準型は要素の宣言には使われない、ということなんだ。つまりここでわかるのは、

※要素の宣言には使われず、他の派生型の基準型としてだけ存在する意味があるデータ型が存在する

ということなんだよ。


■abstract属性

さらら: 何かもったいぶった言い方だけれど、そういうデータ型があってもおかしくないわよね。

たけち: そこで、ここで紹介したいのは、xsd:complexType要素に加えることができるabstractという属性だよ。「抽象的な」という意味かな。

さらら: abstract.....

たけち: xsd:complexType要素にとってはoptionalな属性で、省略された場合はabstract="false"という意味になるんだ。つまり僕達はxsd:complexType要素を使っていて、そこで知らず知らずに abstract="false" という属性の設定をしていたのだけれど、これを次のように明示的にabsract="true"という書き方にするね。

たけち

※xsd:complexTypeのabstract属性
<xsd:complexType name="PoemType" abstract="true">
<xsd:sequence>
    <xsd:element ref="pno" />
    <xsd:element ref="date" />
    <xsd:element ref="poet" />
    <xsd:element ref="yomi" />
    <xsd:element ref="situation" minOccurs="0" />
    <xsd:element ref="season" minOccurs="0" />
    <xsd:element ref="district" minOccurs="0" />
    <xsd:element ref="source" minOccurs="0" />
    <xsd:element ref="emotion" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>

さらら: こういう属性を加えると何ができるの? (^ ^)

たけち: いや、何ができるんじゃなくて、できなくなる方なんだけど、こうするとPoemTypeというデータ型で要素を宣言しても、その要素は実際のXMLデータ(インスタンス)の中で使えなくなるんだ。

さらら: はぁ?

たけち: つまり、abstract属性を指定していない

たけち

※xsd:complexTypeのabstract属性指定無し
<xsd:complexType name="PoemType">
<xsd:sequence>
    <xsd:element ref="pno" />
    <xsd:element ref="date" />
    <xsd:element ref="poet" />
    <xsd:element ref="yomi" />
    <xsd:element ref="situation" minOccurs="0" />
    <xsd:element ref="season" minOccurs="0" />
    <xsd:element ref="district" minOccurs="0" />
    <xsd:element ref="source" minOccurs="0" />
    <xsd:element ref="emotion" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>

 のままだと、

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

といったように要素を宣言して、そのXML Schemaに合致した次のようなXMLデータを作ることができるよね。

※万葉歌(sample)
<?xml version="1.0" encoding="Shift_JIS" ?>
<poem>
    <pno>1419</pno>
    <date>未詳</date>
    <poet>鏡王女</poet>
    <yomi>神なびの石瀬の社の呼子鳥いたくな鳴きそ我が恋まさる</yomi>
    <situation>橘諸兄宅宴席</situation>
    <season>春</season>
    <district>斑鳩</district>
    <emotion>恋愛</emotion>
</poem>


■抽象要素
-- 実際のXMLデータでは使えない要素 --

さらら: えぇ・・・・・

たけち: しかし、abstract="true"というふうに、この属性でtrueを指定すると、それができなくなるんだよ。

さらら: へぇ〜。でも、そんなことをして、というか、できなくなって何か良いことあるの?

たけち: このPoemTypeを間違って要素に使ったりするようなミスをすることがなくなり、またこのデータ型が、派生させることによって使えるデータ型だということがはっきりわかるよね。

さらら: ふ〜ん、そんなものなの。

たけち: 今はぴんと来ないかもしれないけれど、こういう書き方ができるというのは、オブジェクト指向でモデリングする際に、それなりに役に立つ機能だから覚えておこうね。

さらら: う〜ん、やっぱり何かぴんと来ないわね。。

さらら

たけち: ちなみにこのabstract属性は、xsd:complexType要素には存在するけれど、xsd:simpleType要素には存在しないんだ。だから複合型を抽象的なデータ型にはできるけれど、単純型を抽象的なデータ型にはできないから、その点は気をつけてね。

さらら: 複合型ではできて、単純型にはできないなんて・・・・・ますます存在意義がわからないわ。

たけち: まあ、これは実際にオブジェクト指向的にスキーマを作っていくようになると、それなりに意義がわかってくるようになるよ(^^;)
あとね、抽象的にできるのはデータ型だけでなく、要素宣言も抽象的にできるんだ。

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

という書き方で、抽象要素poemの宣言になるんだよ。

さらら

さらら: 抽象要素って何??

たけち: それ自体では、実際のXMLデータ(インスタンス)側の方では使えない要素のことだよ。

さらら: はぁっ!? (?_?)

たけち: つまり
<xsd:element name="poem" type="PoemType" abstract="true" />

という抽象要素poemを宣言すると、実際のXMLデータ側の方では、

<?xml version="1.0" encoding="Shift_JIS" ?>
<poem>
    <pno>1419</pno>
    <date>未詳</date>
    <poet>鏡王女</poet>
    <yomi>神なびの石瀬の社の呼子鳥いたくな鳴きそ我が恋まさる</yomi>
    <situation>橘諸兄宅宴席</situation>
    <season>春</season>
    <district>斑鳩</district>
    <emotion>恋愛</emotion>
</poem>

というふうに使ってはいけないということなんだ。

さらら: 使ってはいけない要素を宣言するの!?

たけち: そう。

さらら: 使ってはいけない要素を宣言して、いったい何になるの!? わっけわかんな〜〜〜い!! (ーー;

たけち: ごめん、ごめん。確かにこの説明だけだとわけがわからないよね(^^;) この抽象要素は次回に説明する「代替要素」のようなテクニックと組み合わせて、使い道があるようなテクニックなんだ。ひとまずこういうものがあるということだけ覚えておこうね(^^;) 次回に期待してね。

さらら: は〜い。。。(も少し聞けば分かるかしら... (^ ^; )

次は、代替要素です 。。。。 (^ ^*

さらら

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