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)); } }
|