- PR -

Xindiceのサーブレットでの日本語検索について

1
投稿者投稿内容
たか
会議室デビュー日: 2005/02/02
投稿数: 5
投稿日時: 2005-02-02 11:39
はじめまして。卒業研究でXindiceを使用していますが、サーブレットで日本語検索ができません。Javaアプリケーションプログラムでは、日本語検索ができるのですが。
以下はXindiceServlet.javaというサンプルを改造したプログラムです。
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
import org.w3c.dom.*;

public class XindiceServlet extends HttpServlet {

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

// XMLで返します
response.setContentType("text/xml; charset=Shift_JIS");

//ブラウザへの出力オブジェクトの取得
PrintWriter out = response.getWriter();

try {
// 検索した結果をXMLで出力します
String xpath = "//material[material_name=*[text()[contains(.,'きゃべつ')]]]";
serialize(out, xpath);
}
catch (Exception e) {
throw new ServletException(e);
}
finally {
out.close();
}

}
// 検索した結果をDOMで受け取ってoutにシリアライズします
public void serialize(Writer out, String xpath) throws Exception {
System.out.println(xpath);
org.apache.xml.serialize.OutputFormat format = new
org.apache.xml.serialize.OutputFormat("XML", "Shift_JIS", false);
format.setPreserveSpace(true);
org.apache.xml.serialize.XMLSerializer serializer = new
org.apache.xml.serialize.XMLSerializer(out, format);
serializer.serialize(searchWithXindice(xpath));
System.out.println("----------------------");
}

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

System.out.println("search_started");

// 検索結果をまとめる要素<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実装クラスの登録
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);

// 2. コレクションの取得
col = DatabaseManager.getCollection("xmldb:xindice:///db/MENU2db");

// 3. XPathQueryServiceの取得
XPathQueryService service =
(XPathQueryService) col.getService("XPathQueryService", "1.0");

// 5. XPathで検索
ResourceSet resultSet = service.query(xpath);

System.out.println("result_process_started");

// 6. ResourceSetから検索結果を取り出す
ResourceIterator results = resultSet.getIterator();
while (results.hasMoreResources()) {
System.out.println("ruselt_existed");
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();
org.w3c.dom.Node desc1 =
org.apache.xpath.XPathAPI.selectSingleNode
(node, "material/material_code");
System.out.println("材料コード :" + desc1.getFirstChild().getNodeValue());
org.w3c.dom.Node desc2 =
org.apache.xpath.XPathAPI.selectSingleNode
(node, "material/material_name");
System.out.println("材料名 :" +
desc2.getFirstChild().getNodeValue());
}
}
}
catch (XMLDBException e) {
throw new ServletException(e);
}
finally {
if (col != null) {
// 7. コレクションのクローズ
col.close();
}
}

return resultDocument;
}

}

上記プログラムを実行すると、
// 6. ResourceSetから検索結果を取り出す以下のルーチンで、while内が実行されません。ResourceSetに検索結果が返ってきていないようです。

また、日本語検索に成功しているJavaアプリは以下の通りです。
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
import org.w3c.dom.*;

public class Example1 {
public static void main(String[] args) throws Exception {
Collection col = null;
try {

//System.out.println(args[0]);

// 1. Database実装クラスの登録
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);

// 2. コレクションの取得
col = DatabaseManager.getCollection
("xmldb:xindice:///db/MENU2db");

// 3. XPathQueryServiceの取得
XPathQueryService service =
(XPathQueryService) col.getService("XPathQueryService", "1.0");

// 5. XPathで検索(ステータスがオープンのもの)
String xpath = "//material[material_name=*[text()[contains(.,'きゃべつ')]]]";

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();
org.w3c.dom.Node desc1 =
org.apache.xpath.XPathAPI.selectSingleNode
(node, "material/material_code");
System.out.println("材料コード :" + desc1.getFirstChild().getNodeValue());
org.w3c.dom.Node desc2 =
org.apache.xpath.XPathAPI.selectSingleNode
(node, "material/material_name");
System.out.println("材料名 :" +
desc2.getFirstChild().getNodeValue());
}
}
}
catch (XMLDBException e) {
System.err.println("XML:DB Exception occured " + e.errorCode);
}
finally {
if (col != null) {
// 7. コレクションのクローズ
col.close();
}
}
}
}
上記プログラムを実行すると、
// 6. ResourceSetから検索結果を取り出す以下のルーチンで、while内が実行され、検索結果が表示されます。ResourceSetに検索結果が返ってきています。

環境は、j2sdk1.4.2_07, Xindice1.0, jakarta-tomcat-4.0.4, OSはXPです。

>追記
最初に書いた内容に誤りがありました。訂正しましたので、よろしければ再読お願いします。

xpath式
コード:

xpath = "//material[material_name=*[text()[contains(.,'きゃべつ')]]]";


と、データベース検索&結果表示ルーチンは、サーブレット版、アプリ版と同様の処理です。
たとえば、xpath式の'きゃべつ'を'15'にすると、サーブレット版、アプリ版ともに、検索結果が返ってきます。

[ メッセージ編集済み 編集者: たか 編集日時 2005-02-02 15:02 ]

[ メッセージ編集済み 編集者: たか 編集日時 2005-02-02 15:03 ]

[ メッセージ編集済み 編集者: たか 編集日時 2005-02-03 16:49 ]

[ メッセージ編集済み 編集者: たか 編集日時 2005-02-03 16:50 ]

[ メッセージ編集済み 編集者: たか 編集日時 2005-02-03 16:54 ]

[ メッセージ編集済み 編集者: たか 編集日時 2005-02-04 22:26 ]
たか
会議室デビュー日: 2005/02/02
投稿数: 5
投稿日時: 2005-02-02 11:42


[ メッセージ編集済み 編集者: たか 編集日時 2005-02-02 15:04 ]
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2005-02-02 13:11
えーと、resultElementに対してxindiceから取得したノードを追加する必要があると
思うのですが。これだとxinciceから取得したものを表示しているだけですよね?
たか
会議室デビュー日: 2005/02/02
投稿数: 5
投稿日時: 2005-02-02 15:06
最初の投稿では、resultElementを定義していましたが、ソースコードの添付間違いでした。
実際は、xindiceの検索結果をそのまま表示している処理で、サーブレット版、アプリ版ともに同じことをしています。
1

スキルアップ/キャリアアップ(JOB@IT)