XMLデータベース開発方法論(5) Page 3/4

XMLデータベース設計におけるYAGNI問題


川俣 晶
株式会社ピーデー
2005/10/14

要素と属性の使い分け

 XMLを学んだ初心者が、いざ自分で言語を考えようとして直面する問題が、「この情報は要素として書くべきなのか、属性として書くべきなのか」という混乱である。

 これについての、すっきりとした明快な答えはない。どちらを使っても大差ない状況では、どちらを選択しても問題はないということになる。しかし条件を限定すれば、指針を示すことができる場合がある。例えば、文書系のデータを記述する場合には、「タグを取り除いたとき、文書が自然に読めるように要素と属性を使い分ける」という原則がある。例えば、以下のXML断片はこの原則を満たす。

<p>この件については<a href="http://www.atmarkit.co.jp/">@IT</a>を参照してください。</p>

 ここからすべてのタグを除去すると、以下のようになってスムーズに読むことができる。

この件については@ITを参照してください。

 しかし、もしもhref属性を要素に置き換えると、この原則を満たさなくなる。

<p>この件については<a><href>http://www.atmarkit.co.jp/</href>@IT</a>を参照してください。</p>

 ここからタグをすべて抜き出すと、以下のようになり、意味をなさない。

この件についてはhttp://www.atmarkit.co.jp/@ITを参照してください。

 さて、いくつかの状況においては、両者には明確な差が発生し、正しい使い分けが生じることがある。

 まず、要素は子要素を持てるが、属性は子要素を持てないという違いがある。つまり、属性は値として文字列を持つことしかできず、そこに子要素や属性を付け加えて表現力を拡張する余地がない。例えば、個人の名前を属性に記述するXML断片があったとしよう。

<個人 名前="小泉八雲">……</個人>

 しかし、運用しているうちに、以下のような記述も可能であることが分かったとしよう。

<個人 名前="Lafcadio Hearn">……</個人>

 そして、名前がいかなる言語で書かれているかを示す情報を追加したいと思ったとしよう。しかし、属性にはそれ以上子要素も属性も付けることができない。

 もし、属性ではなく要素によって名前を記述していれば、このような問題は起こらない。

<個人>
  <名前>小泉八雲</名前>
  ……
</個人>

 名前要素に、言語を示す属性を付けることなど、たやすいことである(実際に行う場合は、「言語」属性よりもxml:lang属性を使う方がベターだろう)。

<個人>
  <名前 言語="日本語">小泉八雲</名前>
  ……
</個人>

 もう1つの決定的な相違は、順番の有無である。XMLは順番のあるデータを記述できるといわれるが、それはXMLで主として使用される要素を使う場合に当てはまる特徴である。属性には順番がなく、順番を意識したデータを属性を用いて記述することはできない。

 例えば、以下の2つのXML断片は等価であり、区別して扱えることを期待することはできない。

<どっちが先か 卵="かえる" 鶏="生む" />
<どっちが先か 鶏="生む" 卵="かえる" />

 また、1つの要素に同じ名前の属性を2つ以上持つことはできない。つまり、同じ種類の情報を列挙するような使い方に、属性は向いていない。

 以上を大まかにまとめれば、要素と属性を比較すると要素の方がより多くの機能性を持つことが分かる。もし、要素にするか属性にするか悩んだとき、特にどちらを優先すべき理由もない場合は、要素にしておくとよいだろう。

データ分割の単位

 RDBでは、データをテーブルに分割して保存することから、分割を常に意識する必要がある。テキスト形式のXML文書を扱う場合にも、分割の単位を意識する場合がある。XML文書の解析には時間がかかるために、できるだけ小さな単位で保存しておく方が有利であるという事実があると同時に、データの検索を行うためにはできるだけ多くの情報がひとまとまりになっている方がやりやすいという事実もあるためである。

 XMLデータベースにおいては、データを分割する単位を意識する必然性はほとんどない。特別の理由がない限り、必要なデータはすべて1つのデータベースの1つのツリー構造に格納すればよいのである。

 このような問題を非常に単純化してくれるのが、XMLデータベースの特徴の1つといえるだろう。

混合内容の使い方

 XMLの要素の内容には、大ざっぱに分類すると、以下の4種類があり得る。

  • 要素(子要素)だけを置く
  • テキストだけを置く
  • 要素とテキストの双方を置く
  • 何も置かない(空要素)

 このうち、「要素とテキストの双方を置く」というのが、混合内容である。混合内容は、文章系の用途では必須といえる重要な機能である。例えば、以下のようなXML断片を記述できるのは、混合内容があればこそである。

<段落>台風一過、<強調>猛暑</強調>到来</段落>

 この場合、段落要素の内容には、「台風一過、」というテキスト、強調要素、「到来」というテキストの3つが含まれることになる。

 しかし、連続性のないデータを集めて記述する場合には、混合内容は扱いにくい場合があるので、避けた方がよい。

 その一例を以下に示す。例えば、以下のようなXML断片があったとする。

<人物>野原ひろし</人物>

 ここに、後から役職である「係長」という情報を付加したいと思ったとしよう。もし、属性を使わないとすれば、混合内容を使い、人物要素の子要素に役職要素を追加するという方法があり得る。

<人物>野原ひろし<役職>係長</役職></人物>

 しかし、このような構造を持たせると、クエリにより人名だけを含む要素を選択する手段がなくなってしまう。例えば、内容に「野原ひろし」という文字列を含む人物要素をクエリによって選択したとすると、その要素には常に役職要素が付いてきてしまう。この要素の内容からテキストのみ抜き出して処理しようとすると「野原ひろし係長」という文字列が得られ、これは意図した情報ではない。

 これを回避するには、名前要素を導入し、混合内容を回避すればよい。

<人物>
  <名前>野原ひろし</名前>
  <役職>係長</役職>
</人物>

 このように記述すれば、内容に「野原ひろし」という文字列を含む名前要素をクエリによって選択することができ、その要素は値に役職要素を含まない。

 もう1つ、混合内容の悩ましいところは、これが基本的にどの位置にテキストを記述してもよい点にある。例えば、混合内容では以下のように記述することも可能であるが、これを「野原ひろし」という一続きの名前を記述したと見なすか否かは悩ましい問題を引き起こす。

<人物>野原<役職>係長</役職>ひろし</人物>

 このようなタイプの問題を引き起こすことがあるので、混合内容はそれを使用する正当な理由がある場合を除き、避けておく方がよいだろう。(次ページへ続く)

3/4

 Index
XMLデータベース開発方法論(5)
XMLデータベース設計におけるYAGNI問題
  Page 1
・前回のおさらいと今回のテーマ
・IDの付与
・順序のあるデータ、ないデータ
・数値の活用
  Page 2
・列挙型の活用
・名前空間を使う
・既存ボキャブラリ(語い)の活用
Page 3
・要素と属性の使い分け
・データ分割の単位
・混合内容の使い方
  Page 4
・無限詳細化とYAGNI
・なぜXMLデータモデルに固執するのか
・次回予告


XMLデータベース開発論


Database Expert フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Database Expert 記事ランキング

本日月間