グローバル属性 - xsi:type属性(2)

2003年6月22日(日)更新


■代替要素を使う例

たけち: 今回は、代替要素を使う場合について学ぼうね。

さらら: はい。

たけち: まずは代替要素を使ったXMLスキーマの例をみてみよう。

XMLデータ例: 万葉歌 【manyouPoem1.xml】
<?xml version="1.0" encoding="Shift_JIS" ?>
<mp:poems
     xsi:schemaLocation="http://www.yuragi.jp/ns/manyouPoem manyouPoem1.xsd"
     xmlns:mp="http://www.yuragi.jp/ns/manyouPoem"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

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

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

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

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

</mp:poems>

XML Schema例: 万葉歌 【manyouPoem1.xsd】
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema targetNamespace="http://www.yuragi.jp/ns/manyouPoem"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns:mp="http://www.yuragi.jp/ns/manyouPoem">

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

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

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

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

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

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

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

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

<xsd:complexType name="MetaphoricalPoemType">
     <xsd:complexContent>
          <xsd:extension base="mp: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="mp: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>

さらら: あっ、これって代替要素のところに出てきたわね。

たけち: そう、この例を、xsi:typeを使って、以下のようなXMLデータとXML Schemaの組み合わせに変えることができるんだよ。

たけち


■xsi:typeを使うと、XMLスキーマで代替要素を使わなくて良い

XMLデータ例: 万葉歌 【manyouPoem2.xml】 xsi:type属性を使用
<?xml version="1.0" encoding="Shift_JIS" ?>
<mp:poems
     xsi:schemaLocation="http://www.yuragi.jp/ns/manyouPoem manyouPoem2.xsd"
     xmlns:mp="http://www.yuragi.jp/ns/manyouPoem"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

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

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

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

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

</mp:poems>

XML Schema例: 万葉歌 【manyouPoem2.xsd】
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema targetNamespace="http://www.yuragi.jp/ns/manyouPoem"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns:mp="http://www.yuragi.jp/ns/manyouPoem">

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

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

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

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

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

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

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

<xsd:complexType name="MetaphoricalPoemType">
     <xsd:complexContent>
          <xsd:extension base="mp: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="mp: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スキーマは、代替要素を使ってないのね。

たけち: そうなんだ。XMLスキーマ【manyouPoem2.xsd】に

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

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

 と書かれていることからわかるように、PoemTypeを抽象的なデータ型として宣言してしまったので、それを使って宣言しているpoem要素は本来出現できないはずなんだよね。

さらら: あっ、そうよね。

たけち: そうなんだね。

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

たけち:  と書いたりすれば、エラーになるはずだよね。だけど、

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

たけち:  と書くことによって、このpoem要素はMiscellaneousPoemType型を使って宣言されているのと同じことになるんだね。だから出現可能になっているんだよ。

さらら: なるほど。。。。。。代替要素を使ったのと似たようなことができるわけなのね。

さらら


■複数のデータ型をとりうる場合に、そのどれかを指定する場合

たけち: それから例えば、こういう例を考えてみるね。

 医療機関に病気でかかる場合、病気やその人の状況によっては、公費で医療費が支払われる場合もあるんだよね。その場合、窓口でいくらか本人が負担する場合もあって、どれくらい負担するかは、「10,000円の負担」というふうに固定的な金額が決められている場合もあるし、「かかった医療費の5%を負担」というふうに、率(パーセント)で決められている場合もあるんだよね。

これをXMLデータで表現すると、次のような2つのXMLデータのような感じになるよ。

たけち

XMLデータ例: 固定的な金額が決められている場合(10,000円、など)
<?xml version="1.0" encoding="Shift_JIS" ?>
<hi:payment xsi:type="hi:Fix"
  &nbs;  xmlns:hi="http://www.yuragi.jp/ns/HealthInsurance"
  &nbs;  xsi:schemaLocation="http://www.yuragi.jp/ns/HealthInsurance hi.xsd"
  &nbs;  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

10000
</hi:payment>

XMLデータ例: 率で決められている場合(かかった医療費の5%、など)
<?xml version="1.0" encoding="Shift_JIS" ?>
<hi:payment xsi:type="hi:Ratio"
  &nbs;  xmlns:hi="http://www.yuragi.jp/ns/HealthInsurance"
  &nbs;  xsi:schemaLocation="http://www.yuragi.jp/ns/HealthInsurance hi.xsd"
  &nbs;  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

0.05
</hi:payment>

さらら: 最初のXMLデータが、xsi:type="hi:Fix" で固定的な金額ということを示して、その次のXMLデータが xsi:type="hi:Ratio" で率ということを示しているのね。

たけち: そう、この場合は次のようにスキーマを書くことができるんだよ。

XML Schema例: 医療費 【hi.xsd】
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema targetNamespace="http://www.yuragi.jp/ns/HealthInsurance"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns:hi="http://www.yuragi.jp/ns/HealthInsurance">

<xsd:element name="payment" type="hi:PaymentType" />

<xsd:simpleType name="PaymentType">
     <xsd:union memberTypes="hi:Fix   hi:Ratio" />
</xsd:simpleType>


<xsd:simpleType name="Fix">
<xsd:restriction base="xsd:integer" />
</xsd:simpleType>

<xsd:simpleType name="Ratio">
<xsd:restriction base="xsd:decimal">
<xsd:minInclusive value="0" />
<xsd:maxInclusive value="1" />
<xsd:fractionDigits value="2" />
</xsd:restriction>
</xsd:simpleType>

</xsd:schema>


■unionのメンバー型をxsi:typeで指定できる

さらら: なるほど、実際のpaymentがとりうるデータ型のPaymentTypeは、FixとRatioのユニオン型なのね。こういう使い方があるのね... あら? あれ? あれれぇ??

たけち: えっ、どうしたの?(^ ^;)

さらら: たけちって、最初に、
xsi:typeを使って変更できるデータ型は、元々宣言されたデータ型から派生したデータ型に限る
 って、言わなかったかしら?

たけち: うん、そういう説明をしたよね(^ ^;)

さらら: この場合、FixとRatioから派生してPaymentTypeが作られたのよね。FixとRatioは派生したデータ型ではなくて、派生の元になっているデータ型だわ。これでいいの?

さらら

たけち: 確かにそう思えるけれど、実はユニオン型の場合は例外なんだ。この場合は、派生の元となっているメンバー型の方が、xsi:typeを使って変更できるデータ型になるんだよ(^^;)

さらら: そっ、そうなの?

たけち: それについては次回にしようね。

さらら: うーん、ユニオン型だけ例外なのね。何かずるいみたい。

たけち: でも、この方が意味が通るよね(^ ^;)

さらら: えぇ、そうだわねぇ。(^ ^*

たけち: グローバル属性全般については、これでおしまいにするね。

さらら: はい。ありがとう。

次回に続きます...... (^ ^;


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