用Java實現可儲存狀態的資料庫產生XML樹(3)
來源:互聯網
上載者:User
xml|產生xml|資料|資料庫 4.4.構造顯示樹型結構的XSL模版
在上面的demotree.xml,是不能單獨顯示出如圖一一樣的樹結構的,需要把XML檔案用XSL模版來轉換。
在這裡實際上需要把XML文檔用模版格式為以下樣式:
<ul>
<li></li>
<li></li>
<ul>
<li></li>
<li></li>
</ul>
</ul>
每一個li表示一個子節點,ul表示其上的li為一樹杈,其下的li為其子節點,可能為樹杈,可能為葉子,取決於該子節點是否具有ul。
XSL模版功能定義著如何轉化嵌套的node節點為嵌套的ul和li表示。
模版轉化的關鍵代碼:
<xsl:template match="node">
<xsl:for-each select=".[number(layer) $eq$ 0 ]"><!—對於每一個節點,如果他的layer值為0,進行下面的代碼變化-->
<xsl:if test=".[href $eq$ '']"><!—如果節點的href域為空白,說明其為樹杈,需要檢索其下面的嵌套node-->
<xsl:element name ="li"><!—對於li標籤,不僅僅是指定其id為goldheader,還指定其序號no為該節點的id值-->
<xsl:attribute name="id">foldheader</xsl:attribute>
<xsl:attribute name="no"><xsl:value-of select="id"/></xsl:attribute>
<xsl:value-of select="value"/>
</xsl:element>
……
</xsl:if>
<xsl:if test=".[href $ne$ '']"> <!—如果節點的href域不為空白,說明其為葉子,轉換為li格式,並把連結,目標框架,顯示字串的值以超連結的形式顯示出來-->
<li><xsl:element name ="a">
<xsl:attribute name="HREF">
<xsl:value-of select="href"/>
</xsl:attribute>
<xsl:attribute name="TARGET">
<xsl:value-of select="target"/></xsl:attribute>
<xsl:value-of select="value"/>
</xsl:element>
</li>
</xsl:if>
</xsl:for-each>
</xsl:template>
因為瀏覽器對XSL支援的不同,所以在目前的瀏覽器使用比例上言,MSIE是可以作為預設瀏覽器標準來定義的,在不安裝MSXSL3的情況下,MSIE只是支援XSL2,對XSL變數等不支援,所以,在這裡的實現過程中以嵌套的代碼來實現替換變數實現的效果。整體的代碼比較冗長,但易於讀寫和修改。不對代碼進行重複,具體請參見treefunc.xsl檔案中從<xsl:template match="node">開始到</xsl:template>結束的中間的代碼實現。
樹狀顯示還依賴於js的支援,js定義著點擊樹杈時樹的顯示變化,例如,噹噹前點擊樹杈節點為收縮狀態時,點擊的效果是展開該樹杈,顯示樹杈的下級節點,反之亦然。
首先對ul和li進行類的標識,對於樹杈的li,定義其元素的id為’ foldheader’,對於其下跟隨的ul定義其元素的id為’ foldinglist’,style.display為’none’或者’’,然後定義一個change函數,功能為點擊樹杈節點後的介面變化。
同時因為樹結構的層次可能會比較深,需要考慮到客戶瀏覽時,在重新整理頁面或者重新開啟同一頁面時應該儲存住客戶最後瀏覽的樹的層次,在這裡實現的方式是用cookie保持每個樹杈的是否展開的布爾值,
對cookie的操作函數和對點擊事件的操作函數都在treefunc.xsl檔案中,下面是javascript編寫的對XML產生樹進行HTML動作處理的方法,
/*說明是在載入頁面時就要發生的動作*/
var temp_str = 'thexmltreecookie';/*定義一個字串,用於在cookie中尋找節點展開狀態*/
var fl_n = 0;
temp_str = temp_str + "=";
for (i=0;i<foldinglist.length;i++){/*把所有的樹杈都預設為未展開,並統計個數*/
temp_str=temp_str+"0:";
}
temp_str = temp_str.substring(0,temp_str.length-1);
fl_n = temp_str.length -17 ;
if ((document.cookie == '')||(WM_readCookie('thexmltreecookie').length != fl_n)){/*當cookie不為空白,而且cookie中有正確對應的樹杈個數,讀取cookie中儲存的樹杈狀態*/
document.cookie = temp_str;/*檢驗cookie中值不為正確,則賦予新值*/
}
else {
/*cookie中儲存的樹杈狀態形如”1:0:0:0:1”,這表示第一和第五節點是展開的,第二,三,四節點是收縮的,這種形式並沒有儲存樹的層次屬性,所以,這裡的節點展開沒有一一反應到樹的表現上來,例如:如果第五節點是第四節點的子節點,那麼儘管第五節點是展開的,但因為父節點未展開,所以在查看樹時,是不可能看到第五節點的,只有當第五節點的父節點,祖父節點,直到頂層節點都為展開狀態,第五節點才為可視的展開狀態.這裡用函數WM_readCookie()方法取得樹杈狀態字串,並把它按’:’分開,放入數組temp_s中*/
var temp_s = WM_readCookie("thexmltreecookie").split(":");
/*從第一個樹杈開始,根據樹杈字串相應位置的取值,設定該樹杈節點的顯示內容*/
for (i=0;i<foldinglist.length;i++){
if (temp_s[i] == 0){
var tb =0;
for (j=0;tb < 1;j++){
if (document.all[j] == foldinglist[i]){
tb = 1;
document.all[j-1].style.listStyleImage="url(/images/fold.gif)";
}
}
foldinglist[i].style.display="none";
}
else {
var tb =0;
for (j=0;tb < 1;j++){
if (document.all[j] == foldinglist[i]){
tb = 1;
document.all[j-1].style.listStyleImage="url(/images/open.gif)";
}
}
foldinglist[i].style.display="";
}
}
}
/*函數changge()是點擊頁面時觸發的動作,*/
function change(){
/*點擊的對象是頁面上的元素動作才繼續*/
if(!document.all)
return;
/*由temp_ss數組得到樹杈節點的展開屬性*/
var temp_ss =WM_readCookie("thexmltreecookie").split(":");
var temp_s = 'thexmltreecookie';
temp_s = temp_s + '=';
/*如果點擊元素是樹杈,則繼續動作,這裡判斷是否樹杈是通過判斷點擊對象的id是否為foldheader*/
if (event.srcElement.id=="foldheader") {
/*srcIndex賦值為點擊HTML元素的在HTML文檔中的序號*/
var srcIndex = event.srcElement.sourceIndex;
/*nested賦值為點擊元素的下一個元素,是<ul>元素,樹杈節點的控制元素,通過控制該元素的屬性可以控制該樹杈是否顯示和顯示的圖片*/
var nested = document.all[srcIndex+1];
/*遍曆樹杈節點,作用是當點擊的對象是遍曆到的HTML元素時,做相應的變化,如,更改cookie中樹杈狀態字串,使點擊的節點展開或縮回其子節點,在cookie中儲存當前點擊節點的Id值*/
for (i=0;i<foldinglist.length;i++){
if (foldinglist[i] == nested){
/*定義變數ClickId,儲存點擊對象的no屬性,no屬性是指該節點在XML中取得的id屬性值*/
var ClickId;
ClickId = "ClickId="+event.srcElement.no;
document.cookie =ClickId;
if (temp_ss[i]==0){
temp_ss[i]=1;
}
else {
temp_ss[i]=0;
}
}
}
for (i=0;i<foldinglist.length;i++){
temp_s =temp_s+temp_ss[i]+':';
}
temp_s = temp_s.substring(0,temp_s.length-1);
document.cookie = temp_s;
/*更換相應的圖片*/
if (nested.style.display=="none") {
nested.style.display=''
event.srcElement.style.listStyleImage="url(/images/open.gif)"
}
else {
nested.style.display="none"
event.srcElement.style.listStyleImage="url(/images/fold.gif)"
}
/*重新整理其他的頁面*/
top.topFrame.location.reload();
}
}
/*指定在頁面中點擊事件的處理函數為change()*/
document.onclick=change;
/*函數WM_readCookie(name)用來調用WM_getCookieValue(name)取得在cookie中以name為名稱的cookie串的值*/
function WM_readCookie(name){
//如果沒有cookie則返回false或者取得值並返回該值
if(document.cookie == ''){
return false;
}
else {
return unescape(WM_getCookieValue(name));
}
}