明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

用Java完成可保存狀態(tài)的數(shù)據(jù)庫生成XML樹(3)

[摘要]4.4.構(gòu)造顯示樹型結(jié)構(gòu)的XSL模版在上面的demotree.xml,是不能單獨(dú)顯示出如圖一一樣的樹結(jié)構(gòu)的,需要把XML文件用XSL模版來轉(zhuǎn)換。 在這里實(shí)際上需要把XML文檔用模版格式為以下樣式:<ul><li></li><li></li>...
4.4.構(gòu)造顯示樹型結(jié)構(gòu)的XSL模版
在上面的demotree.xml,是不能單獨(dú)顯示出如圖一一樣的樹結(jié)構(gòu)的,需要把XML文件用XSL模版來轉(zhuǎn)換。
在這里實(shí)際上需要把XML文檔用模版格式為以下樣式:
<ul>
<li></li>
<li></li>
<ul>
 <li></li>
 <li></li>
</ul>
</ul>
每一個(gè)li表示一個(gè)子節(jié)點(diǎn),ul表示其上的li為一樹杈,其下的li為其子節(jié)點(diǎn),可能為樹杈,可能為葉子,取決于該子節(jié)點(diǎn)是否具有ul。
XSL模版功能定義著如何轉(zhuǎn)化嵌套的node節(jié)點(diǎn)為嵌套的ul和li表示。
模版轉(zhuǎn)化的關(guān)鍵代碼:
<xsl:template match="node">
<xsl:for-each select=".[number(layer) $eq$ 0 ]"><!—對于每一個(gè)節(jié)點(diǎn),如果他的layer值為0,進(jìn)行下面的代碼變化-->
<xsl:if test=".[href $eq$ '']"><!—如果節(jié)點(diǎn)的href域?yàn)榭,說明其為樹杈,需要檢索其下面的嵌套node-->
 <xsl:element name ="li"><!—對于li標(biāo)簽,不僅僅是指定其id為goldheader,還指定其序號no為該節(jié)點(diǎn)的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$ '']"> <!—如果節(jié)點(diǎn)的href域不為空,說明其為葉子,轉(zhuǎn)換為li格式,并把鏈接,目標(biāo)框架,顯示字符串的值以超鏈接的形式顯示出來-->
 <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>
因?yàn)闉g覽器對XSL支持的不同,所以在目前的瀏覽器使用比例上言,MSIE是可以作為默認(rèn)瀏覽器標(biāo)準(zhǔn)來定義的,在不安裝MSXSL3的情況下,MSIE只是支持XSL2,對XSL變量等不支持,所以,在這里的實(shí)現(xiàn)過程中以嵌套的代碼來實(shí)現(xiàn)替換變量實(shí)現(xiàn)的效果。整體的代碼比較冗長,但易于讀寫和修改。不對代碼進(jìn)行重復(fù),具體請參見treefunc.xsl文件中從<xsl:template match="node">開始到</xsl:template>結(jié)束的中間的代碼實(shí)現(xiàn)。
樹狀顯示還依賴于js的支持,js定義著點(diǎn)擊樹杈時(shí)樹的顯示變化,例如,當(dāng)當(dāng)前點(diǎn)擊樹杈節(jié)點(diǎn)為收縮狀態(tài)時(shí),點(diǎn)擊的效果是展開該樹杈,顯示樹杈的下級節(jié)點(diǎn),反之亦然。
首先對ul和li進(jìn)行類的標(biāo)識,對于樹杈的li,定義其元素的id為’ foldheader’,對于其下跟隨的ul定義其元素的id為’ foldinglist’,style.display為’none’或者’’,然后定義一個(gè)change函數(shù),功能為點(diǎn)擊樹杈節(jié)點(diǎn)后的界面變化。
同時(shí)因?yàn)闃浣Y(jié)構(gòu)的層次可能會(huì)比較深,需要考慮到客戶瀏覽時(shí),在刷新頁面或者重新開啟同一頁面時(shí)應(yīng)該保存住客戶最后瀏覽的樹的層次,在這里實(shí)現(xiàn)的方式是用cookie保持每個(gè)樹杈的是否展開的布爾值,
對cookie的操作函數(shù)和對點(diǎn)擊事件的操作函數(shù)都在treefunc.xsl文件中,下面是javascript編寫的對XML生成樹進(jìn)行HTML動(dòng)作處理的方法,
/*說明是在載入頁面時(shí)就要發(fā)生的動(dòng)作*/
var temp_str = 'thexmltreecookie';/*定義一個(gè)字符串,用于在cookie中查找節(jié)點(diǎn)展開狀態(tài)*/
var fl_n = 0;
temp_str = temp_str + "=";
for (i=0;i<foldinglist.length;i++){/*把所有的樹杈都預(yù)設(shè)為未展開,并統(tǒng)計(jì)個(gè)數(shù)*/
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)){/*當(dāng)cookie不為空,而且cookie中有正確對應(yīng)的樹杈個(gè)數(shù),讀取cookie中保存的樹杈狀態(tài)*/
document.cookie = temp_str;/*檢驗(yàn)cookie中值不為正確,則賦予新值*/
}
else {
/*cookie中保存的樹杈狀態(tài)形如”1:0:0:0:1”,這表示第一和第五節(jié)點(diǎn)是展開的,第二,三,四節(jié)點(diǎn)是收縮的,這種形式并沒有保存樹的層次屬性,所以,這里的節(jié)點(diǎn)展開沒有一一反應(yīng)到樹的表現(xiàn)上來,例如:如果第五節(jié)點(diǎn)是第四節(jié)點(diǎn)的子節(jié)點(diǎn),那么盡管第五節(jié)點(diǎn)是展開的,但因?yàn)楦腹?jié)點(diǎn)未展開,所以在查看樹時(shí),是不可能看到第五節(jié)點(diǎn)的,只有當(dāng)?shù)谖骞?jié)點(diǎn)的父節(jié)點(diǎn),祖父節(jié)點(diǎn),直到頂層節(jié)點(diǎn)都為展開狀態(tài),第五節(jié)點(diǎn)才為可視的展開狀態(tài).這里用函數(shù)WM_readCookie()方法取得樹杈狀態(tài)字符串,并把它按’:’分開,放入數(shù)組temp_s中*/
var temp_s = WM_readCookie("thexmltreecookie").split(":");
/*從第一個(gè)樹杈開始,根據(jù)樹杈字符串相應(yīng)位置的取值,設(shè)置該樹杈節(jié)點(diǎn)的顯示屬性*/
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="";
}
 }
}

/*函數(shù)changge()是點(diǎn)擊頁面時(shí)觸發(fā)的動(dòng)作,*/
function change(){
/*點(diǎn)擊的對象是頁面上的元素動(dòng)作才繼續(xù)*/
if(!document.all)
 return;
/*由temp_ss數(shù)組得到樹杈節(jié)點(diǎn)的展開屬性*/
var temp_ss =WM_readCookie("thexmltreecookie").split(":");
var temp_s = 'thexmltreecookie';
temp_s = temp_s + '=';
/*如果點(diǎn)擊元素是樹杈,則繼續(xù)動(dòng)作,這里判斷是否樹杈是通過判斷點(diǎn)擊對象的id是否為foldheader*/
if (event.srcElement.id=="foldheader") {
 /*srcIndex賦值為點(diǎn)擊HTML元素的在HTML文檔中的序號*/
var srcIndex = event.srcElement.sourceIndex;
/*nested賦值為點(diǎn)擊元素的下一個(gè)元素,是<ul>元素,樹杈節(jié)點(diǎn)的控制元素,通過控制該元素的屬性可以控制該樹杈是否顯示和顯示的圖片*/
 var nested = document.all[srcIndex+1];
/*遍歷樹杈節(jié)點(diǎn),作用是當(dāng)點(diǎn)擊的對象是遍歷到的HTML元素時(shí),做相應(yīng)的變化,如,更改cookie中樹杈狀態(tài)字符串,使點(diǎn)擊的節(jié)點(diǎn)展開或縮回其子節(jié)點(diǎn),在cookie中保存當(dāng)前點(diǎn)擊節(jié)點(diǎn)的Id值*/
 for (i=0;i<foldinglist.length;i++){
if (foldinglist[i] == nested){
/*定義變量ClickId,保存點(diǎn)擊對象的no屬性,no屬性是指該節(jié)點(diǎn)在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;
/*更換相應(yīng)的圖片*/
 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();
}
 }
/*指定在頁面中點(diǎn)擊事件的處理函數(shù)為change()*/
 document.onclick=change;
 /*函數(shù)WM_readCookie(name)用來調(diào)用WM_getCookieValue(name)取得在cookie中以name為名稱的cookie串的值*/
 function WM_readCookie(name){
//如果沒有cookie則返回false或者取得值并返回該值
 if(document.cookie == ''){
 return false;
 }
 else {
 return unescape(WM_getCookieValue(name));
 }
 }