Wolfgang Meierのオープン・ソースeXistデータベースは、現在入手可能なネイティブXMLデータベースの中で最も人気のあるものです(最も人気があるものがベストなものとは限りませんが)。eXistはJava™プログラミング言語で書かれていて、主要なプラットフォームのほとんどで動作します。プログラムは、バンドルされているHTTPサーバーを通じてeXistと通信します。SOAP、XML-RPC、およびRESTfulインターフェースのすべてが提供され、これらを通じて、XPath、XQuery、およびXUpdate要求をコア・サーバーに送信することができます。コマンドラインおよびGUIクライアントも使用可能です。
eXistにはJava 1.4以上が必要ですが、親切なことにそれ以外の必要な依存ファイルはすべてバンドルされています。実際、eXistのインストールは、サーバー・サイドのオープン・ソース・プロジェクトとしては驚くほど簡単です。クローズド・ソースにしてもオープン・ソースにしても、他の多くのプロジェクトは、この簡単さを見習うべきでしょう。インストーラーはIzPackでビルドされています。ディストリビューションは単一のJARアーカイブです。eXistをインストールするには、次のようにアーカイブを実行するだけです。
$ java -jar eXist-1.0b2-build-1107.jar |
インストーラーによってGUIが表示されて、eXistディレクトリーのインストール先をたずねます。私は/home/elharo/eXistにインストールしました。eXist/binディレクトリーには、必要な起動スクリプトが含まれています。サーバーを起動するには、startup.sh(UNIX®)またはstartup.bat(Microsoft® Windows®)を実行します。
$ ./startup.sh |
このコマンドは、ポート8080でサーバーを実行して、/eXist内のファイルの提供を開始します。どのWebブラウザーからでもeXistに接続できます。たとえば、私はeXistをeliza.elharo.comにインストールしたので、次のようなURLで接続できます。
http://eliza.elharo.com:8080/exist/ |
(Don't try this at home -- my firewall will block you. You'll have to connect to your own server.)
(自宅でこれを試さないでください。ファイアーウォールでブロックされます。あなたはあなたのサーバーに接続する必要があります。)
はじめに、eXistマニュアルが表示され、いくつかのサンプルも表示されるので、試してみることができます。
eXistは、実際にはWebサーバーではありません。基盤となるデータベース・サーバーへの便利なインターフェースとしてWebサーバーを使用するだけです。パッケージには、さまざまな操作の実行に使用できる独立型GUIクライアントとプログラミングAPIが含まれています。WebDAVを使用して、Microsoft Windows Explorerからブラウズすることもできます。最初の実験としては、シンプルなGUIクライアントを使うのが最も簡単でしょう。クライアントを起動するには、eXist/binディレクトリーからclient.sh(UNIX)またはclient.bat(Windows)を実行します。
$ ./client.sh |
図1に示されているように、デフォルトでは、クライアントはポート8080上のlocalhostで実行しているeXistデータベースへの接続を試みます。URLテキスト・フィールドで別のホストとポートを指定することができます。同じウィンドウで、ユーザー名とパスワードも要求されます。デフォルトでは、ユーザー名はadminです。パスワード・フィールドは空白のままでかまいません。(ソフトウェア会社各社は、デフォルトのユーザーとパスワードを設定してサーバーを出荷すべきでないことを今まで学ばなかったのでしょうか。)
図1. eXistへの接続
|
はい、あなたはユーザーを管理し、パスワードを設定し、権限を設定し、さまざまなアクセス権をもつさまざまなグループにユーザーを割り当てることができます。その他、完全な実働環境で必要なタスクをすべて行うことができます。ただし、この記事では紙面の都合上、そのようなオプションの多くを割愛して、説明をデータベースの要点に絞らざるをえません。 |
ログイン後、クライアントは図2のGUIを表示します。当初、eXistにはsystemという名前のコレクションが付随し、ここにユーザー情報が格納されます。とりあえず、このコレクションはこのままにしておきましょう。その代わり、File > New Collectionを選択して、自分のドキュメント用の新しいコレクションを作成してください。私はbooksという名前のコレクションを作成しました。コレクションを開くには、GUIの中のコレクションをダブルクリックします。コレクションを開いた後、ドキュメントをアップロードするには、+記号の付いた書類のアイコンをクリックします。
図2. eXist adminクライアント
私はまず、2つの小さなドキュメントをアップロードし、データベースは何も苦情を言わずにそれらを受け入れました。次に、私の著書『Processing XML with Java』の全文をアップロードしてみました。この操作は失敗し、エラー・メッセージは何も表示されませんでした。GUIクライアントの代わりにWebインターフェースからアップロードしても失敗しました。ただし、このインターフェースでは、問題のデバッグに役立つスタック・トレースが表示されました。その結果、eXistは文書型宣言で使用された相対URLを解決していないことがわかりました。外部DTDサブセット付きのドキュメントをロードするには、DTDをサーバーのファイルシステムに手動でインストールし、カタログ・ファイルを編集して、DTDの場所をデータベースに教える必要があります。その後、データベース・サーバーを再起動して、カタログ・ファイルを再ロードさせなければなりません。これは、かなり面倒ですが、通常、DTDをインストールする必要があるのは、それぞれのDTDについて1回だけです。ドキュメントがDTDを使用しないか、あまり頻繁に変更されない少数のDTDしか使用しない場合、eXistは最もよく動作します。
eXistはXPathとXQueryの両方をサポートしています(それぞれの詳細については、「参考文献」を参照してください)。eXistは、2003年11月版のXQueryワーキング・ドラフトのXQuery構文を使用しています。より新しいワーキング・ドラフトの構文を使用するように、データベースをアップデートする作業が行われているところです。基本的なFor-Let-Where-Order-Return(FLWOR)クエリーについては、ドラフト間の違いは大きくありません。
コレクションに対するクエリーを入力するには、GUIクライアントの中の小さな双眼鏡アイコンをクリックします。すると、図3に示されているウィンドウが表示されます。
図3. eXistクエリー・ウィンドウ
厄介なことに、このインターフェースではコピー・アンド・ペーストができないので、すべてのクエリーを手作業で入力しなければなりません。もちろん、このプログラムは実際にはテストと実験のためにすぎません。Oracleデータベースに生のSQLを入力する以上に重大なデータベースとの通信には使用しないでください。実行したいクエリーについていいアイデアが浮かんだら、次に述べるように、クエリーをアルゴリズムによって生成し送信するプログラムを書くことができます。
IBM®、Oracle、およびその他のJSR 225エキスパート・グループのメンバーは、現在、JDBCがSQLに対してすることをXQueryに対して行うAPIを定義する作業を進めています。ただし、このプロセスが終了して、APIがeXistに実装されるまでは、eXistのネイティブAPIを使用する必要があります。このAPIには、SOAP、XML-RPC、WebDAV、またはHTTPインターフェースからアクセスできます。これらのプロトコルの1つをサポートするAPIであれば、eXistと通信できます。たとえば、JAX-RPCを使用してSOAP経由でeXistと通信したり、java.netを使用してHTTP経由で通信することができます。
RESTfulHTTPインターフェースは、これらの中で最もシンプルで最も広く入手可能です。たとえば、"XSLT"という単語を含んでいるすべてのpara要素をbooksコレクションから検索したいとします。リスト1のXQueryは、このような要素をすべて検索します。
リスト1. サンプルのXQuery
for $p in //para
where contains($p, "XSLT")
return $p
|
このクエリーを次のURLからGETします。
http://eliza.elharo.com:8080/exist/servlet/db/books/ |
eliza.elharo.comは、データベースが実行しているネットワーク・ホストです。8080は、ポートです。/exist/servlet/dbは、それぞれWebアプリケーション、サーブレット、およびデータベースを識別します。booksは、そのデータベースでクエリーする特定のコレクションです。eXistではネストされたコレクションが可能です。たとえば、booksコレクションの中にfictionコレクションとnonfictionコレクションが含まれているとすると、次のようなURLでアクセスできます。
http://eliza.elharo.com:8080/exist/servlet/db/books/fiction/ http://eliza.elharo.com:8080/exist/servlet/db/books/nonfiction/ |
しかし、この記事の目的では、フィクションとノンフィクションの両方を含むすべての書籍をクエリーします。XQueryはURLのクエリー文字列(URLの疑問符の後の部分)の_queryフィールドの値として送信されます。これは通常通りパーセント記号化されていなければなりません(たとえば、スペースは%20になり、二重引用符は%22になります)。したがって、次のURLをGETすることによって、リスト1のクエリーをサーバーに送信することができます。
http://eliza.elharo.com:8080/exist/servlet/db/books/?_query= for%20$p%20in%20//para%20where%20contains($p,%20%XSLT%22)%20return%20$p |
サーバーは、リスト2のようにexist:result要素で囲まれたクエリー結果を返します。
リスト2. サンプル・クエリーの結果
<exist:result xmlns:exist="http://exist.sourceforge.net/NS/exist"
exist:hits="148" exist:start="1" exist:count="10">
<para><quote>HTML? You must be joking</quote> said the fourth, a computer
science professor on sabbatical from MIT, who was engrossed in an XSLT
stylesheet ...</para>
<para>XSLT and the TrAX API</para>
<para>Combine functional XSLT transforms with traditional imperative Java code</para>
<para>The TrAX API for XSLT processing</para>
<para>Once you're comfortable with one or more of these APIs, you
can read Chapters 16 and 17 on XPath and XSLT.
However, those APIs and chapters do require some knowledge of at least one
of the three major APIs.</para>
...</exist:result>
|
その他、オプションのクエリー文字列変数によって、結果を見やすく表示するかどうか、結果をラップする要素、返されるマッチ数(デフォルトでは、eXistは最初の10ヒットしか返しません)などを制御することができます。
これはすべてHTTP GETで行われるので、適切なURLをWebブラウザーに入力するだけで、このクエリーを実行することができます。もちろん、HTTP対応のソフトウェア・ライブラリーもこのクエリーを送信して、結果をXMLストリームとして受け取ることができます。このクエリーをJava言語で書くとすれば、リスト3に示されているように、URLEncoderクラスを使用してクエリー文字列をエンコードし、URLクラスを使用して送信し、XOMを使用して結果を処理します。
リスト3. JavaコードでのeXistのクエリー
String xquery = "for $p in //para"
+ " where contains($p, \"XSLT\") "
+ " return $p";
String encodedQuery = URLEncoder.encode(xquery);
URL u = new URL("http://eliza.elharo.com:8080/exist/servlet/db/books/?_query=");
+ encodedQuery);
InputStream in = u.openStream();
Document doc = (new Builder()).build(in);
// work with the document...
|
このようなHTTPインターフェースは、完全に言語独立です。リスト3の機能は、Perl、Python、C、C#、または単純なHTTPライブラリーとある程度のXMLサポートを備えている言語であればどんな言語でも、簡単に再現できます。このようなデータベースにクエリーする最も効果的な方法は、結果を書式化するXSLTスタイルシートを書くことです。
ドキュメントの挿入
XQueryによって、データベースから情報を取得することができます。しかし、データを入れる場合はどうでしょう。この方が簡単です。GET要求を送信する代わりに、PUT要求を送信します。データをPUTするURLは、データベース内でドキュメントが置かれるURLです。要求の本体は、格納するドキュメントです。たとえば、リスト4のJavaコードは、Cafe con Leche WebサイトからRSSフィードを取得して、それを20050401という名前でsyndicationコレクションに入れます。
リスト4. JavaコードでのeXistへのドキュメントの挿入
URL u = "http://www.cafeaulait.org/today.rss";
InputStream in = u.openStream();
URL u = new URL("http://eliza.elharo.com:8080/exist/servlet/db/syndication/20050401");
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("PUT");
conn.setHeaderField("Content-type", "application/xml");
OutputStream out = conn.getOutputStream();
for (int c = in.read(); c != -1; c = in.read()) {
out.write(c);
}
out.flush();
out.close();
in.close();
// read the response...
|
新しいドキュメントをデータベースにPUTするには、通常、認証が必要です。eXistのRESTインターフェースは、HTTP基本認証をサポートしています。Java言語は、java.net.Authenticatorクラスによってこれをサポートしています。この話題について詳しく述べるのはとても無理ですが、要するに、データベースのユーザー名とパスワードを知っている(または質問方法を知っている)クラスにAuthenticatorサブクラスを作り、このサブクラスのインスタンスをシステムのデフォルトの認証プログラムとしてインストールします。
ドキュメントの削除
コレクションからドキュメントを削除する必要があるときは?リスト5に示されているように、該当するURLにDELETE要求を送信するだけです。
リスト5. eXistでのドキュメントの削除
URL u = new URL("http://eliza.elharo.com:8080/exist/servlet/db/syndication/20050401");
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod("DELETE");
conn.connect();
// read the response...
|
やはり、実際には、Authenticatorオブジェクトを介してユーザー名とパスワードを指定する必要があります。
ドキュメントの更新
最後の、そして最も難しい操作は、データベース内の情報を変更することです。たとえば、私の電子メール・アドレスをelharo@metalab.unc.eduからelharo@macfaq.comに変更するとします。したがって、<email>elharo@metalab.unc.edu</email>要素をすべて、<email>elharo@macfaq.com</email>に変更しなければなりません。これはXQueryではできないので、eXistは代わりにXUpdateを使用します。リスト6のXUpdateクエリーによって変更を加えます。
リスト6. XUpdateを使用してeXistのドキュメントを更新する
<xupdate:update
xmlns:xupdate="http://www.xmldb.org/xupdate"
select="//email[.='elharo@metalab.unc.edu']">
elharo@macfaq.com
</xupdate:update>
|
この操作によってリソースが変更されるので、これをサーバーに送信するにはPOSTメソッドを使用する必要があります。変更したいドキュメントのURLにPOSTして、要求の本体でXUpdate命令を与えます。
RESTインターフェースの重要点だけを簡単にご紹介しましたが、コレクションの作成と削除、クエリー結果の書式化方法の指定、およびユーザー認証情報の指定などの命令もあります。eXistへのインターフェースはHTTPだけではありません。eXistは、Perl、PHP、およびJava言語用のネイティブAPIと、汎用のWebDAV、SOAP、およびXML-RPCインターフェースも備えています。幅広いAPIサポートが、eXistの強みの1つです。
eXistは、地球上で最速のデータベースというわけではありません。ローカル・データベースに接続している高速なハードウェアでも、ストップウォッチを使えば、中サイズのドキュメントのロードにかかる時間を測定することができます。クエリーの速度は、そのまま品質ということになります。中規模の大きさのコレクションに対して複雑なクエリーを実行すれば、その間にコーヒーを淹れることができます。ドキュメントのロードとクエリーの両方の時間を改善するには、eXistのメモリーを増やしてください。eXistのデフォルトの構成では、約256MBのメモリーを搭載しているマシンに適切な設定が指定されています。より高性能なサーバーを使用している場合は、conf.xmlファイルを修正して、メモリー割り当てを増やすことができます。
データベースをチューニングするために、インデックスを追加することができます。デフォルトでは、eXistはドキュメントの全文だけでなく、要素および属性ノードにもインデックスを付けます。クエリーで発生しそうな特定のノード・セットについて、追加の範囲インデックスを指定することができます。たとえば、para要素を探すクエリーが多くなりそうだとわかっている場合は、//paraのインデックスを定義することができます。こうすると、eXistは、後で必要になりそうなので、ドキュメント内のすべてのpara要素の値をあらかじめ計算して格納します。
それでもやはり、eXistにふさわしいのは、速度が不可欠ではない小さなコレクションです。ギガバイト・クラスのドキュメントがある場合や、1時間に数千ものトランザクションを処理する場合は、他の方法を考えてください。
同様に、重要なデータをeXistに任せてよいものかどうか、確信がもてません。個人的には、データベース破損を経験してはいません。しかし、開発者たちはいまだにデータベース破損問題を発見し、修正し続けていて、その頻度が私に不安を覚えさせます。プラス面として、eXistを使用すると、データベースのバックアップが非常に簡単になります。非常に重要なこととして、バックアップ形式は独自形式のバイナリではなく、実際のテキストXMLで内容を保存します。これは、最悪の場合でも、テキスト・エディターで問題を修復できることを意味します。頻繁に圧縮バックアップを行う場合、eXistはデータを検索不能にするようなことは何もしません。
多機能なeXistは基本的なニーズに十分応え、XIncludeサポートなど、思いがけない利点も備えています。トランザクション、ロールオーバー、フォールバックなど、企業レベルの機能は何も備えていません(トランザクションは「to do」リストに入っています)。しかし、アプリケーションの多くは、このような高度な機能を必要としません。
eXistに関する私の最大の懸念の1つは(この点については他のどのXQueryベースのネイティブXMLデータベースについても同じですが)、基盤となっている標準とAPIの安定性です。この記事はeXistの最新のベータ版(2004年11月)に基づき、これは2003年11月のXQueryドラフトに基づいています。現在、CVSにあるeXistのバージョンでは、ごく少数の下位互換性のない変更が加えられていますが、まだ詳しくは文書化されていません。今後、eXistにも、それが依存しているW3Cの仕様にも、さらに多くの変更が加えられるでしょう。あなた独自のコードの再テストと書き直しが必要になるような頻繁なアップデートがあってもかまわないというのでない限り、eXistを実働環境で使用しないでください。
データが増えるほど、何らかの種類のデータベースを使用してデータを管理することが重要になってきます。データがXMLの場合は、安定したネイティブXMLデータベースを使用すべきです。eXistは、そのような安定したシステムでしょうか。悲しいことに、答えはノーです。eXistは面白い研究プロジェクトであり、1年か2年のうちに実用的なツールに発展するかもしれません。しかし、現在の状態では、推奨はできかねます。マニュアルは不完全であり、誤解を招く記述も少なくありません。エラー・メッセージは存在しません。(すべてのプログラマーへの注:例外スタック・トレースは、まともなエラー・メッセージとしてカウントせず、eXistはエラー・メッセージすら表示しません。)GUIは、あらゆる点でユーザー・インターフェース標準に反しています。コピー・アンド・ペーストのような基本的機能が省かれています。この記事のために行ったごく基本的なテスト中に、何度もバグに遭遇しました。
eXistは、まだ完成していません。現在はベータとして分類されています。私が遭遇した問題の多くは、バージョン1.0公開前に修正されるかもしれませんが、今日、明日のことではなさそうです。すでにeXistを実際の仕事に使っている人がいるのはわかっていますが、心配です。彼らは非常にラッキーか、eXistのバグを避けるように慎重にクエリーとドキュメントを工夫しているか、どちらかです。やりがいのあるオープン・ソース・プロジェクトに貢献することに興味がある場合は、eXistはその候補となります。しかし、時間に余裕のあるプログラマーにとって、eXistは不完全だからこそ面白いプロジェクトですが、その不完全さゆえに、実働システムには適さないものとなっています。
- SourceForgeからeXistをダウンロードしてください。
- eXistは、XML Apache ProjectのCocoonアプリケーション・サーバーの上に位置しており、Jettyサーブレット・エンジンをバンドルしています。しかしeXistは、例えばApache Jakarta ProjectのTomcatなど、他のサーブレット・コンテナーの中に統合することもできます。
- eXistインストーラーは、Julien PongeによるオープンソースのIzPackで構築されました。
- Elliotte Rusty Haroldの著書、Processing XML with Java(2002年、Addison Wesley Professional刊)を読んでください。オンラインで読むこともでき、また紙の本を購入することもできます。
-
Java Network Programming(2004年、O'Reilly Media刊)を読んで、URLクラスやURLConnectionクラスが、eXistのRESTインターフェースなどのHTTPサーバーとどのように通信するかについて学んでください。
- 様々なタイプのデータベース・システムでXMLを使うための方法を、Ronald Bourretが堅実に紹介しています。
-
Java Specification Request 225, XQuery API for Javaのエキスパート・グループを、IBMとOracleが主導している様子を調べてください。現在、この仕様の初期ドラフトが見られるようになっています。
- W3CのXQueryは、印刷すると何百ページにもなります。著者は、XML Query Use Casesから始めることをお勧めします。
- W3C勧告を読んで、XML Path Language (XPath)について学んでください。
-
XUpdate仕様を読んでください。
- 著者のサーバーであるElizaは、Neal StephensonによるBaroque Cycleの、Eliza de la Zeurにちなんで名付けられました。
- Elliotte Rusty HaroldがdeveloperWorksで書いている、XMLデータの管理 シリーズの、これまでの記事も読んでください(日本語化されていない記事もあります)。
- developerWorksのXMLゾーンには、XMLに関する資料が豊富に用意されています。
-
XMLおよび関連技術においてIBM認証開発者になる方法については こちら を参照してください。

Elliotte Rusty Haroldはニューオーリンズ出身であり、時たま、おいしいgumbo(オクラ入りのスープ)を食べに帰っています。ただし現在はニューヨークのブルックリン近郊のProspect Heightsに、妻のBethと猫のCharm(charmed quarkからとりました)とMarjorie(義理の母の名前からとりました)と一緒に住んでいます。彼はPolytechnic Universityのコンピューター・サイエンスの非常勤教授として、Java技術とオブジェクト指向プログラミングを教えています。彼のCafe au Lait Webサイトは、インターネット上で最も人気のある独立系Javaサイトの一つです。また、そこから派生したCafe con Lecheは、最も人気のあるXMLサイトの一つです。彼の最近の著作には『Java I/O, 2nd edition』があります。現在はXML処理用のXOM APIやJaxen XPathエンジン、Jesterテスト・カバレッジ・ツールなどに取り組んでいます。