リーフセパレーションアルゴリズムは Dunbundle, Dtieおよび DtoXml で使われ, Dレコード中におけるリピーティンググループを 見つける。 リーフフィールドリストは特定フィールドリスト の一種で,リピーティンググループをなすフィールドを 指定するために使用する。
Dレコードの中で階層的な木構造をインプリシットに表現することができる。 この場合,上位階層に属するフィールドを「ステムフィールド」, 下位階層に属するフィールドを「リーフフィールド」とよぶ。
木構造のできる典型的な場合として, Dbundle コマンドによって,同一キー値のDレコードを束ねた場合がある。 この場合,キーフィールドがステムフィールドとなり, キー以外ののフィールドがリーフフィールドとなる。
例1:
a:A
b:1
a:A
b:2
a:A
b:3
これら3つのレコードを,Dbundle aコマンドで フィールド"a"をキーとして束ねると,次のレコードになる:
a:A
b:1
b:2
b:3
フィールド"a"がステムフィールドとなり, フィールド"b"がリーフフィールドとなる。 あるいは,ステム a:Aと3つのリーフ b:1, b:2 and b:3 があるといっても良い。
上記の例では1個のリーフフィールドがリピートしている。 一般的にはリーフフィールドは,2個以上のフィールドが 組になってリピートするリピーティンググループをなす。 次の例を見よ。
例 A:
house:Plantagenets
name:Henry II
reign:1154-89
name:Richard I
reign:1189-99
name:John
reign:1199-1216
name:Henry III
reign:1216-72
この例では,"house"がステムフィールドで,"name"と"reign" とがリーフフィールドである。リーフフィールドが リピーティンググループとなっている。 リーフが1人の王のエントリをなしていることは容易にわかるだろう。 このように各リーフが必ず"name"と"reign"をこの順で持っている場合, 話は単純である。 "name"と"reign"フィールドのペアを端から取り出していけば, 個々のリ−フとなる。
しかし,実際のデータではほかにも情報を加えたいということはよくある。 たとえば:
例B:
house:Plantagenets
name:Henry II
reign:1154-89
name:Richard I
byname:Lion-Heart
reign:1189-99
name:John
byname:Lackland reign:1199-1216
name:Henry III
reign:1216-72
別称(byname)が何人かに加えられている。 この場合でも,個々のリーフはフィールド"name"で始まる というルールにより識別できる。
Dのバンドリング演算(Dbundle)は, 一般的にいえば可逆ではない。 しかし,上記A,Bに示したように多くの場合 何らかの方法(アルゴリズム)によって個々のリーフを 再グループ化することが可能であり,この場合には バンドリング演算は可逆といえる。 このアルゴリズムをリーフセパレーションアルゴリズムと呼ぶ。
個々のリーフを示すための記法を導入する。
a:A
b:1 l1
b:2 l2
b:3 l3
"l"のついたフィールドがリーフで, 後ろに続く数値が個々のリーフの順番を示す。 マークの付いていないフィールドはステムフィールドである。
Dレコードの中の木構造を見つけるには 2つの情報が必要である。 ひとつはどのフィールドがリーフとなるかを示すリーフフィールドリストで, もうひとつはそれらのフィールドを個々のリーフに分離する方法を与える リーフセパレーションアルゴリズムである。 このアルゴリズムには汎用的なものから特定用途のものまで多くのものがあり得る。 現在のDコマンドでは単純であるが実用的な3つのアルゴリズムを用意してある。 N-thオカレンス, リーディングフィールドおよび シーケンスブレークである。
リーフフィールドリストは,リーフとなるフィールド名を並べたリストであるが, オプションで"*"をつけることができる。 これはリーフの中でそのフィールドが繰り返しよいことを示す。
リーフフィールドリストの構文は,フィールドフォーマットリストの サブセットで,"*"だけが意味を持つ。 Dtieコマンドでは フィールドフォーマットリスト(出力)が同時に リーフフィールドリストとしても使われる。command, the
リーフフィールドリストは排他フィールドリストでも良い。 ただし,この場合N-thオカレンスアルゴリズム以外は使えない。
これが省略時のリーフセパレーションアルゴリズムである。 -Nオプションが指定されるか, 他のアルゴリズムが指定されないと,このアルゴリズムが使われる。
このアルゴリズムでは,各リーフフィールドのN番目の値が N番目のリーフに属する。 このアルゴリズムが有効なのは個々のリーフ中で各リーフフィールドが 必ず1つづつ存在する場合である。 上記例1は,このアルゴリズムで元に戻すことができる。 個々のリーフ中でのフィールドの繰り返しは許されないため, "*"は指定できないが,指定してあっても無視される。
例2: -N "b,c"
a:A
b:1 l1
b:2 l2
c:3 l1
c:4 l2
-Lを指定するとこのアルゴリズムが使われる。 リーフフィールドの先頭のフィールドが「リーディングフィールド」となる。 Dレコード中でリーディングフィールドが現れると,新しいリーフがはじまる。
例3: -L "b,c"
a:A
b:1 l1
b:2 l2
c:3 l2
c:4 l2
リーディングフィールドが繰り返し可能なとき, リーディングフィールドが続けて現れても,新しいリーフの開始にはならない。 (ステムフィールドは,アルゴリズムに影響しない。 ステムフィールドがリーフフィールドや,連続するリーディングフィールドの 間に挟まってもかまわない。)
例4: -L "b:*,c"
a:A
b:1 l1
b:2 l1
c:3 l1
c:4 l1
リーディングフィールド以外に"*" があっても無意味で,単に無視される。
例5: -L "b:*,c:*"
a:A
b:1 l1
a:2
b:3 l1
c:4 l1
a:5
c:6 l1
Dレコード中で最初のリーフフィールドの現れが リーディングフィールドでなかった場合も, そこから最初のフィールがはじまる。
例6; -L "b,c"
a:A
c:1 l1
b:2 l2
c:3 l2
b:4 l3
リーディングフィールドアルゴリズムでは,排他フィールドリストは禁止される。 (何がリーディングフィールドとなるかわからないため。)
-Sを指定するとこのアルゴリズムが使用される。 与えられたDレコード中のフィールフィールド順がリーフフィールドリストで与えられた順序と 一致しなくなったときに,新しいリーフの始まりとする。 フィールドエントリにリピートマークがない場合,同一フィールドの繰り返しは 順序の不一致となる。
例7;
-S "b,c" | -S "b:*,c" | -S "b,c:*" | -S "b:*,c:*" | |
a:A | ||||
b:1 | l1 | l1 | l1 | l1 |
b:2 | l2 | l1 | l2 | l1 |
c:3 | l2 | l1 | l2 | l1 |
c:4 | l3 | l2 | l2 | l1 |
ステムフィールドが間に入っても,リーフフィールド順に関係はしない。 また,排他フィールドリストは,リーフフィールド順を与えることができないので, このアルゴリズムでは使えない。
MIYAZAWA Akira