匿名の型定義

2002年8月18日(日)更新


■匿名の型定義

たけち: 今日から複合型の話をするつもりだったけれど、ちょっと横道にそれて匿名の型定義の話をするね。まず、以前説明した「テストの点数型」に出てきてもらおうね。

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

<xsd:element name="kokugo_test" type="TestPointType" />

<xsd:simpleType name="TestPointType">
  <xsd:restriction base="xsd:int">
  <xsd:minInclusive value="0" />
  <xsd:maxInclusive value="100" />

  </xsd:restriction>
</xsd:simpleType>

</xsd:schema>

さらら: 0〜100の値をとるTestPointTypeというデータ型を定義して、それをkokugo_testという要素の宣言に使っているのね。

たけち: そうだよね。ところで今日はデータ型の名前を定義せずに、同じ内容を定義してみるね。

さらら: えっ、データ型の定義をしないの?

たけち: あっ、そうじゃないんだ。XMLスキーマでは、まずはじめにデータ型ありきで、データ型の定義なしには、要素の構造を決めることはできないんだ。データ型の定義は絶対必要なんだよ。ただ、そのデータ型の名前を省略する方法があるということだよ。例えば、つぎのようにするんだよ。

さらら

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

<xsd:element name="kokugo_test">
  <xsd:simpleType>
  <xsd:restriction base="xsd:int">
  <xsd:minInclusive value="0" />
  <xsd:maxInclusive value="100" />
  </xsd:restriction>
</xsd:simpleType>
<xsd:element>

</xsd:schema>

さらら: わぁ、これだと見やすいわぁ。 (^ ^*
これって、要素の宣言の内容として、直接、データ型の定義を持ってきてるのね。これだとTestPointTypeというデータ型の名前なんか要らないし、書く手間が省けて楽だわ。

たけち: こういうデータ型の名前を決めないデータ型の定義を匿名の型定義と呼ぶんだよ。

さらら: どうしてこれを今まで教えてくれなかったの?

さらら


■匿名の型定義じゃない方がいい場合

たけち: そうだね(^^;) 今まで教えなかった理由の一つは、要素や属性を宣言するためには、まずデータ型が必要ということを、まずはしっかりと覚えてもらいたかったからなんだ。匿名の型定義の書き方だと、今ひとつこの点が覚えてもらいにくいところがあったからね。それともう一つは、一つのデータ型が必ず一つの要素しか使われないなら匿名の型定義で充分だけれど、一つのデータ型が複数の要素の宣言に使われたりする場合は匿名の型定義じゃない方がいいからね。

さらら: 例えばどんなこと?

たけち: 例えば次のような例だよ。

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

<xsd:element name="kokugo_test" type="TestPointType" />
<xsd:element name="rika_test" type="TestPointType" />
<xsd:element name="shakai_test" type="TestPointType" />
<xsd:element name="sansuu_test" type="TestPointType" />

<xsd:simpleType name="TestPointType">
<xsd:restriction base="xsd:int">
<xsd:minInclusive value="0" />
<xsd:maxInclusive value="100" />
</xsd:restriction>
</xsd:simpleType>

</xsd:schema>


■派生の基準型の例

さらら: なるほど、そうよね。全部の要素にいちいち匿名の型を書いていられないものね。

たけち: それと「匿名の型定義」が使われるのは、要素や属性の宣言だけでなくて、他にも使える場面があることも覚えておこうね。まず今まで派生の元となる基準型をxsd:restriction要素の中のbase属性の値で指定していたけれど、これも匿名の型定義を使うことができるんだ。例えば次の例を見てみようね。

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

<xsd:element name="kokugo_test" type="TestPoint10Type" />

<xsd:simpleType name="TestPoint10Type">
<xsd:restriction base="TestPointType">
<xsd:pattern value="\d*0" />
</xsd:restriction>
</xsd:simpleType>

<xsd:simpleType name="TestPointType">
<xsd:restriction base="xsd:int">
<xsd:minInclusive value="0" />
<xsd:maxInclusive value="100" />
</xsd:restriction>
</xsd:simpleType>

</xsd:schema>

たけち: これは先ほどのTestPointTypeを元に、それの1桁目が0、つまり0点、10点、20点.....80点、90点、100点といった10単位の点数でないといけないというTestPoint10Typeを定義したものだよ。

さらら: <xsd:pattern value="\d*0" />というのがそうなのね。

たけち: そうそう。<xsd:pattern value="\d*0" />というのが、1桁目が0であることを示しているんだね。これを以下のように書くことができるんだ。

たけち

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

<xsd:element name="kokugo_test" type="TestPoint10Type" />

<xsd:simpleType name="TestPoint10Type">
  <xsd:restriction>
    <xsd:simpleType>
      <xsd:restriction base="xsd:int">
      <xsd:minInclusive value="0" />
      <xsd:maxInclusive value="100" />
      </xsd:restriction>
    </xsd:simpleType>
    <xsd:pattern value="\d*0" />
  </xsd:restriction>
</xsd:simpleType>

</xsd:schema>

さらら: TestPoint10Typeの基準型が<xsd:restriction>の内容になっているわけね。

たけち: そう。こういう書き方もできるんだね。


■ユニオン(union)の例

たけち: あと、前々回のユニオンの例についてみておこう。次のようだったね。

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

<xsd:element name="ranking" type="RankingType" />

<xsd:simpleType name="RankingType">
<xsd:union memberTypes="DisqualifiedType xsd:positiveInteger" />
</xsd:simpleType>

<xsd:simpleType name="DisqualifiedType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="失格" />
</xsd:restriction>
</xsd:simpleType>

</xsd:schema>

たけち: これをつぎのように書くことができるんだよ。

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

<xsd:element name="ranking" type="RankingType" />

<xsd:simpleType name="RankingType">
  <xsd:union memberTypes="xsd:positiveInteger">
  <xsd:simpleType>
  <xsd:restriction base="xsd:string">
  <xsd:enumeration value="失格" />
  </xsd:restriction>
  </xsd:simpleType>
  </xsd:union>
</xsd:simpleType>

</xsd:schema>

さらら: memberTypes属性の値の中から、DisqualifiedTypeが消えてしまって、xsd:unionの内容に匿名の型定義が来たのね。

たけち: そうなんだ。さらに次のように書くと、memberTypes属性そのものが必要なくなってしまうんだよ。

さらら

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

<xsd:element name="ranking" type="RankingType" />

<xsd:simpleType name="RankingType">
  <xsd:union>
    <xsd:simpleType>
    <xsd:restriction base="xsd:positiveInteger" />
    </xsd:simpleType>
    <xsd:simpleType>
    <xsd:restriction base="xsd:string">
    <xsd:enumeration value="失格" />
    </xsd:restriction>
    </xsd:simpleType>
  </xsd:union>
</xsd:simpleType>

</xsd:schema>

さらら: あれ?
    <xsd:simpleType>
    <xsd:restriction base="xsd:positiveInteger" />
    </xsd:simpleType>
って書き方、なんか変じゃない? xsd:positiveIntegerを制限(restriction)しますよ、と言っておきながら、制約ファセットが存在しないわ。

たけち: うん、こういう書き方も許されるんだよ。「以下のように制限(restriction)しますよ」と言っておきながら、具体的にどう制限するのかという制約ファセットが存在しない、ということは、早い話が制限していない、ということだよ。つまりxsd:positiveIntegerそのもの、ということになるね。まあこういう書き方をするのは、ちょっとやりすぎだけどね (^ ^; )

さらら: ふ〜ん、こんな書き方も許されるってことなのね。


■リスト(list)の例

たけち: それから、匿名の型定義は前回学んだxsd:listでも使えるんだよ。
まず、今まで歌の番号を正の整数(xsd:positiveInteger)であらわしてきたけれど、よく考えると、万葉集の歌は全部で4516首(→注参照)に分類するのが一般的だよね。1番から4516番までしかないわけだから、以下のように書くともっと厳密だよね。

たけち

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

<xsd:element name="yomi" type="YomiType" />

<xsd:complexType name="YomiType">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="pno" type="ManyouPoemNumberType" use="required" />
<xsd:attribute name="hanka" type="ManyouPoemNumberListType" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>

<xsd:simpleType name="ManyouPoemNumberListType">
<xsd:list itemType="ManyouPoemNumberType" />
</xsd:simpleType>

<xsd:simpleType name="ManyouPoemNumberType">
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxInclusive value="4516" />
</xsd:restriction>
</xsd:simpleType>

</xsd:schema>

さらら: そうねぇ。このほうが厳密なのよね。。。。。

たけち: どうしたの?

さらら: あっ、ちょっと頭の中がごちゃごちゃしやって... (^ ^;

たけち: あっ、そっか。じゃあ、今のスキーマ定義を簡単な図にしてみるから関連を確認してみて。

たけち

万葉歌の属性例

さらら: やっとわかったわ。

たけち: やはりこの場合、<xsd:list>の内容に匿名の型定義を持ってくることができて、次のように書くこともできるんだよ。

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

<xsd:element name="yomi" type="YomiType" />

<xsd:complexType name="YomiType">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="pno" type="xsd:positiveInteger" use="required" />
<xsd:attribute name="hanka" type="ManyouPoemNumberListType" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>

<xsd:simpleType name="ManyouPoemNumberListType">
<xsd:list>
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxInclusive value="4516" />
</xsd:restriction>
</xsd:simpleType>
</xsd:list>

</xsd:simpleType>

</xsd:schema>

さらら: なるほど、わかったわ。この書き方もすっきりまとめられていていいわね。

たけち: ただこの例の場合、ManyouPoemNumberTypeという名前が消えてしまったから、この名前でpno属性を宣言できないんだよね。それで、そこはxsd:positiveIntegerに戻してしまっているんだけどね(^^;) ここも同じ内容にすると二度手間だからね。

さらら: あら、本当だわ。こうしてみると、匿名の型定義って、注意して使わないといけないのね。

たけち: そうだね。それなりに合っている場合に使えばすっきりするけれど、考えて使わないと、かえって見づらくなったり使いにくくなったりする場合もあるから気をつけようね。

さらら: は〜い。

→ 次回は、単純型内容を持った複合型 - 定義の基本です。。。。 (^ ^)v

さらら


■注) 万葉歌の数は、数え方によって異なります。たとえば、万葉集古義では4496首とされているようですし、現在では、4536首という見解が指示されているようです。ここでは、4516首とさせていただいています。

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