Xindice:無料で使えるXMLデータベース(3)

サーブレットからのXMLデータベース検索


3-2. Xindiceを呼び出すサンプルサーブレット

 Xindiceを呼び出すサンプルサーブレットとして、最初に、Xindiceから検索した結果をXML文書として返すもの、次に結果をXSLTでHTMLに変換して返すものを紹介します。

 このサンプルサーブレットでは、連載第1回「ネイティブXMLデータベースを立ち上げる!」で使ったデータベースインスタンスをそのまま利用しますので、データベースを用意していない場合は第1回を参照してデータベースインスタンスを準備してください(第2回のものでも構いません)。

 また、サーブレットのコンパイルのためには以下のようにクラスパスを設定しておく必要があります。このクラスパスは第2回「JavaアプリケーションによるXMLデータベース検索」で設定したものにservlet.jarを追加したものになっています。

Windows
C:\> set XINDICE_LIB=%XINDICE_HOME%\java\lib
C:\> set CLASSPATH=.;%XINDICE_LIB%\xmldb.jar;% XINDICE_LIB%\xindice.jar;%XINDICE_LIB%\openorb-1.2.0.jar;%XINDICE_LIB%\xerces-1.4.3.jar;%XINDICE_LIB%\xalan-2.0.1.jar;%CATALINA_HOME%\common\lib\servlet.jar
UNIX系(Bシェル)
$ XINDICE_LIB=$XINDICE_HOME/java/lib
$ export CLASSPATH=$XINDICE_LIB/xmldb.jar:$XINDICE_LIB/
xindice.jar:$XINDICE_LIB/openorb-1.2.0.jar:$XINDICE_LIB/
xerces-1.4.3.jar:$XINDICE_LIB/xalan-2.0.1.jar:$CATALINA_HOME/common/lib/servlet.jar

XPath式の結果をXML文書として返す

 まずは、XindiceからXPath式「//action」で検索した結果を単純にXML文書として返すサーブレットを紹介します。大事なところだけを抜き出したので、リスト全体を参照するときは、リストの最後にあるリンクからダウンロードしてください。また、リスト後半の「1.」「2.」…などと番号が振ってあるところは、前回の「ネイティブXMLデータベースを立ち上げる!」で詳しく解説したところです。その解説と同様に番号が振ってありますので、このリストでは「4」に相当する部分がありません。

… 略 …
public class XindiceServlet extends HttpServlet {
  // HTTP GETに対応するメソッド
  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    … 略 …

    try{
        // 検索した結果をXMLで出力します
        String xpath = "//action";
        serialize(out, xpath);
      }
     catch (Exception e) {
          throw new ServletException(e);
      }
     finally {
         out.close();
      }
  }

  // 検索した結果をDOMで受け取ってoutにシリアライズします
  public void serialize(Writer out, String xpath) throws Exception {
    … 略 …
  }

// XindiceからXPathを使って検索します
private Document searchWithXindice(String xpath) throws Exception {
  Collection col = null;

  // 検索結果をまとめる要素<result>を作成する   
  javax.xml.parsers.DocumentBuilderFactory docBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
  docBuilderFactory.setNamespaceAware(true);
  Document resultDocument = docBuilderFactory.newDocumentBuilder().newDocument();
  // 次の設定はXindiceから取得したDOMオブジェクトを
  // Xercesでimportする ためには必要

  ((org.apache.xerces.dom.DocumentImpl) resultDocument).setErrorChecking(false);
  Element resultElement = resultDocument.createElement("result");
  resultDocument.appendChild(resultElement);

  try {
    // 1. Database実装クラスの登録
… 略 …
    // 2. コレクションの取得
… 略 …
    // 3. XPathQueryServiceの取得
    XPathQueryService service = (XPathQueryService) col.getService("XPathQueryService", "1.0");
    // 5. XPathで検索
    ResourceSet resultSet = service.query(xpath);
    // 6. ResourceSetから検索結果を取り出す
    ResourceIterator results = resultSet.getIterator();
    while (results.hasMoreResources()) {
      Resource res = results.nextResource();
      if (res.getResourceType().equals("XMLResource")) {
        org.xmldb.api.modules.XMLResource xmlres = (org.xmldb.api.modules.XMLResource)res;
        org.w3c.dom.Node node = xmlres.getContentAsDOM();
        resultElement.appendChild(
          resultDocument.importNode(node.getFirstChild(), true));
        }
      }
    }

    catch (XMLDBException e) {
      throw new ServletException(e);
    }
    finally {
      if (col != null) {
        // 7. コレクションのクローズ
        col.close();
      }
    }
    return resultDocument;
  }
}
XindiceServlet.java
サーブレットからXindiceへXPathで検索をかけ、結果をXML文書で受け取る(リストのダウンロード

 実際の検索を行うsearchWithXindiceメソッドは、前回の記事のサンプルコードとほぼ同様で、1から3までがXPathで検索するための準備、5で実際の検索を行なって、6で検索結果を処理しています。最大の違いは、検索結果を要素<result>の子要素として表現していることです。searchWithXindiceメソッドの先頭で要素<result>を作成し、6で検索結果を要素<result>に追加しています。

 6の追加の具体的な処理内容は、検索結果のリソースの内容(Documentオブジェクト)をgetContentAsDOMメソッドで取り出し、その要素をimportNodeメソッドで要素<result>のDocumentオブジェクトにコピーした上で追加しています。

 作成した要素<result>を含むXML文書は、serializeメソッドでサーブレットの出力として書き出されます。このメソッドは、検索結果のDocumentオブジェクトをXercesのXMLSerializerクラスを用いてエンコーディングし、Shift_JISのXML文書として文字列に変換します。

 結果のXML文書を見るには、XML文書をそのまま表示可能なWebブラウザ(例えばIE 5.0以降など)で「http://localhost:8080/XindiceSample/servlet/XindiceServlet」にアクセスしてください。うまく動作していれば、次のようなXML文書が表示されるはずです。

<?xml version="1.0" encoding="Shift_JIS"?>
<result><action src:col="/db/sampledb" src:key="prob1" who="A_company" xmlns:src="http://xml.apache.org/xindice/Query">
    <description>
      タイムアウト値を変更できるパッチを出す。
    </description>
  </action><action src:col="/db/sampledb" src:key="prob1" who="B_corporation" xmlns:src="http://xml.apache.org/xindice/Query">
    <description>
      レスポンスセンターに問い合わせる。
    </description>
</action><action src:col="/db/sampledb" src:key="prob2" who="A_company" xmlns:src="http://xml.apache.org/xindice/Query">
    <description>
      開発元に問合せ。
    </description>
   </action><action src:col="/db/sampledb" src:key="prob2" who="C_customer" xmlns:src="http://xml.apache.org/xindice/Query">
    <description>
      情報収集
    </description>
  </action></result>
検索結果として示されるXML文書

結果をXSLTでHTMLに変換する

 次にこのサーブレットをXSLTを使ってHTMLを出力するよう変更してみます。

… 略 …

public class XindiceServlet2 extends HttpServlet {

  // HTTP GETに対応するメソッド

  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    // HTMLで返します
    response.setContentType("text/html; charset=Shift_JIS");
    PrintWriter out = response.getWriter();
    try {
      // 検索した結果をXSLTでHTMLに変換し出力します
      transform(out, getServletContext().getRealPath("/sample.xsl"));
    }
    catch (Exception e) {
      throw new ServletException(e);
    }
    finally {
      out.close();
    }
  }

  // 検索した結果をスタイルシートstylesheetUrlを使って
  // XSLTでHTMLに変換し、outに出力します

  public void transform(Writer out,
      String stylesheetUrl) throws Exception {
    String xpath = "//action";
    javax.xml.transform.Transformer transformer = getTransformer(stylesheetUrl);
    transformer.transform(new javax.xml.transform.dom.DOMSource(searchWithXindice(xpath)), new javax.xml.transform.stream.StreamResult(out));
  }
  // JAXPを使ってXSLTに使うTransformerを得ます
  private javax.xml.transform.Transformer getTransformer(String url) throws Exception {
    javax.xml.transform.TransformerFactory tFactory = javax.xml.transform.TransformerFactory.newInstance();
    javax.xml.transform.Transformer transformer;
    transformer = tFactory.newTransformer(new javax.xml.transform.stream.StreamSource(url));
    return transformer;
  }


  // XindiceからXPathを使って検索します
  private Document searchWithXindice(String xpath) throws Exception {
    Collection col = null;
    // 検索結果をまとめる要素<result>を作成する
    … 略 …

    return resultDocument;
  }
}
XindiceServlet2.java
サーブレットからXindiceへXPathで検索をかけ、結果をXSLTでHTML文書へ変換する(リストのダウンロード

 前のサーブレットと違うのは、単純なシリアライズを行うserializeメソッドの代わりに、XSLTによる変換を行うtransformメソッドを使うようにしたところです。searchWithXindiceメソッドは同じです。

 作成した要素<result>を含むドキュメントは、transformメソッドでサーブレットの出力として書き出されます。このメソッドは、検索結果のDocumentオブジェクトにJAXPのTransformerクラスを用いてsample.xslを適用し、エンコーディングShift_JISのHTMLに変換します。

変換のためのXSLTは別ファイル

 次に示すXSLTで使うスタイルシートsample.xslをXindiceSampleディレクトリに置いてください。

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" encoding="Shift_JIS"/>
  <xsl:template match="result">
    <html>
      <head>
        <title>検索結果</title>
      </head>
      <body>
        <p>
          <table border="1">
            <tr><th>Who</th><th>Description</th></tr>
            <xsl:apply-templates/>
          </table>
        </p>
      </body>
    </html>
  </xsl:template>

   <xsl:template match="action">
    <tr><td>
      <xsl:value-of select="@who"/></td><td><xsl:value-of select="description"/>
    </td></tr>
  </xsl:template>

</xsl:stylesheet>
sample.xsl 結果のXMLをHTMLへ変換するXSLT(リストのダウンロード

 結果を見るには、Webブラウザで「http://localhost:8080/XindiceSample/servlet/XindiceServlet2」にアクセスしてください。うまく動作していれば、次のようなHTMLが表示されるはずです。

サーブレットからXindiceに問い合わせ、結果をHTMLで返した場合の表示

6/9

Index
Xindice:無料で使えるXMLデータベース
  Xindiceをインストールする(Windows/UNIX)
・Javaで作られたXindice
・ネイティブXMLデータベースの特徴
・Xindiceの特徴
・Xindiceをインストールする
  XMLデータベースの作成と基本的な検索
・起動と停止
・コマンドラインからXindiceを利用する
・コレクションとドキュメント
・では、検索してみよう
・Xindiceの主なコマンド一覧
  Javaプログラムによる検索の手順
・検索用APIの使い方
  検索サンプルアプリケーションの実際
・例外
・XPath
・Xindiceで検索するサンプルアプリケーション
・ネームスペースを利用しない例
・ネームスペースを利用する例
  サーブレットからXindiceを呼び出す
・サーブレット環境の準備
・Webアプリケーションの準備
Xindiceを呼び出すサンプルサーブレット
・XPath式の結果をXML文書として返す
・結果をXSLTでHTMLに変換する
・変換のためのXSLTは別ファイル
  インデックスで高速化
・インデックス管理コマンド
・インデックスの有無によるスピード比較
・測定結果
  XUpdate言語の使い方
・現在ドラフト中のXUpdate
・ノードの挿入・追加
・ノードの更新
ノードの削除
・ノード名変更
  Javaアプリケーションから更新・削除を実行する
・更新用APIの使い方
・サンプルアプリケーション
・実行準備


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

注目のテーマ

HTML5+UX 記事ランキング

本日月間