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 |
|