代替要素

2002年11月17日(日)更新


■歌集(poems)

さらら: 前回の「抽象的なデータ型」って、何かぴんと来なかったし、「抽象要素」に至っては、何故こんなものがあるのかさっぱりわからなかったわ。

たけち: あっ、ごめんね (^ ^; 確かにあれだけだと、ぴんと来なかったり、何に使うものなのかわからなかったりするよね。前回説明したことは、今回説明する代替要素とセットにすると、結構意味があることがわかると思うよ。そして前回の「抽象的なデータ型、抽象要素」にしても、今回説明する「代替要素」にしても、以前の説明でも使ったことがあって、説明を省いていただけなんだけれど、そのことについて今日はしっかり説明することにするね。まずは前回、こんなUMLのクラス図のスキーマを作ったよね。

万葉歌のクラス図(sample)

さらら: そうね。図にするとこういう感じよね。

たけち: さて、この図に、複数の歌を羅列している歌集(poems)を加えてみることにするね。

歌集(poems)のクラス図(sample)

さらら: えぇ・・・

たけち: この図に対応するようなXMLデータの例は次のようになるよね。

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

<elegy>
    <pno>0146</pno>
    <date>大宝元年</date>
    <poet>柿本人麻呂</poet>
    <yomi>後見むと君が結べる磐代の小松がうれをまたも見むかも</yomi>
    <district>紀伊国</district>
    <source>柿本朝臣人麿歌集</source>
    <on>有間皇子</on>
    </elegy>
<lovePoem>

    <pno>0085</pno>
    <date>難波の高津の宮に天の下知ろしめしし天皇の代</date>
    <poet>磐姫皇后</poet>
    <yomi>君が行き日長くなりぬ山尋ね迎へか行かむ待ちにか待たむ</yomi>
    <source>山上憶良臣類聚歌林</source>
    <emotion>恋愛</emotion>
    <sendTo>仁徳天皇</sendTo>
</lovePoem>

<metaphoricalPoem>
    <pno>0408</pno>
    <date>未詳</date>
    <poet>大伴家持</poet>
    <yomi>なでしこがその花にもが朝な朝な手に取り持ちて恋ひぬ日なけむ</yomi>
    <emotion>恋愛</emotion>
    <sendTo>坂上大嬢</sendTo>
</metaphoricalPoem>
</poems>

たけち: このようにmiscellaneousPoemn、elegy、lovePoem、metaphoricalPoemはpoemsの子要素になるんだ。これを今までの知識でXML Schemaで書くとどうなるかな?

さらら: えっ(^ ^;

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

<xsd:element name="poems" type="PoemsType" />

<xsd:complexType name="PoemsType">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="miscellaneousPoem" />
<xsd:element ref="elegy" />
<xsd:element ref="lovePoem" />
<xsd:element ref="metaphoricalPoem" />
</xsd:choice>
</xsd:complexType>


<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" 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>

<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:NMTOKEN" />
<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>

たけち: こんな感じだよね。さて、ここで見てもらいたいのが、

<xsd:complexType name="PoemsType">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="miscellaneousPoem" />
<xsd:element ref="elegy" />
<xsd:element ref="lovePoem" />
<xsd:element ref="metaphoricalPoem" />
</xsd:choice>
</xsd:complexType>

たけち: の部分なんだ。PoemsTypeを構成する子要素4つがここに並べられているんだけれど、これが結構面倒くさいと思わないかい。

さらら: そう言われればそういう感じもするけれど、でも、仕方がないわよね。

たけち: ところがこの場合、もうちょっとすっきり書く方法があるんだ。例えば、さららが宴会の幹事をすることになったとするよね。ここでは仮に「万葉歌会」という会で宴会することにしとこうかな。宴会場となるところに「宴会をしたい」という申し込みをする場合、この「万葉歌会」に所属している参加者全員の名前、たとえば「さららと、たけちと、大伴家持と...が参加します」というふうに名前全部を挙げて「こういう人達で宴会するからね」と頼んだりするかい?

さらら: そんなことは普通しないわ。普通、その宴会の主体となる組織の名前、会の名前で宴会を申し込むわよね。この場合「『万葉歌会』という会で宴会をしたいので、お願いしますね」というふうに頼むわね。そして出席者は当然皆「万葉歌会-会員」ということになるわね。

たけち: そうだね。そういう場合、普通参加者全員を含む「組織、会」の名前や「代表者」の名前で申し込むようなことをするし、出席者は皆「万葉歌会-会員」ということになるよね。さて、それと同様に、先ほどの例題も、「組織、会」の名前で登録することができるんだよ。要するに「さららと、たけちと、大伴家持と...が参加します」という方法ではなくて「出席者は万葉歌会-会員です」といった申し込み方ができるんだ。


■代替グループ

さらら: え、具体的にどうするの?

たけち: まずはmiscellaneousPoem、elegy、lovePoem、metaphoricalPoemを含む一団を総称する名前としてpoemで登録してみる書き方をしてみようね。

<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="poems" type="PoemsType" />

<xsd:complexType name="PoemsType">
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="poem" />
</xsd:sequence>
</xsd:complexType>

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

<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:NMTOKEN" />
<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>

たけち:  ここで注目してもらいたいのが、まず

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

たけち: という部分なんだ。最初にpoemという要素をPoemType型として要素宣言をしている。そしてmiscellaneousPoem、elegy、lovePoem、metaphoricalPoemを要素宣言をしているところに、substitutionGroupつまり訳すると代替グループという属性があるよね。そこで総称名となるヘッド要素としてpoemを指定しているんだ。

さらら: こんなことをして、何になるの?

たけち: これがさっきの例で言えば「たけちとさららと大伴家持は万葉歌会の会員ですよ」というふうに宣言しているような部分なんだ。そしてさらに次の部分も見てね。

たけち

<xsd:complexType name="PoemsType">
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="poem" />
</xsd:sequence>
</xsd:complexType>

たけち: というところだよ。最初の例だと、内容モデルとして、

<xsd:complexType name="PoemsType">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="miscellaneousPoem" />
<xsd:element ref="elegy" />
<xsd:element ref="lovePoem" />
<xsd:element ref="metaphoricalPoem" />
</xsd:choice>
</xsd:complexType>

たけち:  として書かなければならなかった。つまり子要素になりうるものを全部書かないといけなかったわけだね。ところがさっきの書き方だと、内容モデルは、

<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="poem" />
</xsd:sequence>

たけち: となっているね。つまりpoemという子要素が連続していくつも出現しても良いという書き方なんだけれど、そのpoem要素が出現するべき場所に代わりに代替グループとして設定されたmiscellaneousPoem、elegy、lovePoem、metaphoricalPoemといった要素が出現しても良い、ということなんだよ。

代替要素の指定と出現

たけち: つまり、ヘッド要素という「総称名」が出現している部分に、ヘッド要素の代替グループになることを宣言した要素が出現してもよい、ということなんだ。こういう要素のことを代替要素と呼ぶんだよ。

さらら: あ、なるほど。

たけち: ここで注意して欲しいのは、代替グループのヘッド要素になれるのは、それらのデータ型と同じデータ型か、もしくはその基準型やさらにその先祖となっている基準型などで宣言された要素でないといけないということなんだ。つまり、同じデータ型で宣言されているか、もしくはそれらの派生関係の上の方にあるデータ型で宣言されていないとヘッド要素になれないんだね。

さらら: ふーん。

たけち: そして、さっきの書き方には実は致命的な問題点があるんだよ。

さらら: えっ??

たけち

たけち: 図に示したXMLデータ例をよく見て。

<poems>
<miscellaneousPoem>.....</miscellaneousPoem>
<poem>.....</poem>
<lovePoem>.....</lovePoem>
<metaphoricalPoem>.....</metaphoricalPoem>
<miscellaneousPoem>.....</miscellaneousPoem>
<elegy>.....</elegy>
</poems>

たけち: 出現して欲しいのは、miscellaneousPoem、elegy、lovePoem、metaphoricalPoemの4種類なんだけれど、それを総称した要素であるpoemも出現しているんだ。  先ほどの「万葉歌会」の例で考えると、「万葉歌会-会員」の会員として、僕やさららや大伴家持が宴会に出席するのは良いけれど、参加者の中に「万葉歌会-会員さん」という名前の人物まで参加してくるようなものだね(^^;)

さらら: そうね。それって変だわ。。。。。じゃあこの方法は使えないのかしら。

さらら


■抽象的なデータ型、抽象要素を利用する

たけち: そんなことはないよ。そこで、必要になってくるのが前回学んだ「抽象的なデータ型、抽象要素」のテクニックだよ。

さらら: あっ!

たけち: 「万葉歌会」というのは、歌を読む人たちの集まりの総称であって、「万葉歌会-会員さん」という名前の人物のような具体的な実体を伴うものじゃないんだ。つまり「万葉歌会-会員」というのは「抽象的な概念」なんだよね。ということは、XML Schema的に言うとabstract="true"という属性を伴うものなんだね。それと同様に、miscellaneousPoem、elegy、lovePoem、metaphoricalPoemの4種類を総称するpoemという要素、そしてそのデータ型であるPoemTypeも「抽象的な概念」で、XML Schema的に言うとabstract="true"という属性を伴うものなんだね。実際にこの属性を入れて書き直してみようね。

さらら

※歌集(poems)のXML Schema: 代替グループと抽象要素を使用
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="poems" type="PoemsType" />

<xsd:complexType name="PoemsType">
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="poem" />
</xsd:sequence>
</xsd:complexType>

<xsd:element name="poem" type="PoemType" abstract="true" />
<xsd:element name="miscellaneousPoem" type="MiscellaneousPoemType" substitutionGroup="poem" />
<xsd:element name="elegy" type="ElegyType" substitutionGroup="poem" />
<xsd:element name="lovePoem" type="LovePoemType" substitutionGroup="poem" />
<xsd:element name="metaphoricalPoem" type="MetaphoricalPoemType" substitutionGroup="poem" />

<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>

<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:NMTOKEN" />
<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>


■代替グループ

たけち:  この中で、
    <xsd:element name="poem" type="PoemType" abstract="true" />
 と、
    <xsd:complexType name="PoemType" abstract="true">
 に注目してね。

たけち:   後者はPoemTypeというデータ型が抽象的(abstract)なデータ型であることを示しているし、前者はそのPoemTypeで宣言されたpoemという要素が抽象的(abstract)な要素であることを示している。そしてこのpoemは、
    <xsd:sequence minOccurs="0" maxOccurs="unbounded">
    <xsd:element ref="poem" />
    </xsd:sequence>

 という内容モデルの中に使われるけれども、実際にXMLデータの中では、このpoem要素は使うことができず、この抽象要素を具体化した代替要素であるmiscellaneousPoem、elegy、lovePoem、metaphoricalPoemの4種類の要素のみが使える、ということになるんだね。

さらら: あ、そういうわけなのね!!

たけち: この場合のUMLのクラス図も描いておくね。最初の方に出したUMLのクラス図と比べてみてね。随分すっきりした感じになったよね。

たけち

代替要素の指定と出現

さらら: なるほどねぇ〜。

たけち: それから、以前オブジェクト指向的に要素(モデルグループ)の追加をする際は、sequenceで囲まれた形になるので、choiceの内容をそのまま増やすことができない、という話をしたよね。だけど、代替要素を使うと、こういうオブジェクト指向的な関係なら、抽象的なデータ型から派生したデータ型の要素として、代替要素を後から増やすことができるよね。オブジェクト指向的にはこういう考え方で進める方が問題なく解決できるんだね。

さらら: こういうふうにすっきりと考えることができるわけなのね。納得したわ。

次は派生の禁止です 。。。。 (^ ^*

さらら


■補足: Javaの場合

たけち: このあたりはいかにもオブジェクト指向らしいテクニックになるから覚えておこうね。

さらら: またオブジェクト指向ね、ということは、Java...

たけち: あ、そうだ、Javaでどうなるかも見ておこうね。

さらら: .......(やぶ蛇だったわ(^^;) )

たけち: Javaのようなオブジェクト指向プログラミング言語だと、スーパークラスのデータ型として宣言した変数が、サブクラスのインスタンスの値を取ることは一般的なんだよ。実際にJavaのプログラムを見てみようね。

さらら

class J31 {
    public static void main (String args[]) {
        PoemsType poems = new PoemsType();
        poems.display();
    }
}

class PoemsType{
    PoemType[] poem = new PoemType[4];

    public PoemsType() {
        poem[0] = new MiscellaneousPoemType(1419,"未詳","鏡王女",
                "神なびの石瀬の社の呼子鳥いたくな鳴きそ我が恋まさる",
                "橘諸兄宅宴席","春","斑鳩","","");
        poem[1] = new ElegyType(146,"大宝元年","柿本人麻呂",
                "後見むと君が結べる磐代の小松がうれをまたも見むかも",
                "","","紀伊国","","","有間皇子");
        poem[2] = new LovePoemType(85,
                "難波の高津の宮に天の下知ろしめしし天皇の代",
                "磐姫皇后",
                "君が行き日長くなりぬ山尋ね迎へか行かむ待ちにか待たむ",
                "","","","山上憶良臣類聚歌林","恋愛","仁徳天皇");
        poem[3] = new MetaphoricalPoemType(408,"未詳","大伴家持",
                "なでしこがその花にもが朝な朝な手に取り持ちて恋ひぬ日なけむ",
                "","","","","恋愛","坂上大嬢");
    }

    public void display() {
        for (int i = 0; i <= 3; i++) {
                poem[i].display();
        }
    }
}

abstract class PoemType{
    int pno;
    String date;
    String poet;
    String yomi;
    String situation;
    String season;
    String district;
    String source;
    String emotion;

    public PoemType(int pno, String date, String poet, String yomi,
                String situation, String season, String district,
                String source, String emotion){
        this.pno=pno;
        this.date=date;
        this.poet=poet;
        this.yomi=yomi;
        this.situation=situation;
        this.season=season;
        this.district=district;
        this.source=source;
        this.emotion=emotion;
    }

    public void display() {
        System.out.println("------");
        System.out.println(pno);
        System.out.println(date);
        System.out.println(poet);
        System.out.println(yomi);
        System.out.println(situation);
        System.out.println(district);
        System.out.println(source);
        System.out.println(emotion);
    }
}

class MiscellaneousPoemType extends PoemType{
    public MiscellaneousPoemType(int pno, String date, String poet, String yomi,
        String situation, String season, String district, String source,
        String emotion){
            super(pno, date, poet, yomi, situation, season, district, source, emotion);
    }
}

class ElegyType extends PoemType{
    String on;

    public ElegyType(int pno, String date, String poet, String yomi,
        String situation, String season, String district, String source,
        String emotion, String on){
            super(pno, date, poet, yomi, situation, season, district, source, emotion);
            this.on = on;
    }

    public void display() {
        super.display();
        System.out.println(on);
    }
}

class LovePoemType extends PoemType{
    String sendTo;

    public LovePoemType(int pno, String date, String poet, String yomi,
        String situation, String season, String district, String source,
        String emotion, String sendTo){
        super(pno, date, poet, yomi, situation, season, district, source, emotion);
        this.sendTo = sendTo;
    }

    public void display() {
        super.display();
        System.out.println(sendTo);
    }
}

class MetaphoricalPoemType extends LovePoemType{
    public MetaphoricalPoemType(int pno, String date, String poet, String yomi,
        String situation, String season, String district, String source,
        String emotion, String sendTo){
            super(pno, date, poet, yomi, situation, season, district, source,
            emotion, sendTo);
    }
}

たけち: という感じかな。

さらら: え〜、わけがわからない! (^ ^;

さらら

たけち: 理解する必要はないから、似ているところだけを見ていけばいいよ。例えば、

    class MiscellaneousPoemType extends PoemType{

 という行は

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

 に相当するというのは、何となくわかるよね。どちらも
PoemTypeを拡張(extends extension)してMiscellaneousPoemTypeを定義します
 という意味になることは検討がつくよね。

さらら: そう言われればそうねぇ〜。

たけち: abstract class PoemType{

 なんていう行も

    <xsd:complexType name="PoemType" abstract="true">

 という書き方に似ているよね。どちらも
抽象的(abstract)なデータ型であるPoemTypeを定義します  という書き方なんだよ。

さらら: そうね、そう言われれば似ているわね。

たけち: そして

class PoemsType{
PoemType[] poem = new PoemType[4];

 という書き方は、XML Schemaの

    <xsd:complexType name="PoemsType">
    <xsd:sequence minOccurs="0" maxOccurs="unbounded">
    <xsd:element ref="poem" />
    </xsd:sequence>
    </xsd:complexType>

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

 にだいたい相当しているんだ。どちらもPoemsTypeの構成要素が、PoemType型のpoemの羅列(配列)であることを宣言している。そしてそのpoemは実際には、直接PoemType型の値をとるのではなくて、その派生型(サブクラス)である値を以下のようにとるんだね。

    poem[0] = new MiscellaneousPoemType(1419,"未詳","鏡王女",
        "神なびの石瀬の社の呼子鳥いたくな鳴きそ我が恋まさる",
        "橘諸兄宅宴席","春","斑鳩","","");
    poem[1] = new ElegyType(146,"大宝元年","柿本人麻呂",
        "後見むと君が結べる磐代の小松がうれをまたも見むかも",
        "","","紀伊国","","","有間皇子");
    poem[2] = new LovePoemType(85,"難波の高津の宮に天の下知ろしめしし天皇の代",
        "磐姫皇后",
        "君が行き日長くなりぬ山尋ね迎へか行かむ待ちにか待たむ",
        "","","","山上憶良臣類聚歌林","恋愛","仁徳天皇");
    poem[3] = new MetaphoricalPoemType(408,"未詳","大伴家持",
        "なでしこがその花にもが朝な朝な手に取り持ちて恋ひぬ日なけむ",
        "","","","","恋愛","坂上大嬢");

たけち:  という部分が実際のXMLデータである

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

<elegy>
<pno>0146</pno>
<date>大宝元年</date>
<poet>柿本人麻呂</poet>
<yomi>後見むと君が結べる磐代の小松がうれをまたも見むかも</yomi>
<district>紀伊国</district>
<source>柿本朝臣人麿歌集</source>
<on>有間皇子</on>
</elegy>

<lovePoem>
<pno>0085</pno>
<date>難波の高津の宮に天の下知ろしめしし天皇の代</date>
<poet>磐姫皇后</poet>
<yomi>君が行き日長くなりぬ山尋ね迎へか行かむ待ちにか待たむ</yomi>
<source>山上憶良臣類聚歌林</source>
<emotion>恋愛</emotion>
<sendTo>仁徳天皇</sendTo>
</lovePoem>

<metaphoricalPoem>
<pno>0408</pno>
<date>未詳</date>
<poet>大伴家持</poet>
<yomi>なでしこがその花にもが朝な朝な手に取り持ちて恋ひぬ日なけむ</yomi>
<emotion>恋愛</emotion>
<sendTo>坂上大嬢</sendTo>
</metaphoricalPoem>

たけち:  に相当することになるんだ。

さらら: ふーん....。そうしたら代替要素にあたる部分はどこになるの?

たけち: あ、それは存在しないよね。というか、それと同等の機能が最初から用意されているのが、Javaのようなオブジェクト指向プログラミング言語の特徴なんだよ。XML Schemaのようなオブジェクト指向スキーマ言語と、Javaのようなオブジェクト指向プログラミング言語の違いを考えると、後者はスーパークラス側で宣言された変数という条件だけで、こういうことができるのに対し、XML Schemaではその条件に加えて、今まで説明してきたように代替要素の指定をしないと、こういうテクニックが使えないという点が大きな違いになるね。オブジェクト指向プログラミング言語の変数と比べると、XML Schemaでは実際にどういう要素がどう出現するかということの方が一番の目的であるだけに、単に派生関係があるだけでは代替することは許可されないようになっているんだ。こういう違いがちょっと面白いよね。

さらら: そ、そうなの(よくわかんない(^^;) )

たけち: あ、まあ、Javaの話はあくまで参考程度の話で、これは特に理解しなくてもかまわないから(^^;)

さらら: .......(また顔に出たかしら(^^;) )


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