まず、本実施例で使用するXML(Extensible Markup Language)データについて説明する。図1は、XMLデータのデータ構造の一例を示す図である。同図に示すように、このXMLデータは、要素識別子「<」、「</」等により要素が区切られた階層構造を有している。そして、図1のXMLデータの木表現は、図2のように表すことが出来る。
図2は、XMLデータの木表現の一例を示す図である。同図に示すように、XMLの木構造では、XMLデータはノードID1,3,4,5,7,9,10,12,13,14,16,18,19,21,22,23,25の要素ノードと、ノードID2,6,8,11,15,17,20,24,26のテキストノードとを有し、それぞれの要素ノード、テキストノードをそれぞれ接続している。例えば、要素ノードのSyain1は、テキストノードの「シグマ戦隊中原ジャー」2、要素ノードのACT3,12,21に接続されている。
そして、XPath(XML Path Language)クエリ(以下、クエリと表記する)を指定することによって、上記のXMLデータからクエリの照合位置のデータを検出することが可能となる。なお、W3C(World Wide Web Consortium)によるクエリのサブセット(W3CによるXPath2.0のサブセット)は、下記のように定義される。
Path::="/"RPath
RPath::=Step("/"Step)*
Step::=Axis"::"Ntest("["Pred"]")*
Axis::="child"
Ntest::=tagname|"*"|"text()"|"node()"
Pred::=Expr|Expr"and"Expr| Expr"or"Expr|"not"Expr
Expr::=RPath|func"("RPath")"
ここで、「tagname」は、任意のタグ名を表すものとする。また、「func」は、データ中の各ノードに0または1を割当てる関数とする。すなわち、XMLデータのノード集合をVとすると、func:Vは、{0,1}となる。
例えば、クエリが、
Q=/Syain/ACT[cast/name]/chara[id]/name
と指定された場合には、図2の要素ノードname7,16が指定箇所となり、指定箇所に対応したデータを取得することが出来る。図3は、上記クエリによって取得するデータを示す図である。図3に示すように、クエリ「Q=/Syain/ACT[cast/name]/chara[id]/name」により、XMLデータから「<name>シグマレッド</name>」「<name>シグマブルー</name>」を取得することが出来る。なお、上記クエリの[]は制約条件を表し、例えば、ACT[cast/name]は、配下にcast/nameを有するACTを示すものであり、chara[id]は、配下にidを有するcharaを示す。
次に、クエリを評価する従来技術(例えば、TwigList[Qin et al.; DASFAA'07])について説明する。図4は、従来技術を説明するための図である。ここでは説明の便宜上、XMLデータ10aの木構造を図4の左上に示す木構造とし、クエリを「Q=/a[b]c[d]e」とする(クエリの木構造は、図4の左下参照)。また、XMLデータ10aの各ラベルa〜eに付した番号は、ノードIDとする。
従来技術では、まず、XMLデータ10aをスキャンして、クエリを評価するための階層リストを構築する。図4の右側に示す階層リストは、XMLデータ10aの階層リストを示す。この階層リストは、XMLデータ10aの各ラベルa〜eに対応したList_a〜List_eを有する。そして、List_a〜List_eは、XMLデータ10aのラベルに付されたノードIDを保持すると共に、XMLデータ10aに対応して接続している。
具体的には、List_aは、ノードID「1」を保持し、List_bは、ノードID「2,5」を保持し、List_cは、ノードID「3,6」を保持し、List_dは、ノードID「4,7」を保持し、List_eは、ノードID「8,9」を保持している。
そして、List_aのノードID「1」は、List_bのノードID「2,5」、List_c「3,6」に接続されている。また、List_cのノードID「3」は、List_dのノードID「4」に接続され、List_cのノードID「6」は、List_dのノードID「4」およびList_eのノードID「8,9」に接続されている。
次に、従来技術では、階層リストをスキャンして、クエリの埋め込みを求める。クエリ「Q=/a[b]c[d]e」の埋め込みを求めると、かかるクエリの条件にヒットするノードID列は、(1,2,6,7,8)、(1,2,6,7,9)、(1,5,6,7,8)、(1,5,6,7,9)となる。
ここで、(1,2,6,7,8)と(1,5,6,7,8)との照合箇所は、ノードID「8」となり、(1,2,6,7,9)と(1,4,6,7,9)との照合箇所は、ノードID「9」となるので、クエリ「Q=/a[b]c[d]e」の埋め込みによって得られる文脈ノードは、ノードID「8,9」となる。
ところで、従来の技術では、例えば、階層リスト中のList_bのように、同一のラベルに複数のノードIDが含まれている場合には、List_bに保持されたノードIDの数だけクエリのスキャンを無駄に繰り返し実行する必要がある。階層リストを構成するListに複数のノードIDが含まれるということは、XMLデータで言えば、同じラベルを持つ節点が、同一兄弟中に複数含まれることと同じである(例えば、XMLデータ10aのノードID2のノードと、ノードID5のノードとを参照)。
すなわち、階層リストをスキャンして、クエリ「Q=/a[b]c[d]e」の埋め込みを求める場合に、例えば、List_bに含まれるノードID「2」を参照した時点で、List_aに含まれるノードID「1」の制約条件(ここでは、Q=/a[b]までの制約条件)を満たすことが確定するので、List_bのノードID「5」を再度参照することに意味が無く、計算効率が悪いという問題があった。
次に、本実施例にかかる検索装置の概要および特徴について説明する。図5は、本実施例にかかる検索装置の概要および特徴を説明するための図である。ここでは説明の便宜上、XMLデータおよびクエリは、図5に示したXMLデータ10aとクエリ「Q=/a[b]c[d]e」とを用いて説明する。
図5に示すように、本実施例にかかる検索装置は、従来技術の階層リストを作成する代わりに、クエリの述部(制約条件)に対応するXMLデータの述部ノード(制約条件を満たしているか否かを確認する部分)を「真」または「偽」によって表したイベント木を作成することで、クエリの埋め込みを求める場合の計算効率を向上させる。
ここで、イベント木に含まれる「真」は、クエリの制約条件を満たしている旨を示すフラグであり、「偽」は、クエリの制約条件を満たしていない旨を示すフラグである。例えば、図4のList_bに保持されたノードID「2,5」は、Q=/a[b]までの制約条件を満たしているので、List_aのノードID「1」に接続されるList_bを、bit_b「真」とする。
また、図4のList_dに保持されたノードID「4」は、Q=/a[b]c[d]までの制約条件を満たしているので、List_cのノード「3」に接続されるList_dを、bit_d「真」とする。また、図4のList_dに保持されたノードID「7」は、Q=/a[b]c[d]までの制約条件を満たしているので、List_cのノード「6」に接続されるList_dを、bit_d「真」とする。なお、図5のイベント木に含まれる「.」は、ノードの終端を示すものである。
本実施例にかかる検索装置は、図5に示すイベント木を作成した後に、イベント木をスキャンして、クエリの埋め込みを求める。具体的に、図5に示すイベント木を用いて、クエリ「Q=/a[b]c[d]e」の埋め込みを求める処理を説明する。まず、検索装置は、List_aに移行し、bit_bを参照すると、「真」であるため、List_cに移行する。
そして、検索装置は、ノードID「3」の配下に接続されたbit_dを参照すると、「真」であるが、ノードID「3」は「.」に接続されているため(終端ノードであるため)、ノードID「6」に移行する。
検索装置は、ノードID「6」に移行し、bit_dを参照すると、「真」であるため、List_eに移行する。List_eに含まれるノードID「8,9」には接続先が無いため、ノードID「8,9」がクエリ「Q=/a[b]c[d]e」の指定箇所(文脈ノード)となる。
図5に示す例では、全て「真」の場合について説明したが、Listの配下に接続された
bitが「偽」の場合には、そのList以降のスキャンはスキップされることになる。例えば、図5のbit_bに「偽」が登録されている場合には、List_a以降のスキャンは中断される。
このように、本実施例にかかる検索装置は、各List_a〜eが制約条件を満たしているか否かを配下に接続されたbitの「真」または「偽」を一度参照し、参照結果に基づいて、該当List以降のスキャンを継続する、あるいは中断することで、照合箇所を判定するので、図4で説明した従来技術のように複数回スキャンを無駄に繰り返す必要がなくなり、計算効率を向上させることが出来る。
図6は、従来技術と比較した本実施例にかかる検索装置の効果を説明するための図である。ここでは説明の便宜上、XMLデータ10bの木構造を図6の左上に示す木構造とし、クエリを「Q=/a[b]c[d]e」とする(クエリの木構造は、図6の左下参照)。また、XMLデータ10bの各ラベルa〜eに付した番号は、ノードIDとする。
図6の右上に示す階層リストは、図4の場合と同様にしてXMLデータ10bをスキャンして構築された階層リストである。図6の右下に示すイベント木は、図5の場合と同様にして、階層リストの代わりに作成されたイベント木である。
図6の階層リストでは、List_bに複数のノードID「2,3,4,5」(4通り)が含まれており、List_dに複数のノードID「9,10,11,12」(4通り)が含まれているので、List_bとList_dとの組合せにより、同じ指定箇所「ノード13」を得るために、16回スキャンする必要がある。
一方、図6のイベント木では、述部ノード(制約条件を満たしているか否かを確認する部分)をまとめて「真」または「偽」によって表現しているので、XMLデータ10bに対するクエリ「Q=/a[b]c[d]e」の解は1つだけとなり、図6の階層リストのように複数回スキャンを実行する必要がなくなる。
XMLデータのデータサイズをn、クエリサイズをqとすると、従来技術の計算量は、O(q・nq)となり、本実施例にかかる検索装置の計算量は、O(q・n)となる。すなわち、クエリサイズqが大きくなればなるほど、従来技術と比較して本実施例にかかる検索装置の計算量が格段に少なくなる。また、XMLデータに含まれる同一ラベルの節点が、同一兄弟中に大量に出現する場合には、従来技術では、解候補の組合せが増加するが、本実施例の検索装置の解は一つのままなので、計算効率を向上させるという効果が特に大きくなる。
次に、本実施例にかかる検索装置の構成について説明する。図7は、本実施例にかかる検索装置の構成を示す機能ブロック図である。図7に示すように、この検索装置100は、入力部110と、出力部120と、通信制御IF部130と、入出力制御IF部140と、記憶部150と、制御部160とを有する。なお、この検索装置100は、ネットワークを介して端末装置(図示略)に接続しているものとする。
このうち、入力部110は、各種の情報を入力する入力手段であり、キーボードやマウス、マイクなどによって構成され、例えば、上述したXMLデータに関する各種の情報を受け付けて入力する。なお、後述するモニタ(出力部120)も、マウスと協働してポインティングデバイス機能を実現する。
出力部120は、各種の情報を出力する出力手段であり、モニタ(若しくはディスプレイ、タッチパネル)やスピーカなどによって構成され、例えば、上述したXMLデータに関する各種の情報を出力する。
通信制御IF部130は、端末装置(図示略)との間における通信を制御する手段である。入出力制御IF部140は、入力部110、出力部120、通信制御IF部130、記憶部150、制御部160によるデータの入出力を制御する手段である。
記憶部150は、制御部160による各種処理に必要なデータおよびプログラムを記憶する記憶手段(格納手段)であり、特に本発明に密接に関連するものとしては、図7に示すように、XMLデータ150a、パスIDテーブル150b、BINデータ150c、イベント定義表150e、イベント列データ150e、イベント木データ150fを格納する。
このうち、XMLデータ150aは、上述したように要素識別子「<」、「</」等により要素が区切られた階層構造を有する文書データである(図1参照)。パスIDテーブル150bは、XMLデータ150aに含まれるパスとパスID(Identification)とを対応付けたデータである。
図8は、パスIDテーブルのデータ構造の一例を示す図である。図8に示すように、このパスIDテーブル150bでは、パスとパスIDとが対応付けられており、例えば、パス「/Syain」は、パスID「1」に対応付けられている。
BINデータ150cは、XMLデータ150aに含まれる各要素をパスIDテーブル140bのパスIDに置き換えたデータである。図9は、BINデータのデータ構造の一例を示す図である。例えば、XMLデータ150a(図1参照)の1段目に位置する「<Syain>シグマ戦隊中原ジャー」の「<Syain>」は、パスIDテーブル(図8参照)のパス「/Syain」(パスID「1」)に対応するため、BINデータ150cの1段目のように「[1シグマ戦隊中原ジャー」と変換される。このように、XMLデータ150aをBINデータ150cに変換することにより、パス照合におけるタグ階層の管理を省くことが出来る。
イベント定義表150dは、クエリに含まれるイベント種類とパスとを対応付けたデータである。図10は、イベント定義表150dのデータ構造の一例を示す図である。図10に示すように、このイベント定義表150dは、定義IDと、パスと、パスIDと、イベント種類とを対応付けて記憶している。なお、定義IDは、パスと、パスIDと、イベント種類との組合せを識別する情報である。
イベント種類となる集合ETYPE(Q)は、パスヒットイベントZ1、・・・、Zn、述部ヒットイベントP1、・・・Pn、クエリ開始イベントS、文脈ノードイベントCを有する。ここで、パスヒットイベントは、該当パスにヒットした旨を示すイベントであり、述部ヒットイベントは、述部にヒットした旨の示すイベントである。また、クエリ開始イベントは、クエリの開始パスにヒットした旨を示すイベントであり、文脈ノードイベントは、クエリの終了パスにヒットした旨を示すイベントである。
例えば、クエリが、
Q=/Syain/ACT[cast/name]/chara[id]/name
と指定され、イベント種類の集合が、
ETYPE(Q)={Z1,P1,Z2,P2,Z3}
と指定されている場合には、図10に示したイベント定義表150dが生成される。
イベント列データ150eは、BINデータ150cおよびイベント定義表150dを基にして生成されるデータであり、イベント定義表150dにヒットしたBINデータ150cの各種情報を記憶する。図11は、イベント列データ150eのデータ構造の一例を示す図である。図11に示すように、このイベント列データ150eは、イベントIDと、イベント種類と、オフセットとを対応付けて記憶している。このうち、イベントIDは、イベントを識別する情報であり、オフセットは、イベントが発生した時点でのデータ位置を示す。本実施例では一例として、オフセットを、ノードIDで指定する。
イベント木データ150fは、イベント列データ150eに基づいて作成されるイベント木である。このイベント木データ150fは、各ノード構造体が互いに接続することにより構成されている。図12は、ノード構造体のデータ構造の一例を示す図である。図12に示すように、ノード構造体は、イベントIDと、他のノード構造体へのポインタ(ポインタ配列)と、述部とから構成される。述部の初期値は偽(文脈ノードの場合はNull(-))となり、クエリに応じて真に変更される。
なお、ポインタ配列に複数のポインタが格納されている場合には、左端のポインタに接続されたノード構造体から順に走査が実行される。
図13は、イベント木データ150fのデータ構造の一例を示す図である。図13に示すように、このイベント木データ150fは、仮想ルート50と、ノード構造体60〜68とを有する。図13のイベント木データ150fを作成する手法は、イベント木作成部160d(後述する)の説明を行う場合にあわせて説明する。
制御部160は、各種の処理手順を規定したプログラムや制御データを格納するための内部メモリを有し、これらによって種々の処理を実行する制御手段であり、特に本発明に密接に関連するものとしては、図7に示すように、BINデータ生成部160aと、イベント定義表作成部160bと、イベント列作成部160cと、イベント木生成部160dと、イベント木走査部160eとを有する。
このうち、BINデータ生成部160aは、XMLデータ150aとパスIDテーブル150bとを比較して、XMLデータ150aに含まれる各要素をパスIDに置き換えることにより、BINデータ150cを生成する手段である。
例えば、BINデータ生成部160aは、図1において、XMLデータ150aの1段目に位置する「<Syain>シグマ戦隊中原ジャー」の「<Syain>」は、パスIDテーブル150bのパス「/Syain」(パスID「1」)に対応するため、BINデータ150cの1段目を「[1シグマ戦隊中原ジャー」とする。BINデータ生成部160aは、他の段も同様に、パスIDテーブル150bと比較して、各要素をパスIDに置き換えていくことで、BINデータ150cを生成する。
イベント定義表作成部160bは、クエリを取得した場合に、クエリに対応したイベント定義表を作成する処理部である。イベント定義表作成部160bは、例えば、クエリが、
Q=/Syain/ACT[cast/name]/chara[id]/name
と指定され、イベント種類の集合が、
ETYPE(Q)={Z1,P1,Z2,P2,Z3}
と指定されている場合には、クエリの各パスと、イベント種類の集合とを対応させることにより、図10に示したイベント定義表150dを作成する。
上記の条件では、パス「/Syain/ACT」がイベント種類「Z1」に対応し、パス「/Syain/ACT/cast/name」がイベント種類「P1」に対応し、パス「/Syain/ACT/chara」がイベント種類「Z2」に対応する。また、パス「/Syain/ACT/chara/id」がイベント種類「P2」に対応し、パス「/Syain/ACT/chara/id/name」がイベント種類「Z3」に対応する。また、パス「/Syain/ACT」は、クエリの開始パスとし、イベント種類に「S」を含ませる。また、パス「/Syain/ACT/chara/id/name」は、クエリの終了パスであるため、イベント種類に「C」を含ませる。
イベント列作成部160cは、BINデータ150cとイベント定義表150dとを基にして、イベント列データ150eを作成する処理部である。図14は、イベント列作成部160cの処理を説明するための図である。図14に示すように、イベント列作成部160cは、BINデータ150cを1文字ずつスキャンして、タグ開始記号「[」を検出するたびに、オフセットの値を1だけ加算する。なお、本実施例では、説明の便宜上、オフセットの値を、イベントが発生した際の、ノードのノードID(図2参照)をオフセットとする。
また、イベント列作成部160cは、タグ開始記号「[」の後ろ(直後)に、イベント定義表150dに含まれるパスIDを検出した場合には、イベントIDに1を加算して、イベント列に現在のイベントID、イベント種類、オフセットを登録する。以下において、イベント列作成部160cの処理を、図14を用いて説明する。
まず、BINデータ150cの位置「1001」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスIDは検出されない。BINデータ150cの位置「1002」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「2」が検出されるので、イベント(1)が発生し、イベント列作成部160cは、イベントID「1」、イベント種類「Z1、S」、オフセット「3」(図2のノードID「3」のACTに対応)をイベント列データ150eに登録する(図11の1段目参照)。なお、イベント(1)とは、イベント定義表150dの定義ID(1)に対応したイベントを示す。他のイベント(n)も同様である。
BINデータ150cの位置「1003」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「3」が検出されるので、イベント(3)が発生し、イベント列作成部160cは、イベントID「2」、イベント種類「Z2」、オフセット「4」(図2のノードID「4」のcharaに対応)をイベント列データ150eに登録する(図11の2段目参照)。
BINデータ150cの位置「1004」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「4」が検出されるので、イベント(4)が発生し、イベント列作成部160cは、イベントID「3」、イベント種類「P2」、オフセット「5」(図2のノードID「5」のidに対応)をイベント列データ150eに登録する(図11の3段目参照)。
BINデータ150cの位置「1005」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「5」が検出されるので、イベント(5)が発生し、イベント列作成部160cは、イベントID「4」、イベント種類「Z3、C」、オフセット「7」(図2のノードID「7」のidに対応)をイベント列データ150eに登録する(図11の4段目参照)。
BINデータ150cの位置「1006」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスIDは検出されない。BINデータ150cの位置「1007」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスIDは検出されない。
BINデータ150cの位置「1008」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「7」が検出されるので、イベント(2)が発生し、イベント列作成部160cは、イベントID「5」、イベント種類「P1」、オフセット「10」(図2のノードID「10」のnameに対応)をイベント列データ150eに登録する(図11の5段目参照)。
BINデータ150cの位置「1009」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスIDは検出されない。BINデータ150cの位置「1010」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスIDは検出されない。
BINデータ150cの位置「1011」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「2」が検出されるので、イベント(1)が発生し、イベント列作成部160cは、イベントID「6」、イベント種類「Z1、S」、オフセット「12」(図2のノードID「12」のACTに対応)をイベント列データ150eに登録する(図11の6段目参照)。
BINデータ150cの位置「1012」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「3」が検出されるので、イベント(3)が発生し、イベント列作成部160cは、イベントID「7」、イベント種類「Z2」、オフセット「13」(図2のノードID「13」のcharaに対応)をイベント列データ150eに登録する(図11の7段目参照)。
BINデータ150cの位置「1013」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「4」が検出されるので、イベント(4)が発生し、イベント列作成部160cは、イベントID「8」、イベント種類「P2」、オフセット「14」(図2のノードID「14」のidに対応)をイベント列データ150eに登録する(図11の8段目参照)。
BINデータ150cの位置「1014」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「5」が検出されるので、イベント(5)が発生し、イベント列作成部160cは、イベントID「9」、イベント種類「Z3、C」、オフセット「16」(図2のノードID「16」のnameに対応)をイベント列データ150eに登録する(図11の9段目参照)。
BINデータ150cの位置「1015」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスIDは検出されない。BINデータ150cの位置「1016」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスIDは検出されない。
BINデータ150cの位置「1017」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「7」が検出されるので、イベント(2)が発生し、イベント列作成部160cは、イベントID「10」、イベント種類「P1」、オフセット「19」(図2のノードID「19」のnameに対応)をイベント列データ150eに登録する(図11の10段目参照)。
BINデータ150cの位置「1018」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスIDは検出されない。BINデータ150cの位置「1019」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスIDは検出されない。
BINデータ150cの位置「1020」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「2」が検出されるので、イベント(1)が発生し、イベント列作成部160cは、イベントID「11」、イベント種類「Z1、S」、オフセット「21」(図2のノードID「21」のACTに対応)をイベント列データ150eに登録する(図11の11段目参照)。
BINデータ150cの位置「1021」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「3」が検出されるので、イベント(3)が発生し、イベント列作成部160cは、イベントID「12」、イベント種類「Z2」、オフセット「22」(図2のノードID「22」のcharaに対応)をイベント列データ150eに登録する(図11の12段目参照)。
BINデータ150cの位置「1022」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「4」が検出されるので、イベント(4)が発生し、イベント列作成部160cは、イベントID「13」、イベント種類「P2」、オフセット「23」(図2のノードID「23」のidに対応)をイベント列データ150eに登録する(図11の13段目参照)。
BINデータ150cの位置「1023」において、タグ開始記号「[」の直後に、イベント定義表150dに含まれるパスID「5」が検出されるので、イベント(5)が発生し、イベント列作成部160cは、イベントID「14」、イベント種類「Z3、C」、オフセット「25」(図2のノードID「25」のnameに対応)をイベント列データ150eに登録する(図11の14段目参照)。
なお、BINデータ150cの位置「1024」〜「1026」において、タグ開始記号「[」の後に、イベント定義表150dに含まれるパスIDは検出されない。このように、イベント列作成部160cは、BINデータ150cの位置「1001」〜「1026」と、イベント定義表150dとを比較することで、イベント列データ150eを作成する。
イベント木作成部160dは、イベント列データ150e(図11参照)を基にして、イベント木データ150f(図13参照)を作成する処理部である。イベント木作成部160dは、イベント列データ150eをイベントIDに沿って順次参照し、イベント種類がパスヒットイベント(Zn;nは自然数)の場合には、ノード構造体を作成する。また、イベント種類が述部ヒットイベントの場合には、処理対象に設定されたノード構造体の述部を「真」に設定する。以下において、イベント木作成部160dの処理を、具体例を用いて説明する。
図15〜図17は、イベント木作成部160dの処理手順を説明するための図である。まず、イベント木作成部160dは、初期木(仮想ルート)50を設定し(ステップS10)、イベント列データ150eのイベントID「1」を参照する。イベントID「1」のイベント種類はパスヒットイベント「Z1」であるため、イベント木作成部160dは、ノード構造体60を作成する。この時点におけるノード構造体60のイベントIDは、「1」、ポインタ(他のノード構造体へのポインタ)はブランク、述部は初期値の「偽」となる。なお、イベント木作成部160dは、初期木50の配下にノード構造体60を接続する(ステップS11)。
イベント木作成部160dは、イベント列データ150eのイベントID「2」を参照する。イベントID「2」のイベント種類はパスヒットイベント「Z2」であるためイベント木作成部160dは、ノード構造体61を作成し、ノード構造体60のポインタをノード構造体61に設定する(ステップS12)。また、この時点におけるノード構造体61のイベントIDは「2」、ポインタはブランク、述部は初期値の「偽」となる。
イベント木作成部160dは、イベント列データ150eのイベントID「3」を参照する。イベントID「3」のイベント種類は述部ヒットイベント「P2」であるためイベント木作成部160dは、ノード構造体61の述部を「真」に設定する(ステップS13)。
イベント木作成部160dは、イベント列データ150eのイベントID「4」を参照する。イベントID「4」のイベント種類はパスヒットイベント「Z3」であるためイベント木作成部160dは、ノード構造体62を作成し、ノード構造体61のポインタをノード構造体62に設定する(ステップS14)。また、この時点におけるノード構造体62のイベントIDは「4」、ポインタはブランク、述部はNullに設定する(イベント種類にC<文脈ノード>が含まれているため)と共に、親ノードに対応するノード構造体60に移行する。
イベント木作成部160dは、イベント列データ150eのイベントID「5」を参照する。イベントID「5」のイベント種類は述部ヒットイベント「P1」であるため、イベント木作成部160dは、ノード構造体60の述部を偽から真に変更する(ステップS15)。また、親ノードに対応する初期木に移動する。
イベント木作成部160dは、イベント列データ150eのイベントID「6」を参照する。イベントID「6」のイベント種類はパスヒットイベント「Z1」であるためイベント木作成部160dは、ノード構造体63を作成する。この時点におけるノード構造体63のイベントIDは「6」、ポインタはブランク、述部は初期値の「偽」となる。なお、イベント木作成部160dは、初期木50の配下にノード構造体63を接続する(ステップS16)。
なお、イベント木作成部160dは、イベント列データ150eのイベントID「7〜10」の処理をイベントID「2〜5」と同様の処理を実行することにより、ステップS17に示すイベント木が作成される。図17の上段に示すように、初期木50の配下にノード構造体60,63が接続され、ノード構造体60の配下にノード構造体61が接続され、ノード構造体61の配下にノード構造体62が接続される。ノード構造体63の配下にノード構造体64が接続され、ノード構造体64の配下にノード構造体65が接続される。また、ノード構造体60,61,63,64の述部は「真」となり、ノード構造体62,65の述部は「Null」となる。
また、イベント木作成部160dは、イベント列データ150eのイベントID「11〜14」の処理をイベントID「1〜4」と同様の処理を実行することにより、ステップS18に示すイベント木が作成される。図17の下段に示すように、初期木50の配下にノード構造体60,63,66が接続され、ノード構造体60の配下にノード構造体61が接続され、ノード構造体61の配下にノード構造体62が接続される。
ノード構造体63の配下にノード構造体64が接続され、ノード構造体64の配下にノード構造体65が接続される。ノード構造体66の配下にノード構造体67が接続され、ノード構造体67の配下にノード構造体68が接続される。また、ノード構造体60,61,63,64,67の述部は「真」となり、ノード構造体66の述部は「偽」となり、ノード構造体62、65、68の述部は「Null」となる。イベント木作成部160dは、作成したイベント木をイベント木データ150fとして記憶部150に格納する。
このように、イベント木作成部160dは、イベント列データ150e(例えば、図11参照)を順次参照し、イベント種類に応じてノード構造体を作成すると共に、各ノード構造体を接続、ノード構造体の述部の設定(真または偽の設定)を行うことで、イベント木データ150f(例えば、図13参照)を作成する。
図7の説明に戻ると、イベント木走査部160eは、イベント木データ150fに基づいて、クエリによるXMLデータ150aの指定位置を判定し、判定した指定位置に対応するデータを出力する処理部である。イベント木走査部160eは、イベント木データ150fを構成するノード構造体の述部を参照し、述部が真に設定されているか否かによって配下のイベント構造体に移行し、文脈ノード(クエリの指定箇所)を特定する。
具体的に、イベント木走査部160eは、ノード構造体の述部を参照し、述部が「真」の場合に、配下のノード構造体に移行する。一方、イベント木走査部160eは、述部が「偽」の場合には、それ以降の検索を中止する。また、イベント木走査部160eは、ノード構造体の述部が「Null」の場合には、かかるノード構造体のノードIDに対応するノードIDを、クエリの指定箇所(文脈ノード)として判定する。
イベント木走査部160eは、文脈ノードを判定するたびに、文脈ノードに対応するノード構造体のノードIDを、集合Rに登録していく。例えば、図13において、文脈ノードに対応するノード構造体をノード構造体62,65とすると、スキャン後の集合Rは、集合R={4,9}となる。
図18は、イベント木走査部160eの処理手順を説明するための図である。図18に示すように、イベント木走査部160eは、初期の走査位置を仮想ルート(ルートノード)50に設定する(ステップS20)。
イベント木走査部160eは、走査位置をノード構造体60に移行させる。ノード構造体60は、文脈ノードではなく、述部が「真」であるため、配下に接続されたノード構造体61に走査位置を移行する(ステップS21)。
ノード構造体61は、文脈ノードではなく、述部が「真」であるため、イベント木走査部160eは、配下に接続されたノード構造体62に走査位置を移行させる(ステップS22)。ノード構造体62は、文脈ノードであり、述部が「Null」であるため、集合RにノードID「4」を追加し、仮想ルート50に戻る(ステップS23)。
イベント木走査部160eは、走査位置をノード構造体63に移行させる。ノード構造体63は、文脈ノードではなく、述部が「真」であるため、配下に接続されたノード構造体64に走査位置を移行する(ステップS24)。
ノード構造体64は、文脈ノードではなく、述部が「真」であるため、イベント木走査部160eは、配下に接続されたノード構造体65に走査位置を移動させる(ステップS25)。ノード構造体65は、文脈ノードであり、述部が「Null」であるため、集合RにノードID「9」を追加し、仮想ルート50に戻る(ステップS26)。
イベント木走査部160eは、走査位置をノード構造体66に移行させる。ノード構造体66は、文脈ノードではなく、述部が「偽」であるため、イベント木走査部160eは、仮想ルート50に接続されたノード構造体のうち、未走査のノード構造体を検索する。しかし、未走査のノード構造体は存在しないので、処理を終了する(ステップS27)。
イベント木走査部160eは、イベント木データ150fに対する走査を終了した後、集合Rに格納されたノードIDに基づいて、クエリの指定箇所に対応するデータを抽出し、抽出したデータを出力する。
例えば、イベント木走査部160eは、集合Rに格納されたノードIDが「4,9」の場合には、イベントID4,9に対応するノードIDは、ノードID7,16となる(図11参照)ので、ノードID7のnameとノードID16のnameがクエリの指定箇所となる。従って、イベント木走査部160eは、ノードID7のnameに対応するデータ「<name>シグマレッド<name>」とノードID16のnameに対応するデータ「<name>シグマブルー<name>」を出力する(例えば、図3参照)。
次に、本実施例にかかる検索装置100の処理手順について説明する。図19は、本実施例にかかる検索装置100の処理手順を示すフローチャートである。図19に示すように、検索装置100は、クエリを取得し(ステップS101)、イベント定義表作成部160bがイベント定義表150dを作成する(ステップS102)。
続いて、イベント列作成部160cが、イベント列データ作成処理を実行し(ステップS103)、イベント木作成部160dが、イベント木作成処理を実行する(ステップS104)。
そして、イベント木走査部160eが、イベント木走査処理を実行し(ステップS105)、検出結果を出力する(ステップS106)。
次に、図19のステップS103に示したイベント列データ作成処理の処理手順について説明する。このイベント列作成処理は、イベント列作成部160cが、BINデータ150c(図9参照)をスキャンして、イベント列データ150e(図11参照)を作成する処理である。図20は、イベント列データ作成処理の処理手順を示すフローチャートである。
図20に示すように、イベント列作成部160cが、イベント列データ150eを空テーブルとして初期化し、オフセットを初期化する(ステップS201)。そして、イベント列作成部160cは、BINデータ150cを文字ずつスキャンし、タグ開始記号「[」を検出するたびに、オフセットに1を加算する。
また、イベント列作成部160cは、タグ開始記号「[」の直後にイベント定義表150dに含まれるパスIDを検出した場合に、イベント列データ150eのイベントIDに1を加算し、イベント列データ150eに(イベントID、イベント種類、オフセット)を登録し(ステップS202)、イベント列データ150eを出力する(ステップS203)。
なお、図20のステップS202において、イベント列データ150eに登録されるイベント種類は、タグ開始記号「[」の直後に検出されたパスIDと、イベント定義表150dとを比較することで特定される。また、説明の便宜上、図11に示すイベント列データ150eのオフセットは、タグ開始記号「[」の直後に検出されたパスIDに対応するノードのノードIDとする。
次に、図19のステップS104に示したイベント木作成処理の処理手順について説明する。このイベント木作成処理は、イベント木作成部160dが、イベント列データ150e(図11参照)をスキャンして、イベント木データ150f(図13参照)を作成する処理である。図21は、イベント木作成処理の処理手順を示すフローチャートである。
図21に示すように、イベント木作成部160dは、eをイベント列データ150eの最初のイベントに設定し(ステップS301)、イベント木Tを初期木に設定し、v=root(T)とする(ステップS302)。
イベント木作成部160dは、eのイベント種類がパスヒットイベントであるか否かを判定し(ステップS303)、パスヒットイベントでない場合(述部ヒットイベントの場合)には(ステップS304,No)、vのブール値(ノード構造体の述部に対応;図12参照)が偽の場合に、vのブール値を真に変更し(ステップS305)、ステップS308に移行する。
一方、イベント木作成部160dは、パスヒットイベントの場合には(ステップS304,Yes)、ノード構造体wを作成し、wのイベントIDにeのイベントIDを書込み(ステップS306)、vのポインタ配列の最終要素として、ノード構造体wへのリンクを書き込む(ステップS307)。
イベント木作成部160dは、eの次のイベントがイベント列データ150eに存在するか否かを判定し(ステップS308)、eの次のイベントが存在する場合には(ステップS309,Yes)、e=nextevent(E)とし(ステップS310)、v=parnode(e,T)とし(ステップS311)、ステップS303に移行する。
ここで、e=nextevent(E)は、現在のイベントの次のイベントを与える関数である。例えば、図11において、現在のイベントがイベントID「1」のイベントである場合には、e=nextevent(E)によって特定されるイベントは、イベントID「2」のイベントとなる。また、v=parnode(e,T)は、現在のeに指定されるノード構造体の親となるノード構造体を特定する関数である。例えば、現在のeに指定されるノード構造体がノード構造体62の場合には、v=parnode(e,T)により、ノード構造体61が与えられる。
一方、eの次のイベントがイベント列データ150eに存在しない場合には(ステップS309,No)、イベント木T(イベント木データ150f)を出力する(ステップS312)。
次に、図21のステップS311に示した関数parnode(e,T)に対応する処理について説明する。図22は、関数parnode(e,T)に対応する処理のフローチャートである。図22に示すように、イベント木作成部160dは、v=root(T)とし、i=1とし(ステップS401)、i<H(e)の条件を満たすか否かを判定する(ステップS402)。
ここで、イベントeのイベント種類がZnまたはPnのとき、eの高さをH(e)=nと定義する。例えば、eがイベントID「4」のイベントの場合には、イベント種類が「Z3」であるため、H(e)=3となる。
イベント木作成部160dは、i<H(e)となる場合には(ステップS403,Yes)、vのポインタ列の右端が示すノードを新たなvに設定し、i=i+1とし(ステップS404)、ステップS402に移行する。一方、i≧H(e)となる場合には(ステップS403,No)、vを出力する(ステップS405)。
次に、図19のステップS105に示したイベント木走査処理の処理手順について説明する。このイベント木走査処理は、イベント木走査部160eが、イベント木データ150fをスキャンすることにより、クエリの指定箇所を判定する処理である。図23は、イベント木走査処理の処理手順を示すフローチャートである。
図23に示すように、イベント木走査部160eは、v=root(T)とし、R=φ(空集合)とし(ステップS501)、vが文脈ノードであるか否かを判定する(ステップS502)。vが文脈ノードの場合には(ステップS503,Yes)、vの述部が真またはNullであるか否かを判定する(ステップS504)。
イベント木走査部160eは、vの述部が真またはNullの場合には(ステップS505,Yes)、R∪{v}とし(ステップS506)、nextnode(T,v)が存在するか否かを判定する(ステップS507)。ここで、nextnode(T,v)は、イベント木データ150fのプリオーダ順において、vの次のノードを与える関数である。
例えば、図13において、現在のノード構造体(ノード)が、ノード構造体60の場合には、nextnode(T,v)により、ノード構造体61が与えられる。木構造のプリオーダ順の定義と、プリオーダ順の巡回方法については、例えば、従来技術(エイホ・ウルマン・ホップクロフト著(大野訳)「情報処理シリーズ11 データ構造とアルゴリズム」(培風館))に記載されている。
図23の説明に戻ると、イベント木走査部160eは、nextnode(T,v)が存在しない場合には(ステップS508,No)、Rを出力し(ステップS509)、イベント走査処理を終了する。
ところで、イベント木走査部160eは、ステップS503において、vが文脈ノードではない場合に(ステップS503,No)、v=root(T)またはvの述部が真であるか否かを判定する(ステップS510)。そして、条件を満たす場合(すなわち、v=root(T)またはvの述部が真の場合)には(ステップS511,Yes)、ステップS507に移行する。
一方、条件を満たさない場合(すなわち、v≠root(T)かつ述部が偽の場合)には(ステップS511,No)、skipnode(T,v)が存在するか否かを判定する(ステップS512)。ここで、skipnode(T,v)は、vからnextnode(T,v)の適用を繰り返し得られるノードのうち、vの部分木に含まれない最初のノードを定義する関数である。例えば、図13において、vにより指定されるノード構造体がノード構造体62の場合には、skipnode(T,v)により、ノード構造体63が与えられる。
図23の説明に戻ると、イベント木走査部160eは、skipnode(T,v)が存在しない場合には(ステップS513,No)、ステップS509に移行する。一方、skipnode(T,v)が存在する場合には(ステップS513,Yes)、v=skipnode(T,v)とし(ステップS514)、ステップS502に移行する。
ところで、イベント木走査部160eは、ステップS508において、nextnode(T,v)が存在する場合には(ステップS508,Yes)、v=nextnode(T,v)とし(ステップS515)、ステップS502に移行する。
次に、図23に示した関数skipnode(T,v)に対応する処理について説明する。図24は、関数skipnode(T,v)に対応する処理のフローチャートである。図24に示すように、イベント木走査部160eは、vの親ノードpが存在するか否かを判定し(ステップS601)、存在しない場合には(ステップS602,No)、「該当ノードは存在せず」を出力する(ステップS603)。
一方、イベント木走査部160eは、vの親ノードpが存在する場合には(ステップS602,Yes)、vの親ノードpのポインタ配列において、vへのポインタの右隣にポインタが存在するか否かを判定する(ステップS604)。
イベント木走査部160eは、vへのポインタの右隣にポインタが存在しない場合には(ステップS605,No)、vに親ノードpを代入し(ステップS606)、ステップS601に移行する。
一方、イベント木走査部160eは、vへのポインタの右隣にポインタが存在する場合には(ステップS605,Yes)、右隣のポインタ先となるノードをvとし(ステップS607)、vを出力する(ステップS608)。
上述してきたように、本実施例にかかる検索装置100は、イベント木作成部160dが、イベント木データ150fを構成するノード構造体の述部(述部ノードに対応)に、クエリの制約条件を満たしている旨を示す「真」または、クエリの制約条件を満たしていない旨を示す「偽」を設定する。そして、イベント木走査部160eが、イベント木データ150fを走査する場合に、ノード構造体の述部を参照し、述部が「真」の場合には、所定の順序規則に従って走査を継続して文脈ノードを特定することでデータを検出するので、従来技術のように、クエリの制約条件を満たしているにもかかわらず、同一のノード構造体(ノード)を複数回スキャンするという無駄を省き、計算効率を向上させることができる。
また、本実施例にかかる検索装置100は、イベント木走査部160eが、ノード構造体の述部を参照し、述部が「偽」の場合には、述部「偽」を備えるノード構造体の配下に接続されたノード構造体に対する走査をスキップするので、従来技術と同様にしてクエリに指定された文脈ノードを正確に特定することができる。
また、本実施例にかかる検索装置100は、例えば図6に示したように、同じラベルを持つ接点が同一兄弟中に複数含まれる場合でも、述部ノードを「真」または「偽」の1ビットで表現するので、記憶装置に記憶させるべきデータ量を削減することができる。
ところで、本実施例において説明した各処理のうち、自動的に行われるものとして説明した処理の全部または一部を手動的に行うこともでき、あるいは、手動的に行われるものとして説明した処理の全部あるいは一部を公知の方法で自動的に行うこともできる。この他、上記文書中や図面中で示した処理手順、制御手順、具体的名称、各種のデータやパラメータを含む情報については、特記する場合を除いて任意に変更することができる。
また、図7に示した検索装置100の各構成要素は機能概念的なものであり、必ずしも物理的に図示の如く構成されていることを要しない。すなわち、各装置の分散・統合の具体的形態は図示のものに限られず、その全部または一部を、各種の負荷や使用状況などに応じて、任意の単位で機能的または物理的に分散・統合して構成することができる。さらに、各装置にて行われる各処理機能は、その全部または任意の一部がCPUおよび当該CPUにて解析実行されるプログラムにて実現され、あるいは、ワイヤードロジックによるハードウェアとして実現され得る。
図25は、本実施例にかかる検索装置100を構成するコンピュータ200のハードウェア構成を示す図である。図25に示すように、このコンピュータ(検索装置)200は、入力装置201、モニタ202、RAM(Random Access Memory)203、ROM(Read Only Memory)204、記憶媒体からデータを読み取る媒体読取装置205、他の装置(例えば、端末装置)との間でデータの送受信を行う通信装置206、CPU(Central Processing Unit)207、HDD(Hard Disk Drive)208をバス209で接続して構成される。
そして、HDD208には、上記した検索装置100の機能と同様の機能を発揮する検索プログラム208bが記憶されている。CPU207が、検索プログラム208bを読み出して実行することにより、検索プロセス207aが起動される。ここで、検索プロセス207aは、図7に示したBINデータ生成部160a、イベント定義表作成部160b、イベント列作成部160c、イベント木作成部160d、イベント木走査部160eに対応する。
また、HDD208は、記憶部150に格納されたデータに対応する各種データ208aを記憶する。CPU207は、HDD208に格納された各種データ208aを読み出して、RAM203に格納し、RAM203に格納された各種データ203aを利用して、クエリ木データを作成し、クエリの指定箇所に対応するデータを検出する。
ところで、図25に示した検索プログラム208bは、必ずしも最初からHDD208に記憶させておく必要はない。たとえば、コンピュータに挿入されるフレキシブルディスク(FD)、CD−ROM、DVDディスク、光磁気ディスク、ICカードなどの「可搬用の物理媒体」、または、コンピュータの内外に備えられるハードディスクドライブ(HDD)などの「固定用の物理媒体」、さらには、公衆回線、インターネット、LAN、WANなどを介してコンピュータに接続される「他のコンピュータ(またはサーバ)」などに検索プログラム208bを記憶しておき、コンピュータがこれらから検索プログラム208bを読み出して実行するようにしてもよい。