グローバル属性とグローバル属性宣言 その1

2003年3月2日(日)更新


■万葉歌人データの例を考えてみます

たけち: 今回からちょっと違った話をするね。突然なんだけれど、次のXMLデータとDTDを見て。

XMLデータ例: 万葉歌人
<?xml version="1.0" encoding="Shift_JIS" ?>
<pi:person id="3" xmlns:pi="http://www.yuragi.jp/ns/personalInformation">
<pi:name>大伴家持</pi:name>
<pi:sex class="male" />
<pi:degree class="従三位" />
</pi:person>

DTD: 万葉歌人
<!ELEMENT pi:person (pi:name, pi:sex, pi:degree)>
<!ATTLIST pi:person id NMTOKEN #REQUIRED xmlns:pi CDATA #FIXED "http://www.yuragi.jp/ns/personalInformation" >
<!ELEMENT pi:name (#PCDATA)>
<!ELEMENT pi:sex EMPTY>
<!ATTLIST pi:sex class (male | female) #REQUIRED >
<!ELEMENT pi:degree EMPTY>
<!ATTLIST pi:degree class (正一位 | 従一位 | 正ニ位 | 従二位 | 正三位 | 従三位 | 正四位上 | 正四位下 | 従四位上 | 従四位下 | 正五位上 | 正五位下 | 従五位上 | 従五位下 | 正六位上 | 正六位下 | 従六位上 | 従六位下 | 正七位上 | 正七位下 | 従七位上 | 従七位下 | 正八位上 | 正八位下 | 従八位上 | 従八位下 | 大初位上 | 大初位下 | 少初位上 | 少初位下) #REQUIRED>

たけち: 意味はだいたいわかるよね。ある人物について、その名前と性別、そして位(くらい)についてのデータを示したものなんだよ。

さらら: まあ、だいたいわかる気がするわ。

たけち: じゃあ、これのXML Schemaはもう書けるよね。

さらら: えっ?! え〜と (^ ^;)

さらら

W3C XML Schema: 万葉歌人
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema targetNamespace="http://www.yuragi.jp/ns/personalInformation"<br />
         xmlns:xsd="http://www.w3.org/2001/XMLSchema"br />          xmlns:pi="http://www.yuragi.jp/ns/personalInformation">

<xsd:element name="person" type="pi:PersonType" />

<xsd:complexType name="PersonType">
<xsd:sequence>
<xsd:element ref="pi:name" />
<xsd:element ref="pi:sex" />
<xsd:element ref="pi:degree" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:positiveInteger" />
</xsd:complexType>

<xsd:element name="name" type="xsd:string" />
<xsd:element name="sex" type="pi:SexType" />
<xsd:element name="degree" type="pi:DegreeType" />

<xsd:complexType name="SexType">
<xsd:attribute name="class" type="pi:SexClassType" />
</xsd:complexType>

<xsd:complexType name="DegreeType">
<xsd:attribute name="class" type="pi:DegreeClassType" />
</xsd:complexType>
<xsd:simpleType name="SexClassType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="male" />
<xsd:enumeration value="female" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DegreeClassType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="正一位" />
<xsd:enumeration value="従一位" />
<xsd:enumeration value="正ニ位" />
<xsd:enumeration value="従ニ位" />
<xsd:enumeration value="正三位" />
<xsd:enumeration value="従三位" />
<xsd:enumeration value="正四位上" />
<xsd:enumeration value="正四位下" />
<xsd:enumeration value="従四位上" />
<xsd:enumeration value="従四位下" />
<xsd:enumeration value="正五位上" />
<xsd:enumeration value="正五位下" />
<xsd:enumeration value="従五位上" />
<xsd:enumeration value="従五位下" />
<xsd:enumeration value="正六位上" />
<xsd:enumeration value="正六位下" />
<xsd:enumeration value="従六位上" />
<xsd:enumeration value="従六位下" />
<xsd:enumeration value="正七位上" />
<xsd:enumeration value="正七位下" />
<xsd:enumeration value="従七位上" />
<xsd:enumeration value="従七位下" />
<xsd:enumeration value="正八位上" />
<xsd:enumeration value="正八位下" />
<xsd:enumeration value="従八位上" />
<xsd:enumeration value="従八位下" />
<xsd:enumeration value="大初位上" />
<xsd:enumeration value="大初位下" />
<xsd:enumeration value="少初位上" />
<xsd:enumeration value="少初位下" />
</xsd:restriction>
</xsd:simpleType>


</xsd:schema>


■同じ名前で、異なるデータ型の属性

たけち: さて、今回の例題で、classという名前の属性について考えてみよう。

<pi:sex class="male" />
<pi:degree class="従三位" />
 というふうになっているけれど、pi:sex要素のclass属性と、pi:degree要素のclass属性は異なるデータ型になっているよね。

さらら: そうよね。pi:sex要素のclass属性はmaleかfemaleかの列挙型だし、pi:degree要素のclass属性は正一位から少初位下までの列挙型だわ。これは異なるデータ型よね。

たけち: 同じclassという名前の属性なんだけど、異なるデータ型をとっているね。これって不思議な感じがしない?

さらら: う〜ん。別に不思議でもなんでもないんじゃない。

たけち: 要素の場合、同じ名前の要素で違ったデータ型をとったことはなかったよね。

さらら: あ、それはなかったわ。ある名前の一つの要素は、必ず何らかの一つのデータ型と結びついていたわね。

たけち

たけち: でも、要素の場合、同じ名前の要素で違ったデータ型をとったことはなかったよね。

さらら: あ、それはなかったわ。ある名前の一つの要素は、必ず何らかの一つのデータ型と結びついていたわね。

<!ELEMENT pi:sex EMPTY>
<!ELEMENT pi:sex "#PCDATA">
 なんて書いていたらエラーよね。

たけち: そうだね。だけどどうして、同じ名前の要素は必ず何らかの一つのデータ型と結びついているのに、同じ名前の属性は異なるデータ型をとることがあるんだろうか?

さらら: どうしてって言われても... 要素と属性はそういうふうに決められているからでしょ。

たけち: う〜ん、そうだねぇ。じゃあまずDTDの書き方から見てみようかな。

さらら

<!ELEMENT pi:sex EMPTY>
<!ATTLIST pi:sex class (male | female) #REQUIRED >
<!ELEMENT pi:degree EMPTY>
<!ATTLIST pi:degree class (正一位 | 従一位 | 正ニ位 | 従二位 | 正三位 | 従三位 | 正四位上 | 正四位下 | 従四位上 | 従四位下 | 正五位上 | 正五位下 | 従五位上 | 従五位下 | 正六位上 | 正六位下 | 従六位上 | 従六位下 | 正七位上 | 正七位下 | 従七位上 | 従七位下 | 正八位上 | 正八位下 | 従八位上 | 従八位下 | 大初位上 | 大初位下 | 少初位上 | 少初位下) #REQUIRED>

たけち: pi:sexとかpi:degreeといった要素は、他の要素などは関係なく、それがどういうデータ形式をとるかが宣言されているよね。

さらら: えぇ。

たけち: そう。もしここで、
<!ELEMENT pi:sex EMPTY>
<!ELEMENT pi:sex "#PCDATA">

 という2つの同一名の要素型宣言があったらエラーになるよね。

さらら: そうよね。


■どの要素の属性か、どのデータ型の属性か

たけち: それに対して属性リスト宣言の方は、

<!ATTLIST pi:sex class (male | female) #REQUIRED >
<!ATTLIST pi:degree class (正一位 | 従一位 | 正ニ位 | 従二位 | 正三位 | 従三位 | 正四位上 | 正四位下 | 従四位上 | 従四位下 | 正五位上 | 正五位下 | 従五位上 | 従五位下 | 正六位上 | 正六位下 | 従六位上 | 従六位下 | 正七位上 | 正七位下 | 従七位上 | 従七位下 | 正八位上 | 正八位下 | 従八位上 | 従八位下 | 大初位上 | 大初位下 | 少初位上 | 少初位下) #REQUIRED>

たけち: というふうに、「pi:sex要素のclass属性」「pi:degree要素のclass属性」という書き方がされているんだ。つまりDTDでは、属性は、どの要素の属性かということを書かないと宣言できないんだ。

さらら: えぇ、そういう書き方するわよね。

たけち: じゃあ、次にXML Schemaではどう書いていたかをみてみようね。

<xsd:complexType name="SexType">
<xsd:attribute name="class" type="pi:SexClassType" />
</xsd:complexType>

<xsd:complexType name="DegreeType">
<xsd:attribute name="class" type="pi:DegreeClassType" />
</xsd:complexType>

たけち: この書き方を見てわかるように、直接、要素宣言の直下で属性宣言をするのではなくて、SexType型のclass属性、DegreeType型のclass属性ということを書いて宣言していたんだね。
「匿名のデータ型」を使う場合には、一見、要素宣言の下で属性宣言をしているように見えるけれど、ちゃんとデータ型の定義をしないといけなかったことは前に話したね。
要するにどのデータ型の属性かという書き方で宣言していたんだね。

さらら: そういうことになるわ。それで?

たけち: 属性は「どの要素の属性か」「どのデータ型の属性か」という書き方で宣言していた。だから、同じclassという名前の属性でも、「どの要素の属性か」「どのデータ型の属性か」ということが違えば、異なるデータ型になってもかまわなかった、ということなんだ。

さらら: えぇ、でも何か、すごくあたりまえのことのように思えるわ。

たけち: うん、そうなんだけれど、ここでわかって欲しかったのは、属性というものは、要素やデータ型に所属しているものだという考え方がある、ということなんだ。

たけち

さらら: それってあたりまえじゃないの? 「要素に所属している性質」なんだから「属性」と呼ぶわけなんでしょ。
田中家の一郎君と、鈴木家の一郎君が別人であるように、「pi:sex要素のclass属性」と「pi:degree要素のclass属性」は別でいいんじゃないの。

たけち: うん、そうだね。今さららが言ったことは、属性に対する考え方の基本なんだね。

さらら: 基本? じゃあ、応用があるの?...えっ?

さらら、混乱のうちに、グローバル属性とグローバル属性宣言 その2に続きます...... (^ ^;

さらら

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