redefine

2003年2月16日(日)更新


■要素の定義を新しいスキーマファイルで変更できる

たけち: 前回は、同じ名前空間のスキーマを参照できるincludeについて説明したよね。

さらら: そうね。

たけち: 同じ名前空間のスキーマを参照できるのなら、ついでに場合によってはその定義を一部変更するようなことができると便利だよね。

さらら: あ、それは便利そうね(^^) 要素の定義を新しいスキーマファイルで変更できる、というわけなのね。

たけち: だいたいそんなところだね。以下の4つを新しいスキーマファイルで変更するredefineというテクニックがあるんだ。ただ、厳密に言うと「要素宣言」や「属性宣言」そのものは変更できないんだけどね。

さらら

【redefineで変更できるもの】

  • simpleType
  • compleType
  • group
  • attributeGroup

さらら: ふ〜ん、そうなのね。でも、これだけじゃ、なんのことかよくわかんないわ。

たけち: まずは実際に見てもらった方が早いよね。まず、次のXMLデータをみてみよう。

XMLデータ例: 万葉歌人
<?xml version="1.0" encoding="Shift_JIS" ?>
<po:poets xmlns:po="http://www.yuragi.jp/ns/poets">柿本人麻呂 持統天皇 大伴家持 有間皇子</po:poets>

たけち: このXMLデータのXML Schemaとして、次のものを考えたとしよう。

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

<xsd:element name="poets" type="po:PoetsType" />

<xsd:simpleType name="PoetsType">
<xsd:list itemType="xsd:Name" />
</xsd:simpleType>

</xsd:schema>

さらら: あ、これって覚えがあるわ。単純型のリストの説明で出てきた例題よね。そのときは、これをさらにリストの数、つまり詩人の人数が4人になるように変更したのよね。

たけち: そうだったよね。今回も同じようにリストの数、つまり歌人の人数が4人になるように変更してみるけれど、今回はあの時と違って、データ型の名前を変えずにこれを変更してみるね。

さらら: データ型の名前を変えずに変更する?

たけち: そう、実際には次のようにするんだよ。

W3C XML Schema: 万葉歌人(歌人数を4人に制限)
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
         targetNamespace="http://www.yuragi.jp/ns/poets"
         xmlns:po="http://www.yuragi.jp/ns/poets">

<xsd:redefine schemaLocation="poets1.xsd">
<xsd:simpleType name="PoetsType">
<xsd:restriction base="po:PoetsType">
<xsd:length value="4" />
</xsd:restriction>

</xsd:simpleType>
</xsd:redefine>

</xsd:schema>


■redefine要素の中では、基準型と派生型のデータ型の名前が同じ

さらら: あれぇ!?、基準型と派生型のデータ型の名前が同じなの!? 自分自身を基準型にして、派生しているわけなの!?

たけち: そう、普通はこんなことをしたらエラーになるけれど、xsd:redefine要素の中だけは、逆にこれをしないとエラーになるんだ。

さらら: そうなの〜。

たけち: includeでは、同じ名前空間の要素やデータ型、名前付きモデルグループ、名前付き属性グループなどを参照したよね。けれども、あくまで参照するだけであって、その定義まで変更してしまうことはなかったよね。
それに対して、このredefineは、既に別のスキーマファイルで定義されたデータ型、名前付きモデルグループ、名前付き属性グループなどの定義を、自分自身を基準型にしたり、含めたりして、定義し直すものなんだよ。

さらら: そうなんだぁ。

たけち: この例での、そうした関係を見ておこうね。

たけち

redefine


■complexTypeをredefineする例

たけち: 今のはsimpleTypeをredefineした例だったけど、complexTypeをredefineする例も見てみようね。

さらら: えぇ。

たけち: まずXMLデータとそれに対応するXML Schemaを見て。

XMLデータ例: 万葉歌
<?xml version="1.0" encoding="Shift_JIS" ?>
<mp:poem pno="8" xmlns:mp="http://www.yuragi.jp/ns/manyouPoem">
<mp:poet>額田王</mp:poet>
<mp:yomi>熟田津に船乗りせむと月待てば潮もかなひぬ今は漕ぎ出でな</mp:yomi>
</mp:poem>

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="poem" type="mp:PoemType" />

<xsd:complexType name="PoemType">
<xsd:sequence>
<xsd:element ref="mp:poet" />
<xsd:element ref="mp:yomi" />
</xsd:sequence>
<xsd:attribute name="pno" type="xsd:positiveInteger" />
</xsd:complexType>

<xsd:element name="poet" type="xsd:string" />
<xsd:element name="yomi" type="xsd:string" />

</xsd:schema>

さらら: えぇ。わかるわ。

たけち: このXMLデータの内容にkana要素(万葉仮名の文字列を内容として持つ)を追加したような、次のようなXMLデータを考えるよ。

XMLデータ例: 万葉歌-2: kana要素を追加
<?xml version="1.0" encoding="Shift_JIS" ?>
<mp:poem pno="8" xmlns:mp="http://www.yuragi.jp/ns/manyouPoem">
<mp:poet>額田王</mp:poet>
<mp:yomi>熟田津に船乗りせむと月待てば潮もかなひぬ今は漕ぎ出でな</mp:yomi>
<mp:kana>熟田津尓 船乗世武登 月待者 潮毛可奈比沼 今者許藝乞菜</mp:kana>
</mp:poem>

さらら: うんうん。

たけち: これに対応するXML Schemaはredefineを使って次のように書くことができるんだよ。

XML Schema例: 万葉歌-2: kana要素を追加
<?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:redefine schemaLocation="manyouPoem1.xsd">
<xsd:complexType name="PoemType">
<xsd:complexContent>
<xsd:extension base="mp:PoemType">
<xsd:sequence>
<xsd:element ref="mp:kana" />
</xsd:sequence>
</xsd:extension>

</xsd:complexContent>
</xsd:complexType>
</xsd:redefine>

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

</xsd:schema>


■名前付き属性グループ(attributeGroup)をredefineする例

さらら: これも同じ名前の基準型を使って、派生させているのね。

たけち: そうだね。じゃあ、名前付き属性グループ(attributeGroup)の場合も見てみようね。

XMLデータ例: 万葉歌-3
<?xml version="1.0" encoding="Shift_JIS" ?>
<mp:poem pno="0408" xmlns:mp="http://www.yuragi.jp/ns/manyouPoem">
<mp:poet>大伴家持</mp:poet>
<mp:yomi>なでしこがその花にもが朝な朝な手に取り持ちて恋ひぬ日なけむ</mp:yomi>
</mp:poem>

XML Schema例: 万葉歌-3: 【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="poem" type="mp:PoemType" />

<xsd:complexType name="PoemType">
<xsd:sequence>
<xsd:element ref="mp:poet" />
<xsd:element ref="mp:yomi" />
</xsd:sequence>
<xsd:attributeGroup ref="mp:poemAttribute" />
</xsd:complexType>

<xsd:element name="poet" type="xsd:string" />
<xsd:element name="yomi" type="xsd:string" />

<xsd:attributeGroup name="poemAttribute">
<xsd:attribute name="pno" type="xsd:positiveInteger" use="required" />
</xsd:attributeGroup>


</xsd:schema>

さらら: あら、pno属性を定めた部分が名前付き属性グループとして独立しているわ。こんなことをしたら、逆に面倒くさい感じなのに。

たけち: 今まで名前付き属性グループを、綺麗にまとめて記述する手段としてだけ学んできたから、ちょっと変に見えるかもしれないね。でもこれが名前付き属性グループをredefineするために必要な下ごしらえなんだよ。さて、さっきのXMLデータを次のように拡張することを考えるね。

さらら

XMLデータ例: 万葉歌-4
<?xml version="1.0" encoding="Shift_JIS" ?>
<mp:poem pno="0408" sendTo="坂上大嬢" emotion="恋愛"
         xmlns:mp="http://www.yuragi.jp/ns/manyouPoem">
<mp:poet>大伴家持</mp:poet>
<mp:yomi>なでしこがその花にもが朝な朝な手に取り持ちて恋ひぬ日なけむ</mp:yomi>
</mp:poem>

たけち: こんなふうにmp:poem要素にsendTo属性とemotion属性を追加することにするね。

さらら: これってさっきのcomplexTypeのredefineを使えばできるのじゃないかしら。

XML Schema例: 万葉歌-4: sendTo属性、emotion属性を追加
<?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:redefine schemaLocation="manyouPoem2.xsd">
<xsd:complexType name="PoemType">
<xsd:complexContent>
<xsd:extension base="mp:PoemType">
<xsd:attribute name="sendTo" type="xsd:string" />
<xsd:attribute name="emotion" type="xsd:string" />
</xsd:extension>

</xsd:complexContent>
</xsd:complexType>
</xsd:redefine>

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

</xsd:schema>

たけち: さすが、今日はさららは冴えているね。

さらら: これくらいなら、わかるわ(^ ^*)

たけち: でも、今回したかったのはこういう解じゃないんだ。間違いじゃないけれどね(^ ^;)

さらら: あれま・・・(^ ^;)

たけち: この場合は、次のように書けるんだよ。

XML Schema例: 万葉歌-4: sendTo属性、emotion属性を追加(attributeGroup)
<?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:redefine schemaLocation="manyouPoem2.xsd">
<xsd:attributeGroup name="poemAttribute">
<xsd:attributeGroup ref="mp:poemAttribute" />
<xsd:attribute name="sendTo" type="xsd:string" />
<xsd:attribute name="emotion" type="xsd:string" />
</xsd:attributeGroup>

</xsd:redefine>

さらら: なるほど、こうなるわけね。敢えて名前付き属性グループを使った意味があるわけね。

たけち: そうだね。今まで、名前付き属性グループは、綺麗にまとめて記述する手段としてだけ学んできたけれど、こんなふうに、将来改造されて再利用されることを想定して使われる場合もあるんだね。そして、名前付きモデルグループの場合も同様だよ。

さらら


■名前付きモデルグループをredefineする例

XMLデータ例: 万葉歌-5
<?xml version="1.0" encoding="Shift_JIS" ?>
<mp:poem pno="8" xmlns:mp="http://www.yuragi.jp/ns/manyouPoem">
<mp:yomi>熟田津に船乗りせむと月待てば潮もかなひぬ今は漕ぎ出でな</mp:yomi>
<mp:kana>熟田津尓 船乗世武登 月待者 潮毛可奈比沼 今者許藝乞菜</mp:kana>
</mp:poem>

XML Schema例: 万葉歌-5: 【manyouPoem5.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="poem" type="mp:PoemType" />

<xsd:complexType name="PoemType">
<xsd:group ref="mp:poemGroup" />
<xsd:attributeGroup ref="mp:poemAttribute" />
</xsd:complexType>

<xsd:group name="poemGroup">
<xsd:sequence>
<xsd:element ref="mp:yomi" />
<xsd:element ref="mp:kana" />
</xsd:sequence>
</xsd:group>


<xsd:attributeGroup name="poemAttribute">
<xsd:attribute name="pno" type="xsd:positiveInteger" use="required" />
</xsd:attributeGroup>

<xsd:element name="yomi" type="xsd:string" />
<xsd:element name="kana" type="xsd:string" />

</xsd:schema>

たけち: これのyomi要素の前に作者をあらわすpoet要素を追加しようとすると、次のように書けばいいんだよ。

XML Schema例: 万葉歌-5: 【manyouPoem5.xsd】をredefineし、poet要素を追加
<?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:redefine schemaLocation="manyouPoem5.xsd">
<xsd:group name="poemGroup">
<xsd:sequence>
<xsd:element ref="mp:poet" />
<xsd:group ref="mp:poemGroup" />
</xsd:sequence>
</xsd:group>
</xsd:redefine>


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

</xsd:schema>

さらら: あ、なるほど。派生の「拡張」では、前に追加なんてできなかったけれど、名前付きモデルグループでは可能なのね。以前「名前付きモデルグループのネスト」を勉強した際にはそれほど便利な機能だと思わなかったけれど、こうしてみると結構便利な機能だわ。

たけち: そうだね。ただし、ここで気をつけておかないといけないことは、最初から、名前付きモデルグループや名前付き属性グループを作っておかないと、こういうテクニックは使えない、ということなんだ。そういう意味では再利用を考えたら、きちんと前もって名前付きモデルグループや名前付き属性グループを使った方がいいね。

さらら: なるほど。

たけち: redefineについては、これでおしまい。次回は、「グローバル属性とグローバル属性宣言」について勉強しようね。

さらら: あっ、は〜い!!

次回は、グローバル属性とグローバル属性宣言 その1です。...... (^ ^)v

さらら


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