- PR -

別々のXMLのelementの関係付け方法

投稿者投稿内容
豪雪地帯
常連さん
会議室デビュー日: 2004/06/08
投稿数: 34
投稿日時: 2004-09-27 17:04
XML初心者です。
ある要素elementの値が別のXMLの方で定義されている、という関係をXMLスキーマに
記述できないでしょうか。

例えば、
<bookorder>
<bookid>112233</bookid>
</bookorder>


<bookmaster>
<bookinfo>
<isbn>111111</isbn>
<price>2500</price>
</bookinfo>
<bookinfo>
<isbn>112233</isbn>
<price>3600</price>
</bookinfo>
<bookinfo>
<isbn>223344</isbn>
<price>1500</price>
</bookinfo>
</bookmaster>

の2つの別々のXMLが存在する時、
「bookorderのbookidは、bookmasterのisdnである。」
というような関係をbookorder側のXMLスキーマに記述できないでしょうか。

XLinkとかXPointerとも違うように思います。

よろしくお願いします。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2004-09-27 23:24
XMLドキュメント確認用のXSDの制限で挫折した?
Schematron(スキマトロン)を試みてください
http://www.excite.co.jp/world/english/web/body?wb_url=http://msdn.microsoft.com%2Fxml%2F&wb_lp=ENJA&wb_dis=3

 RELAXとSchematronの組合わせはとても良いですね。
 RELAXは、ボキャブラリの物理構造を定めたスキーマとなりますが、この上
位層にアプリケーション上の意味まで踏み込んだスキーマが必要になってきま
す。
 Shcematronというアプローチも良い感じですし、
http://www2.xml.gr.jp/log.html?MLID=relax-users-j&N=1949

XMLSchema でできない範囲をカバーする 検証用言語は いろいろあるようです。
==============================================================

データ構造というより 制約・関連の記述ですから
データモデリング・UML RDF とかの 領域でしょうか
MS の拡張あたりに ありそうな気もしますが、どうでしょう
============================
また、スキーマ記述するだけでなく、サンプルのXMLを当てて
ちゃんと検証ができるか?も確認したほうが、良いとおもいます。
早い段階から

[ メッセージ編集済み 編集者: MMX 編集日時 2004-09-29 12:37 ]
豪雪地帯
常連さん
会議室デビュー日: 2004/06/08
投稿数: 34
投稿日時: 2004-09-28 14:48
MMXさん、ありがとうございます。
しかし、私には難しいです。

でも、やりたかったことが、keyとkeyref指定で出来そうだという事が分かりました。
今まで、"関連"というのに捕らわれていてXLinkとかXPointerとか、リンクの方法を
考えていましたが、それは誤りでした。

上記の例を、ひとつのスキーマの中での定義として記述してみました。
チェックはしていないので、誤った所があるかも知れません。

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

<xsd:element name="books" type="booksType">

<xsd:complexType name="booksType">
<xsd:sequence>
<xsd:element ref="bookorder" />
<xsd:element ref="bookmaster" />
</xsd:sequence>
</xsd:complexType>

<xsd:element name="bookorder">
<xsd:complexType>
<xsd:element name="bookid" type="xsd:string" />
</xsd:complexType>
</xsd:element>

<xsd:element name="bookmaster">
<xsd:complexType>
<xsd:element name="bookinfo">
<xsd:complexType>
<xsd:element name="isbn" type="xsd:string" />
<xsd:element name="price" type="xsd:nonNegativeInteger" />
</xsd:complexType>
</xsd:element>
</xsd:complexType>
</xsd:element>

<xsd:key name="book-isdn"> ・・・(1)
<xsd:selector xpath="bookmaster/bookinfo" />
<xsd:field xpath="isbn" />
</xsd:key>

<xsd:keyref name="book-id" refer="book-isdn"> ・・・(2)
<xsd:selector xpath="bookorder" />
<xsd:field xpath="bookid" />
</xsd:keyref>

</xsd:schema>

(1)で"isbn"の一意性を表し、(2)で"bookid"は"isbn"を参照する、という
つもりなんですが、合っているでしょうか。

合っているのを前提に、"bookorder"スキーマと"bookmaster"スキーマが
別々のスキーマ(名前空間?)の時の定義にも挑戦してみようと思います。

ご教唆よろしくお願いします。
TAKABE
常連さん
会議室デビュー日: 2003/05/14
投稿数: 43
投稿日時: 2004-09-28 16:50
 豪雪地帯様、こんにちは。
 上記スキーマを添削すると、以下のようになります。

1.<xsd:element name="books" type="booksType">
 が閉じられておらず、Well-formedになっていません。

2.<xsd:element name="bookorder">
  <xsd:complexType>
 の直接の子要素として<xsd:sequence>等が必要です。

3.<xsd:element name="bookmaster">
  <xsd:complexType>
 の直接の子要素として<xsd:sequence>等が必要です。

4.<xsd:element name="bookinfo">
  <xsd:complexType>
 の直接の子要素として<xsd:sequence>等が必要です。

5.<xsd:key>や<xsd:keyref>は<xsd:element>の子要素でなくてはなりません。

 以上、5点の間違いを修正すると以下のようになります。

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

<xsd:element name="books" type="booksType">

<xsd:key name="book-isdn">
<xsd:selector xpath="bookmaster/bookinfo" />
<xsd:field xpath="isbn" />
</xsd:key>

<xsd:keyref name="book-id" refer="book-isdn">
<xsd:selector xpath="bookorder" />
<xsd:field xpath="bookid" />
</xsd:keyref>

</xsd:element>

<xsd:complexType name="booksType">
<xsd:sequence>
<xsd:element ref="bookorder" />
<xsd:element ref="bookmaster" />
</xsd:sequence>
</xsd:complexType>

<xsd:element name="bookorder">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="bookid" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:element name="bookmaster">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="bookinfo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="isbn" type="xsd:string" />
<xsd:element name="price" type="xsd:nonNegativeInteger" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

</xsd:schema>
TAKABE
常連さん
会議室デビュー日: 2003/05/14
投稿数: 43
投稿日時: 2004-09-28 17:58
 追伸です。
 上記の修正スキーマは、あくまでその上のスキーマの明らかな間違いを修正しただけのものであって、それが豪雪地帯さんが設計したいスキーマのとおりになっているかはまた別問題です。
 例えば冒頭に出てきたインスタンスでは<bookinfo>が複数出現し、それからまた類推すると<bookorder>や<bookid>も複数出現することも想像できたのですが、上記スキーマではそのどれもが1回しか出現しません。豪雪地帯さんが設計したいスキーマが何なのかを知る情報が存在しなかったので、このあたりは敢えて踏み込まなかったところです。あしからず。
豪雪地帯
常連さん
会議室デビュー日: 2004/06/08
投稿数: 34
投稿日時: 2004-09-29 10:17
TAKABEさん、添削ありがとうございます。感謝です。
また追伸でおっしゃっている通り、出現回数については1回ではありません。
そこで、下記(1)(2)のように修正してみました。(掲載は修正の関係範囲のみ)

<xsd:element name="bookorder">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="bookid" type="xsd:string" maxOccurs="unbounded" />・・・(1)
</xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:element name="bookmaster">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="bookinfo" maxOccurs="unbounded">・・・(2)
<xsd:complexType>
<xsd:sequence>
<xsd:element name="isbn" type="xsd:string" />
<xsd:element name="price" type="xsd:nonNegativeInteger" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

ところで、追伸では、<xsd:element name="bookorder"> のタグ自体にも
maxOccurs="unbounded"を付けた方が良いと読み取れますが、子要素の
bookidにmaxOccurs="unbounded"を付けているので、要らないようにも
思えます。どのように判断したら良いのでしょうか。

また、添削結果への質問をさせてください。
Q1.sequence指定は必須なのでしょうか。elementが1つしかない場合や、
 順序を問わない場合は要らないと思っていました。

Q2.「<xsd:element name="books" type="booksType"> が閉じられていない」
 との事ですが、keyとkeyref指定が追加になったので閉じる必要が出たのだと
 思いますが、いかがでしょうか。

添削の5については知りませんでした。記述していて関係が今いち分かりにくいな、
と思ってたので納得です。
豪雪地帯
常連さん
会議室デビュー日: 2004/06/08
投稿数: 34
投稿日時: 2004-09-29 10:43
追伸です。

出現回数ですが、"最低1回以上で上限無し"のつもりなのですが、その場合は
minOccurs="1" も合わせて指定しないといけないのでしょうか。
下記のmaxOccurs属性の説明では、unboundは最低1回以上、と説明されています。

参考:SEのためのXML入門(3)
htp://www.atmarkit.co.jp/fxml/rensai2/schema03/schema03.html

[ メッセージ編集済み 編集者: 豪雪地帯 編集日時 2004-09-29 10:51 ]
TAKABE
常連さん
会議室デビュー日: 2003/05/14
投稿数: 43
投稿日時: 2004-09-29 11:36
 豪雪地帯さま、こんにちは。

>ところで、追伸では、<xsd:element name="bookorder"> のタグ自体にも
>maxOccurs="unbounded"を付けた方が良いと読み取れますが、子要素の
>bookidにmaxOccurs="unbounded"を付けているので、要らないようにも
>思えます。どのように判断したら良いのでしょうか。

 私が余分なことを言ったために混乱をおこされたようで申し訳ありません。これは「スキーマの文法」の問題ではなくて、豪雪地帯さまがどういうXMLを使いたいかという「XMLの設計運用コンセプト」の問題です。私は単に「本のオーダーなんて、いくつもあるのではないかなぁ…」と「類推」しただけです。豪雪地帯さまがこのXMLをどのようなシステム設計の中で位置付けているかなどは私にはわかりませんから、豪雪地帯さまがこれで良いと思われたなら、それで良いのだと思います。私が少し余分なことを言い過ぎました。すみません。

>Q1.sequence指定は必須なのでしょうか。elementが1つしかない場合や、
> 順序を問わない場合は要らないと思っていました。

 豪雪地帯さまは要らない(省略できる)と思われたそうですが、W3Cの仕様
http://www.w3.org/TR/xmlschema-1/
 には、きちんと

<!ELEMENT %complexType; ((%annotation;)?, (%simpleContent;|%complexContent;|%particleAndAttrs;))>

<!ENTITY % particleAndAttrs '((%mgs; | %group;)?, %attrDecls;)'>

<!ENTITY % mgs '%all; | %choice; | %sequence;'>

 などと書かれていますし、W3Cの仕様上、省略不可ですね。

>Q2.「<xsd:element name="books" type="booksType"> が閉じられていない」
> との事ですが、keyとkeyref指定が追加になったので閉じる必要が出たのだと
> 思いますが、いかがでしょうか。

 それは違います。これはスキーマの文法的問題ではなくて、XMLの基本的仕様の問題で、開いたタグは必ず閉じられないとXMLとして成り立ちません。(XMLはWell-formedの条件を満たしていないといけないということです) 例えばこの場合、もしkeyとkeyrefが追加にならなかった場合は、

<xsd:element name="books" type="booksType" />

 と書かなければなりません。

>添削の5については知りませんでした。記述していて関係が今いち分かりにくいな、
>と思ってたので納得です。

 はい、これが定義されている要素がkeyやkeyrefの有効範囲となりますし、またkeyやkeyrefで使われるselectorのXPathは、ここを起点としないと記述のしようがありません。その意味では、要素との関係なくしてはkeyやkeyrefは定義できないものなのです。

>出現回数ですが、"最低1回以上で上限無し"のつもりなのですが、その場合は
>minOccurs="1" も合わせて指定しないといけないのでしょうか。

 minOccursおよびmaxOccursは、その値が1である場合は、その記述自体を省略可能です。別に書いてもかまいませんが、省略可能なものは省略した方が省力的かな…と(^^;)

スキルアップ/キャリアアップ(JOB@IT)