グローバル属性 - xsi:nil属性

2003年6月8日(日)更新


■(復習)xsiの名前空間に属する4種類のグローバル属性

たけち: 今まで、xsd:anyとxsd:anyAttributeを学んできたけれど、どうしてこの2つを勉強することになったかというと、「xsi:schemaLocationには、複数の名前空間とスキーマファイルのペアを書かないといけない場合がある」という話から、こっちの方に話がとんだんだよね。

さらら: えぇ、そういえば、そうだったわね。

たけち: xsi:schemaLocationの話をした時に、xsiの名前空間には、4種類のグローバル属性が属している、って言ったのを覚えている?

さらら: あっ、う〜ん。。(^ ^;

たけち: それは次の四つだったんだよ。

  1. xsi:schemaLocation属性
  2. xsi:noNamespaceSchemaLocation属性
  3. xsi:nil属性
  4. xsi:type属性
たけち

さらら: そうだったような・・・(^ ^;

たけち: で、この4種類のグローバル属性に共通する性質は次のようだったね。

  1. XMLデータ(instance)の中で使われる。
  2. XMLデータ(instance)のどこに使われても、その存在そのものはXML Schema側で定義しなくても良い。

さらら: そういえばそういう話もあったわ。あ、それだったら、まだxsi:nil属性とxsi:type属性のことを聞いていないわ(^ ^;)

たけち: そうだね、話がxsd:anyとxsd:anyAttributeの方に自然に移ってしまったので、まだこの2つについて勉強していないんだ。というわけで、今日はxsi:nil属性について勉強しようね。

さらら

■例: 歌集をつくる

たけち: まず、こんなことを考えてみようね。さららと僕が、これから世の中に対して歌を公募して、歌集を作ろうとしたとするよね。

さらら: 歌集?! 楽しそうね。

たけち: 公募して集める目標の歌の数としては50首以上かな。これをXML化するんだけれど、そのXMLデータは例えば以下のようにしてみようか。

XMLデータ例: 歌集【m_poem.xml】
<?xml version="1.0" encoding="Shift_JIS" ?>
<an:anthology xmlns:an="http://www.yuragi.jp/ns/anthology"
     xsi:schemaLocation="http://www.yuragi.jp/ns/anthology anthology.xsd"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<an:title>
さらら-たけち編纂和歌集</an:title>
<an:anthologists>
<an:anthologist>さらら</an:anthologist>
<an:anthologist>たけち</an:anthologist>
</an:anthologists>
<an:poems>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
         :
         :
</an:poems>

</an:anthology>


■歌を集める前には歌が無い

さらら: ちょっ、ちょっと、たけちぃ(- -;)

たけち: えっ。な、なに(^ ^;)

さらら: 「この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌」って、ひどすぎない(- -;)。それにその後に「:」なんてマークが入っているけれど、実際にこういうものがXMLデータの中に入るわけないわよね。

たけち: それはそうだね(^ ^;) なにしろ、肝心のデータというか歌はこれから公募するんだから、現時点では存在しないんだ。現時点では存在しないから、こういうダミーを書いて例示したんだけれど...(^ ^;)

さらら

さらら: でも、こんな歌が絶対、歌集の中に実際に入るわけないわよね。

たけち: それは、もちろん。これはあくまでダミーだもの (^ ^;)

さらら: じゃあ、外してしまう方が正しくないかしら? 公募していないうちは、このan:poems要素の中に入るan:poem要素の内容は空だと決まっているわ。

たけち: じゃあ、そうしようね。そうすると、次のようになるよ。

XMLデータ例: 歌の無い歌集データ 【anthology.xml】
<?xml version="1.0" encoding="Shift_JIS" ?>
<an:anthology xmlns:an="http://www.yuragi.jp/ns/anthology"
     xsi:schemaLocation="http://www.yuragi.jp/ns/anthology   anthology.xsd"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<an:title>さらら-たけち編纂和歌集</an:title>
<an:anthologists>
<an:anthologist>さらら</an:anthologist>
<an:anthologist>たけち</an:anthologist>
</an:anthologists>
<an:poems />
</an:anthology>


■歌集のXMLスキーマ例

さらら: これで良いと思うわ。公募していないうちは、これが正しいのよ。

たけち: 確かにそうだね。さて、さっきのXMLデータのXML Schemaを作ってみてね。さっきも言ったように集める歌の数の目標は50首以上なんだから、an:poem要素のminOccursの値は50になるんだよ。

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

<xsd:element name="anthology" type="an:AnthologyType" />

<xsd:complexType name="AnthologyType">
  <xsd:sequence>
    <xsd:element ref="an:title" />
    <xsd:element ref="an:anthologists" />
    <xsd:element ref="an:poems" />
  </xsd:sequence>
</xsd:complexType>

<xsd:element name="title" type="xsd:string" />

<xsd:element name="anthologists" type="an:AnthologistsType" />

<xsd:complexType name="AnthologistsType">
  <xsd:sequence>
    <xsd:element ref="an:anthologist" maxOccurs="unbounded" />
  </xsd:sequence>
</xsd:complexType>

<xsd:element name="anthologist" type="xsd:string" />

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

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


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

</xsd:schema>

さらら: こんな感じかしら。

たけち: そうだねぇ。確かにこれで正しいんだけれど、だけどさっきのXMLデータは検証でエラーになるよね。

さらら: えっ? 正しいなら検証がパスするはずじゃない。え〜と、XMLSPYで確かめて... あら? エラーが出力されたわ(^ ^;)

たけち

【anthology.xml】をXMLSPYで検証した結果


■XMLデータ【anthology.xml】がエラーとなった理由

たけち: XML Schema【anthology.xsd】に
<xsd:complexType name="PoemsType">
  <xsd:sequence>
    <xsd:element ref="an:poem" minOccurs="50" maxOccurs="unbounded" />
  </xsd:sequence>
</xsd:complexType>

 と書いたのに、XMLデータ【anthology.xml】にはan:poem要素は存在せず、an:poems要素は空要素になっているよね。だからエラーになるんだ。

さらら: あっ、そっか〜。現時点では一首も歌のデータが存在しないからエラーになるのね。でも、せめてそれ以外の部分だけでも正しいかどうか検証したいわね。どうしたらいいのかしら?


■歌集XMLデータの検証をOKにする方法

たけち: まず、一つの方法はダミーのデータを実際に50以上入れたXMLデータで検証することだね。

XMLデータ例: ダミー歌を50個入れた歌集データ
<?xml version="1.0" encoding="Shift_JIS" ?>
<an:anthology xmlns:an="http://www.yuragi.jp/ns/anthology"
     xsi:schemaLocation="http://www.yuragi.jp/ns/anthology   anthology.xsd"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<an:title>さらら-たけち編纂和歌集</an:title>
<an:anthologists>
<an:anthologist>さらら</an:anthologist>
<an:anthologist>たけち</an:anthologist>
</an:anthologists>
<an:poems>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
<an:poem>この歌は ほんとじゃないよ ほんとはね ダミーであって にせものの歌</an:poem>
</an:poems>
</an:anthology>

さらら: やだぁ〜! こんなのいやぁ!(^ ^;)

たけち: そうだね(^^;) いくらダミーを50以上用意すればうまくいくとはいえ、みっともなさすぎるよね (^ ^;) 実はもっとスマートに綺麗に検証する方法がXML Schemaには用意されているんだよ。

さらら: え、どんな方法?


■xsi:nil属性を使用する方法

たけち: 以下のXMLデータとXML Schemaを見てごらん。

XMLデータ例: xsi:nil属性を使用した歌集データ
<?xml version="1.0" encoding="Shift_JIS" ?>
<an:anthology xmlns:an="http://www.yuragi.jp/ns/anthology"
     xsi:schemaLocation="http://www.yuragi.jp/ns/anthology   anthology.xsd"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<an:title>さらら-たけち編纂和歌集</an:title>
<an:anthologists>
<an:anthologist>さらら</an:anthologist>
<an:anthologist>たけち</an:anthologist>
</an:anthologists>
<an:poems xsi:nil="true" />
</an:anthology>

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

<xsd:element name="anthology" type="an:AnthologyType" />

<xsd:complexType name="AnthologyType">
  <xsd:sequence>
    <xsd:element ref="an:title" />
    <xsd:element ref="an:anthologists" />
    <xsd:element ref="an:poems" nillable="true" />
  </xsd:sequence>
</xsd:complexType>

<xsd:element name="title" type="xsd:string" />

<xsd:element name="anthologists" type="an:AnthologistsType" />

<xsd:complexType name="AnthologistsType">
  <xsd:sequence>
    <xsd:element ref="an:anthologist" maxOccurs="unbounded" />
  </xsd:sequence>
</xsd:complexType>

<xsd:element name="anthologist" type="xsd:string" />

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

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

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

</xsd:schema>

たけち: はじめの方で作ったXMLデータとXML Schemaと比べると、それぞれ一箇所ずつ変更された点があるんだ。まず、XML Schemaの方では、an:poems要素の参照の中で、
    <xsd:element ref="an:poems" nillable="true" />
というふうに、nillable="true"という新しい属性が加わっていることなんだ。これはこのan:poems要素を「空要素にすることができる」という意味なんだ。

さらら: へぇ〜、こんなのがあるのね。

たけち: 次にXMLデータの方を見て欲しいけれど、an:poems要素は、
<an:poems xsi:nil="true" />
 と書かれているよね。つまりxsi:nil="true"というグローバル属性が新たに加わっているね。これはこのan:poems要素を空要素にしますということを表現しているんだ。

さらら: うわー、こうするとan:poems要素が空要素でも、ちゃんと検証してくれるのね。

さらら

たけち: そうだよ。ただ、ここで気をつけて欲しいのは、XML Schema側の、
    nillable="true"
 と、実際のXMLデータ側の
    xsi:nil="true"
 の2つが両方とも揃って、初めて空要素のままでも大丈夫だと検証してくれることなんだ。
だから、nillable="true"が設定してあっても、xsi:nil="true"が書いてなければ駄目だし、逆にxsi:nil="true"が書いてあっても、nillable="true"が設定していなければ駄目なんだよ。

さらら: あら、どっちかでも良いようにしてくれればいいのに。

たけち: でも、こうなっているからこそ、実際に50首以上のデータが集まったあとでは、xsi:nil="true"を書かないことによって、ちゃんと50首以上あることを検証できるよね。

さらら: あ、そうか。元々意図したことも、ちゃんと検証できるようにもなるのね。便利そうだわ。

たけち

たけち: そうなんだね。xsi:nilについてはこれでおしまい。

さらら: それじゃあ、次回は4つのxsiのグローバル属性のうち、最後のxsi:typeね。

たけち: うん、そうだね。

さらら: ありがと。

次回は、xsi:type属性(1)です...... (^ ^;

さらら


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