ヒント: XMLボキャブラリーの中で内部参照を使う

ID型またはインライン化XPathクエリーを使って、繰り返しとそれによるエラーを最小限にする

場合によっては、1つのフィールドから別のフィールドへの内部参照を使用することにより、同じデータ・フィールドの繰り返しを避けることができます。この記事でUche Ogbuji氏がその方法について説明します。

Uche Ogbuji, Principal Consultant, Fourthought, Inc.

Photo of Uche OgbujiUche Ogbuji は、次世代の Web 技術を専門とするサービスの会社である、Uli, LLC の代表者です。Ogbuji 氏は XML、RDF、およびナレッジ管理アプリケーション用のオープン・ソース・プラットフォームである 4Suite の開発リーダーであり、Versa RDF 照会言語の開発リーダーでもあります。ナイジェリア出身のコンピューター・エンジニア兼ライターで、米国コロラド州ボールダー在住です。彼に関して詳しくは、彼のブログである Copia を見てください。



2003年 3月 01日

従来のデータベース専門家がXMLについて述べる最大の批判の1つは、XMLでは階層構造のためにデータを繰り返す傾向にあるが、リレーショナル・データベースの正規化ではそれが解消される、という点です。これは確かにもっともな指摘であり、XMLが成功を収めているのは、その柔軟性と便利さがこの欠点を補って余りあるからにほかなりません。(もちろん、XMLの利点がこの欠点を上回っているように感じるのは厳密さをあまり重視しない人にとってだけである、とデータベースの潔癖主義者は主張します。)この記事では、特定のケースにおいてこの問題点を改善するのに役立つテクニックを2つほどご紹介します。しかしそれらは、XMLの階層構造から生じる制限の問題に対する一般的な解決策ではありません。

カット・アンド・ペーストをやめる

データの繰り返しは、データを再利用できるものの必ずしも再利用が必要ではない場合にしばしば発生します。その良い例は、ビジネス・パートナーの請求先住所と送付先住所です。リスト1 は、それら2つの住所データを含む顧客レコードの例です。

リスト1. 顧客レコードの例
<customer>
  <name>Bards, Inc.</name>
  <billing-address>1000 Lay Way, Burgh, UK</billing-address>
  <shipping-address>1000 Lay Way, Burgh, UK</shipping-address>
  <phone>606-217-8899</phone>
  <email>bards@angles.co.uk</email>
</customer>

この場合、billing-address (請求先住所) とshipping-address (送付先住所) は、同じ文字列です。今、このファイルが、顧客があるフォームに入力した結果であるとしましょう。それら2つの別個のフィールドの値が同じであっても、そのそれぞれにデータを入力するようになっています。これは、データの不整合エラーが発生するかもしれない典型的な例です。そのため、実際の多くのフォームでは、請求先住所だけを入力し、送付先住所は自動的に請求先住所と同じになるようにするためのチェック・ボックスが用意されています。XMLデータについても、ボキャブラリーの点で問題がない限り、それと同じようなことができます。XML 1.0では、ID型の使用によってそれが可能です。リスト2 に例を示します。

リスト2. ID型を使用して繰り返しを回避する顧客レコード書式
<!DOCTYPE customer [
  <!ELEMENT customer (name, billing-address, shipping-address,
                      phone, email
  )>
  <!ELEMENT billing-address (#PCDATA)>
  <!ATTLIST billing-address id ID #IMPLIED>
  <!ELEMENT shipping-address (#PCDATA)>
  <!ATTLIST shipping-address ref IDREF #IMPLIED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT phone (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>
<customer>
  <name>Bards, Inc.</name>
  <billing-address id="x">1000 Lay Way, Burgh, UK</billing-address>
  <shipping-address ref="x"/>
  <phone>606-217-8899</phone>
  <email>bards@angles.co.uk</email>
</customer>

ここでは、ボキャブラリーが増強されて、billing-address 要素にオプション属性id が追加されています。それは、固有ID型として定義されています。shipping-address 要素にもオプション属性ref が追加されており、こちらは固有ID型への参照として定義されています。この例では、これらの属性型を宣言するのに必要なDTDを内部サブセットに入れています。処理コードでは、それらの特殊属性を処理して、送付先住所の値を正しく導き出すための方法を知る必要があります。

もう1つの方法は、XPathを使用することによってターゲット値を参照することです。リスト3 をご覧ください。

リスト3. XPathを使用して繰り返しを回避する顧客レコード書式
<customer>
  <name>Bards, Inc.</name>
  <billing-address>1000 Lay Way, Burgh, UK</billing-address>
  <shipping-address>
    <xpath-ref select="../billing-address"/>
  </shipping-address>
  <phone>606-217-8899</phone>
  <email>bards@angles.co.uk</email>
</customer>

ここでは、特殊な要素xpath-ref をボキャブラリーに追加しています。これは、親要素をコンテキスト・ノードとして評価するXPath式を内容とする要素です。この例では、この文書のbilling-address 要素ノード名を選択しており、この部分はおそらく結果として文字列に変換されることになります。この場合も参照は処理プログラムで解決する必要がありますが、XPathを使ったこの方法は、柔軟性の点で優れています。1つの点は、XPathの機能とその他の式の機能を使用することによって、さらに複雑な値を選択できる、ということです。


まとめ

ここに示したような内部参照を使用する際には、いくらかの注意が必要です。ID方式の場合は、文書の妥当性が保たれるように注意する必要があります。また、XPath方式では、修正が加えられた場合に、当初予期したもの以外が選択されてしまうことのないようにしなければなりません。

XMLボキャブラリーを設計する際には、可能な限り繰り返しを最小限にとどめるようにしてください。それにはさまざまな方法があり、内部参照はそのための手軽な方法と言えます。

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML
ArticleID=242724
ArticleTitle=ヒント: XMLボキャブラリーの中で内部参照を使う
publish-date=03012003