レコードデータとXML要素の相互変換(むしろ相互解釈)について述べる。い くつかの方法/事例を列挙するが、それらの優劣を論じることはしない。
「XML要素をレコードとして解釈したい」、あるいは逆に 「レコードをXML構文でエンコードしたい」という要望がある。だが、要素の レコード解釈(あるいはレコードの要素解釈)が一意的に決まるわけではない。 要素-レコード対応は複数ありえるし、それらの対応に絶対的な優劣はない。
この記事では、要素-レコード対応の例をいくつか出して、それらを比較して みることにする。
名前・値ペア(name-value pair)をいくつか集めたデータを‘レコード’と 呼ぶ。レコードを構成している個々の名前・値ペアを‘フィールド’と呼ぶ。 レコードは、構造体、(RDBテーブルの)行(ロウ)、素性構造、プロパティ セットなどとも呼ばれる。使える名前(キー)を実行時に変更できるなら、マッ プと呼ぶこともある。その他にも、このようなデータ構造の呼び名があるかも しれないが、ここでは、細かい差異は無視して一律に「レコード」「フィール ド」という言葉を使うことにする。
レコードの型を定義・記述するには、次の形式を使う。
record Person { date birthDate; string givenName; string familyName; }
XMLの要素をレコードとみなすとき、属性名をフィールド名、属性値をフィー ルド値に対応させる事には異論は少ない。だが、XML要素は属性だけで出来上 がっているわけではない。要素にはタグ名と内容がある。したがって、タグ名 と内容をどのようにレコードにマップするかは意見が別れる。
本記事では特に、タグ名に対する次の3つの解釈を取り上げて論じる。
この3つの解釈を簡単に解説した後で、その他の問題点も取り上げる。
例として出したPerson型レコードに対して、次のようなXML表現を 考えることは自然である。
<Person date birthDate="1976-09-11" givenName="健夫" familyName="園部" />
この場合、型の名前がタグ名によりエンコードされていることになる。した がって、タグ名により型の判別ができ、その型を定義する規則(スキーマ)と の照合も可能である。
要素内容は無名のフィールドとなるが、例えば#contentのような特殊な名前 を持つフィールドと解釈すれば、内容に対する制限も型定義に含めることができる。
record Person { date birthDate; string givenName; string familyName; string #content; /* 自由にコメントを書いてよい */ }
あるいは、通常のフィールドと同様に名前を持たせ、そのフィールドが内容に マップされることをアノテーション(ここでは@Contentとする)で示してもよ い。
record Person { date birthDate; string givenName; string familyName; string @Content comment; }
タグ名もデータとして使われることもある。例えば次のように。
<園部健夫 生年月日="1976-09-11">釣りと盆栽が趣味です。</園部健夫>
この例のようなマークアップは“好ましくない”とされているが、現実には使わ れることもある。このケースでは、タグ名も一種のフィールドとみなすしか ない。タグ名を値とするフィールドのフィールド名を#tagNameとしよう。 すると、次のような型定義ができる。
record Person { Name #tagNmae; /* 人の名前 */ date birthDate; string givenName; string familyName; string #content; /* 自由にコメントを書いてよい */ }
あるいは、アノテーション@TagNameを使ってみれば、次のような定義となる。
record Person { Name @TagName name; date birthDate; string givenName; string familyName; string @Content comment; }
このマークアップでは、型名がXMLインスタンスにエンコードされないので、 環境から型情報を得るしかない。
もう一度次の例を考える。
record Person { date birthDate; string givenName; string familyName; string @Content comment; }
型定義の段階では存在するフィールド名commentは、XMLインスタンスでは消 えてしまう。そこで、タグ名を内容に対する名前(キー)として使うなら、次 のようなマークアップとなる。
<comment birthDate="1976-09-11" givenName="健夫" familyName="園部">釣りと盆栽が趣味です。</comment>
上の事例では、かなり不自然な印象があるが、次ならひどい違和感はないだろう。
<comment personName="園部健夫">釣りと盆栽が趣味です。</comment>
<Person> <birthDate>1976-09-11</birthDate> <givenName>健夫</givenName> <familyName>園部</familyName> </Person>
この方式では、親のタグ名は型名を表している(と思える)が、子のタグ名 はフィールド名に対応する。つまり、親と子ではタグ名の解釈が異なる。もっ とも、要素は単一のフィールドで、Personがフィールド名、内容はレコードデー タを記述しているという解釈もできなくはない(そのとき、型名はエンコード されない。)
以上の事例から、フィールド(名前と値)のXMLへのマッピング法は次 のように分類できそうである。
レコードの型名をXMLインスタンスに埋め込むには、次の方法があり得る。
要素の型を知るには、次の方法があり得る。