[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 編程技術 > XML/WML > 正文
用XML優化二次檢索
本文出自:http://www.computerworld.com.cn 作者:華中科技大學 李鋒 魏瑩 (2002-01-29 20:53:13)
在搜索引擎的設計以及類似的軟件功能設計中,一個必不可少的功能就是:對已有搜索結果的二次檢索。如果檢索的數據集是靜態數據(例如存放在數據庫中),通常的做法是在已有的檢索條件的基礎上,動態加入新的約束條件。但是重新構造數據檢索的約束條件,往往需要用戶同服務器再次交互,重新下載所需數據集合並輸出。如果能在客戶端對已經下載的數據集合進行二次檢索,將極大地減輕Web服務器以及數據庫服務器的負擔。
XML能夠很大程度地滿足以上需求。它將數據內容本身與數據顯示格式獨立開來,分別處理。這樣,如果需要改變文檔的顯示方式,只要修改樣式文件(XSL)就可以了。XML的自我描述特性能夠很好地表現許多復雜的數據關系,使得基XML的應用程序可以在XML文件中準確高效地搜索相關的數據內容,忽略其他不相關的部分。同時,整個數據操作都是在客戶端完成,大大減輕了服務器的負擔。
XML編程接口DOM簡介
DOM(Document Object Model,文檔對象模型)是一種與平台和語言無關的編程接口,它允許程序和腳本動態訪問和修改文檔的內容結構和類型。它定義了一系列的對象和方法對DOM樹的節點進行各種隨機操作。
● Document對象:是DOM樹的最頂層節點,是對整個文檔進行操作的入口。
● Element和Attr對象:這些節點對象都是文檔某部分的映射,節點的層次恰好反映了文檔的結構。
● Text對象:作為Element和Attr對象的子節點,Text對象表達了元素或屬性的文本內容。Text節點不再包含任何子節點。
● 集合索引:DOM提供了多種集合索引方式,可以對節點按指定方式進行遍歷。
DOM採用以上介紹的一系列接口來描述XML文檔的內容和結構,即利用對象將文檔模型化。這種對象模型實現的基本功能包括:
● 描述文檔表示和操作的接口;
● 接口的行為和屬性;
● 接口之間的關系以及互操作。
DOM對結構化的XML文檔進行解析,文檔中的元素、實體、屬性等所有個體都可以用對象模型表示。整個文檔的邏輯結構類似一棵樹,生成的對象模型就是樹的節點,每個對象同時包含了方法和屬性。DOM提供了許多查找節點的方法。其中用搜索的方法有:
● 根據標簽名稱搜索元素: 利用Document對象中的getElementsByTagName方法在全文范圍內查找元素;
● 使用XSL模式搜索節點:所有類型的節點都帶有selectNodes方法,調用這個方法可以利用XSL的模式匹配策略查找節點;
● 使用集合索引搜索節點: 索引參數都是從0開始計數的,例如子節點ChildNodes對象集。
利用DOM,開發人員可以動態地創建XML、遍歷文檔、增加(刪除/修改)文檔內容。DOM提供的API與編程語言無關,所以對一些DOM標準中沒有明確定義的接口,不同解析器的實現方法有可能有所差別。本文的示例採用MSXML DOM方案,並採用IE 5.0作為輸出顯示的瀏覽器。
軟件實現
以下用一個簡單的學生成績查詢系統為例具體說明如何實現。可以先按照學生所在的班級將學生成績查詢出來,然可以選出平均分高設定分數(用一個文本框接收設定分數)的學生列表。
在SQL Server中包含一個學生成績表,關鍵字段有:學生姓名(Name)、班級(Class)、單科成績(YuWen、ShuXue、JiSuanJi、YingYu等)、平均成績(AverageScore)。
首先,編輯初始頁面以提供按班級查詢學生成績的功能。
<form method=post action=MyRearch. asp>
輸入班號: <input type=text name=ClassName>
<input type=submit value=“提交”><input type=reset value=“重填”>
</form>
MyRearch.asp文件中,提供按平均成績查詢的二次查詢功能。關鍵代碼如下:
<%@ Language=VBScript %>
//建立數據庫連接,並根據用戶需求,從數據庫中檢索出所有符合要求的數據集
<% Set Conn=Server.CreateObject(“ADODB.connection”) %>
<% Set rs=server.CreateObject(“ADODB.recordset”) %>
<% Conn. open Application(“SQLserver
Conn”) %>
<% sqlText=“select * from ScoreTable where Class=‘” %>
<% sqlText=sqlText & request.Form(“ClassName”) & “’” %>
<% set rs=conn.Execute(sqlText) %>
<% rs.MoveFirst %>
//在HMTL文件中建立一個XML數據對象(XML數據島)
//並且將數據庫檢索的數據集寫入該數據島中
<XML ID=“StudentList”> //該數據對象的唯一標識為StudentList
<?xml version=“1.0” ?>
<Students>
<% do while not rs.EOF %>
<Student>
<% for i=0 to rs.Fields.Count-1 %>
//以數據庫表的列名為XML節點的節點名
<<%=rs.Fields(i).Name %>>
   <%=rs.Fields(i).Value %>
 </<%=rs.Fields(i).Name %>>
<% next %>
<% rs.MoveNext %>
</Student>
<% loop %>
</Students>
</XML>
//二次檢索的結果集XML對象(XML數據島)
<XML ID=“QueryResult”>
<?xml version=“1.0” ?>
</XML>
<HTML>
<HEAD>
<script language=vbscript>
sub BtnRearch_onClick
//獲得第二次檢索的結果集對象(XML數據島對象)
set doc=QueryResult.XMLDocument
//獲得該結果集的根節點
set oldNode=doc.DocumentElement
//刪除該根節點
doc.removeChild oldNode
//重新創建一個根節點對象,名稱為Students
set rootNode=doc. createElement(“Students”)
//重新生成根節點
doc.appendChild rootNode
//獲得第一次檢索的結果集對象
set doc1=StudentList.XMLDocument
//獲得該對象的根節點
set rtNode=doc1.documentelement
AvaScore=document.forms(0).Score.value
rearchStr= “Student[Average>” & AvaScore & “]”
//設定新的搜索條件(二次)
set SecondList=rtNode.selectNodes(rearchStr)
for each node in SecondList
//從第一次檢索的結果集中復制符合搜索條件的節點
  set newNode=node.cloneNode(true)
  //將符合條件的節點動態添加到二次檢索結果集的根節點上
  rootNode.appendChild newNode
next
end sub
</script>
</HEAD>
<BODY>
//將第一次檢索的結果綁定到HMTL文件的一個TABLE對象中
<table datasrc=“#StudentList”> //指定TABLE對象的XML數據源
<tr>
<% for i=0 to rs.Fields.Count-1 %>
<th><%=rs.Fields(i).Name %></th>
<% next %>
</tr>
<tr>
<% for i=0 to rs.Fields.Count-1 %>
  //指定TABLE對象每一列的XML數據字段,由TABLE的TD對象
  //本身不能綁定對象,所以只能借助DIV等對象綁定數據
<td><div datafld=“<%=rs.Fields(i).Name %>”></div></td>
<% next %>
</tr>
</table>
<form>
輸入期望的平均分:<input type=text name=Score value=80>
<input type=button name= BtnRearch value=“二次查詢”>
</form>
<h3 align=center>二次檢索結果:</h3>
//將二次檢索結果綁定到另外一個TABLE對象
<table datasrc=“#QueryResult”>
//指定XML數據源
<tr>
<% for i=0 to rs.Fields.Count-1 %>
<th><%=rs.Fields(i).Name %></th>
<% next %>
</tr>
<tr>
<% for i=0 to rs.Fields.Count-1 %>
<td><div datafld=“<%=rs.Fields(i).Name %>”></div></td>
<% next %>
</tr>
</table>
<% rs.Close %>
<% set rs=nothing %>
<% conn.Close %>
<% set conn=nothing %>
</BODY>
</HTML>
  動態生成的XML數據島對象如下:
<XML ID=“StudentList”>
<?xml version=“1.0”?>
<Students>
<Student>
<Name>李鋒</Name>
<Class>9703</Class>
<YuWen>86.5</YuWen>
<ShuXue>95.2</ShuXue>
<JiSuanJi>87.0</JiSuanJi>
<YingYu>78.6</YingYu>
<AverageScore>86.825</AverageScore>
</Student>
<Student>
<Name>王可</Name>
<Class>9601</Class>
<YuWen>82.7</YuWen>
<ShuXue>83.5</ShuXue>
<JiSuanJi>89.0</JiSuanJi>
<YingYu>77.3</YingYu>
<AverageScore>83.125</AverageScore>
</Student>
……
</Students>
</XML>
以上代碼在數據庫為SQL Server 7.0、操作系統為NT 4.0、Web服務器為IIS 4.0、瀏覽器為IE 5.0的條件下編譯調試通過。
結 論
由所有對數據集對象的操作是在客戶端完成的,實際上是服務器數據對象的一份復制品,這樣做的好處是避免了網絡承受大量數據通信的負擔。當然,這時用戶在客戶端做的所有操作對服務器上存儲的數據毫無影響,如果要想對服務器記錄也進行修改,那就要用到客戶端與服務器端的數據交互技術(XMLHTTP對象)了,這裡就不再進行討論。

(http://www.fanqiang.com)     進入【UNIX論壇

相關文章
 

★  樊強制作 歡迎分享  ★