使用XQEngine來搜尋XML檔案內容

才智咖 人氣:2.61W

最近我一直在尋找XML搜尋工具,我編寫的應用程式需要定期的搜尋一些有關聯的XML檔案,我本來的意思是為了看一看檔案中是否有與我想要的資料匹配的資料,但是有時候,我也想把找到的這些資料輸出出來。一開始,我試用了一下XSLT和XPath,想通過把搜尋的問題轉化成使用XSLT能夠解決的問題,但是經過一段時間的試驗,我發現,使用XSLT並沒有真正解決我想要處理的搜尋問題,因為我想要輸出的資料是使用逗號隔開的數,而XSLT不能滿足這個要求,而且XLST也不能提供全文搜尋功能。然後我想嘗試一下使用XML查詢語言(XQL),來看看能不能解決,所以我仔細的著了一下XQL的各種版本的實現,很巧,正好發現一個叫XQEngine的小工具能解決這個問題,所以,在本文中我想介紹一下如何使用XQEngine來在你的XML檔案中搜尋你想要找的字串資料。

使用XQEngine來搜尋XML檔案內容

XQEngine可以在網站下找到,它是一個JavaBean,使用一個SAX解析器來索引一個或多個XML文件,然後你就可以在這些文件中進行復合式搜尋了。它所使用的搜尋語言是XQL的超集,與XPath有相似的語法。

使用XQEngine的Java類必須實現一個result()方法,完成搜尋後,引擎將呼叫這個方法把搜尋結果傳到result()方法中,可以使用三種顯示資料的.格式來輸出資料結果。使用命令列引數指明你所需要的搜尋引數,比如說你可以指明一個檔案假如含有stop這個詞,就不會被索引;又如你可以在引數中命令引擎忽略那些少於指定子數的詞。

下面,我給出了一個使用XQEngine的例程,現在讓我們來分析一下。首先,main()方法例項化一個搜尋引擎:XmlEngine engine = new XmlEngine(),然後它從命令列中取得檔名、返回結果格式和搜尋請求這三個引數,再使用各種配置方法來設定引擎,接著呼叫setSaxParserName()方法來設定SAX解析器的全名,因為我們使用的是Xerces解析器,所以要用到 "arser"。然後我們就需要設定搜尋引數,再本例中,我們將不索引數字或任何少於3個字元的詞。在你下載到的XQEngine的API文件當中會有詳細的配置引數說明,所以在此我就不細說如何配置引數了,請大家自己參閱相關文件。最後,setDocument()方法指定XQEngine將要索引或搜尋的XML檔案。當然,如果你想要索引多個檔案的話,只需設定幾個相應的setDocument()方法就可以了。

從下面的程式碼中我們還可以看到,XQEngine引擎將用三種不同的格式返回搜尋結果:STANDARD、SUMMARY和CSV(使用逗號分開的數值)為了簡單起見,我為每種返回結果型別定義了一個數字來代替(1,2,3),然後使用相應的引數呼叫setListenerType()方法。我將在後面詳細介紹每一種返回結果型別。還有個方法printSessionState()用來輸出索引和引擎的資訊,但是我沒有把它寫進例程中,所以上面的程式只會輸出搜尋結果;下一步再呼叫addXQLResultListener()方法,並傳遞Search的一個例項,用來實現XQLResultListener的介面;然後再把查詢字串作為一個引數來呼叫setQuery方法,引擎就會開始執行查詢任務。等到查詢結束後,引擎呼叫Search類的result()方法,把查詢結果傳回,在我提供的例程中,result()方法只是簡單的把結果輸出出來。

 程式碼:

import .*;

import ngine;

import ptions.*;

import esultListener;

public class Search implements XQLResultListener

{

public static void main( String[] args )

{

XmlEngine engine = new XmlEngine();

String searchFile = args[0];

String searchType = args[1];

String query = args[2];

try { file://配置引擎

axParserName( "arser");

inIndexableWordLength( 3 );

oIndexNumbers( false );

ocument( searchFile );

if (ls("1")) {

istenerType(

DARD_LISTENER);

}

else if (ls("2")) {

istenerType(

ARY_LISTENER);

}

else {

istenerType(

_LISTENER);

}

}

catch( MissingOrInvalidSaxParserException e ){

tln(

"缺少或不可用的 SAX解析器" );

return;

}

catch( FileNotFoundException e ) {

tln(

"不能找到 XML 檔案: ");

return;

}

catch( CantParseDocumentException e ) {

tln(

"不能解析 XML 檔案: ");

return;

}

// tSessionStats();

QLResultListener( new Search() );

try {

uery( query );

}

catch( InvalidQueryException e ) {

tln(

"不可用的查詢請求: " + essage() );

return;

}

}

public void results( String xqlResults )

{

tln( xqlResults );

}

}

好,我們已經把一個使用XQEngine的程式編寫出來了,那麼就讓我們來執行這段程式碼,在編譯這段程式碼之前,我們需要下載到XQEngine和SAX解析器。我是從上下載到Xerces解析器的。我使用的作業系統是Windows 2000 Professional,JDK為1.3版,好,搞定這些以後就跟我來設定CLASSPATH吧,在"環境變數"中修改CLASSPATH,新增"c:;c:; c:"。現在就可以編譯程式碼了,不過為了能夠執行程式,我們還需要一個XML檔案,我使用了Apache Tomcat裡的檔案作為演示。前面我也介紹過了,我們使用1,2,3來分別代替三種返回查詢結果格式:

1、使用STANDARD_LISTENER (數字1)和查詢項"//welcome-file-list/welcome-file",C:xqlxql1>java Search 1 "//welcome-file-list/welcome-file"

allSaxParser:

<arser>

installed successfully

1: indexing

Query: ( // ( / welcome-file-list welcome-file ) )

3 hit(s) for file://welcome-file-list/welcome-file

<?xml version="1.0"?>

<xql:result

query="//welcome-file-list/welcome-file"

hitCount="3"

elemCount="3"

docCount="1"

xmlns:xql=" Standard_">

<welcome-file>

</welcome-file>

<welcome-file>

</welcome-file>

<welcome-file>

</welcome-file>

</xql:result>

上面的例子中,查詢項要求找到任何"welcome-file-list"元素的所有的"welcome-file"子元素。請注意,搜尋的結果基本上是從原XML文件中摘錄出來的,不能夠建立搜尋結果和原文件之間的關係。SUMMARY_LISTENER(2)返回型別則有些不同,它包括一個"docID"號和一個"elemlx"號,這樣就能夠把結果和原文件聯絡起來了。

 如下是返回結果的示例:

C:xqlxql1>java Search 2

"//welcome-file-list/welcome-file"

allSaxParser: <arser>

installed successfully

1: indexing

Query: ( // ( / welcome-file-list welcome-file ) )

3 hit(s) for file://welcome-file-list/welcome-file

<?xml version="1.0"?>

<xql:result

query="//welcome-file-list/welcome-file"

hitCount="3"

elemCount="3"

docCount="1"

xmlns:xql="

Summary_">

<welcome-file xql:docID="0" xql:elemIx="270"/>

<welcome-file xql:docID="0" xql:elemIx="271"/>

<welcome-file xql:docID="0" xql:elemIx="272"/>

</xql:result>

我前面也說過,對於我的應用程式來說,最重要的是返回使用逗號隔開的返回結果,所以CSV_LISTENER(3)就很有用了,它能夠返回一個使用使用逗號隔開的結果,如下:

C:xqlxql1>java Search 3

"//welcome-file-list/welcome-file"

allSaxParser:

<arser>

installed successfully

1: indexing

Query: ( // ( / welcome-file-list welcome-file ) )

3 hit(s) for file://welcome-file-list/welcome-file

3,3,1,0

0,270,welcome-file

0,271,welcome-file

0,272,welcome-file

當然,XQEngine還有很多很強大的功能,在此我不可能一一介紹,它所附帶的文件中有豐富的源程式和使用方法,你可以對照著自己學習使用,當然,如果你願意的話你甚至還可以開發出一個GUI程式,文件中就自帶了一個基於GUI的搜尋程式:SwingQueryDemo,你可以看一看研究研究。