XML第二篇 XML的造型大師--XSL[转载]

转载 2006年06月03日 18:02:00
JXML第二篇 XML的造型大師--XSL

恆逸資訊教育訓練中心首頁

作者: 恆逸資訊 許嘉仁

在上一期的文章中我們介紹了XSL技術的其中一種應用,那就是目前最熱門的B2B或B2C的資料交換,面對散落於各地不同格式的資料,XML的可攜性、透通性以及跨Internet的方便性漸漸取代舊式EDI文件的交換。

造型大師XSL

而XSL技術的另外一種應用就是讓XML資料展現在網頁中,聽起來似乎沒什麼大不了,同樣使用HTML搭配文字資料一樣能夠展現,差別只在於XML將資料的部分獨立出來,XSL則負責來展現資料,對於資料的維護則較為容易,但是讀者可能還沒有很大的感覺,所以在這邊將一份靜態網頁改換使用XML資料搭配XSL技術來展現,透過比較,我們能夠更了解XML所帶來的好處。
為了能夠看出XSL如何做XML的造型,如何讓網站維護成本降低,首先先來看看HTML搭配Client端Script所製作的Menu Bar,程式碼及結果如下:
< HTML >
< HEAD >
< META name="VI60_DefaultClientScript" Content="VBScript" >
< TITLE >MenuBar< /TITLE >
< SCRIPT ID=clientEventHandlersVBS LANGUAGE=vbscript >
Sub document_onclick
if window.event.srcElement.className="parent" then
if window.event.srcElement.children(2).style.display="none" then
window.event.srcElement.children(0).src="images/red.gif"
window.event.srcElement.children(2).style.display="block"
else
window.event.srcElement.children(0).src="images/blue.gif"
window.event.srcElement.children(2).style.display="none"
end if
end if
End Sub
< /SCRIPT >
< style >
.parent { cursor:hand;FONT-WEIGHT: bold;height:20px }
.child { height:30px }
.title { color:maroon;font-size:14px;height:20px }
a { TEXT-DECORATION: none; height:14px }
< /style >
< /HEAD >
< BODY rightmargin="0" style="FONT-FAMILY: Verdana; FONT-SIZE: 12px" >
< div >< DIV class="title" >< b >恆逸課程查詢< /b >< /DIV >
< DIV class="parent" onmouseover="me.style.color='red'" onmouseout="me.style.color='black'" >
< IMG src="images/blue.gif" style="CURSOR: default" >微軟認證課程< br >
< DIV class="child" style="DISPLAY: none" >
< A href="MCDBA(全套).htm" >MCDBA(全套)< /A >< br >
< A href="MCSD(全套).htm" >MCSD(全套)< /A >< br >
< A href="W2K MCSE升級(全套).htm" >W2K MCSE升級(全套)< /A >< br >
< A href="W2K MCSE(全套).htm" >W2K MCSE(全套)< /A >< br >
< /DIV >
< /DIV >
< DIV class="parent" onmouseover="me.style.color='red'" onmouseout="me.style.color='black'" >
< IMG src="images/blue.gif" style="CURSOR: default" >.Net相關課程< br >
< DIV class="child" style="DISPLAY: none" >
< A href="DOTNET FrameWork.htm" >.NET FrameWork< /A >< br >
< A href="ASP.NET開發技術.htm" >ASP.NET開發技術< /A >< br >
< A href="C#語言.htm" >C#語言< /A >< br >
< A href="Visual Studio.NET.htm" >Visual Studio.NET< /A >< br >
< /DIV >
< /DIV >
< /div >
< /BODY >
< /HTML >


上面這支Menu Bar程式可以展開收合並能夠超連結至其他網頁,通常用來當目錄分類或是網頁功能的列表,看起來似乎也沒什麼不好,在下結論前,我們將這樣的網頁改成以XML搭配XSL方式展現。

轉換資料為XML格式



首先將程式碼中灰底部分的標題資料、大綱資料以及超連結資料分別定義XML格式資料儲存成檔案,將資料從負責展現資料的HTML標籤中獨立出來,如右列MenuBar.xml展現:

資料獨立出來又有什麼好處呢?透過上面的XML文件,讀者可以從檔案的第二列清楚的看到說明,包括哪個標籤或哪個屬性存放什麼資料,再比較一下原本的HTML頁面的標籤,如果你不是程式的原作者,應該會覺得混雜難以辨識且修改不易,另外,如果網頁想要改變展現風格,那可能就必須重寫,包括標題、大綱、超連結資料都一樣。

簡單來講,這份網頁的資料無法再利用,但是我們還沒撰寫XSL檔案讓XML資料能夠達到同樣的功能,那該如何著手呢?其實很簡單,首先先把XSL檔案基本的語法寫好,不過因為我們將使用到中文資料,所以第一列必須要加上encoding屬性設定為Big5,如下:
< ?xml version="1.0" encoding="big5"? >
< xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" >
< xsl:template match="/" >
………
………
< /xsl:template >
< /xsl:stylesheet >
接下來再把MenuBar.htm中非灰底的部分,包括HTML標籤和Client端程式碼全部拷貝貼至XSL文件當中,也就是貼至上列………的位置,而灰底部分的資料必須改用XSL語法來產生,大致可以分為四個步驟來完成,首先MenuBar.htm灰底部分可以看出分為兩大部分,也就是"微軟相關課程"和".NET相關課程"。

第一個步驟:取得MenuBar標題內容

所以第一個步驟我們會使用XSL語法中的for-each迴圈,透過迴圈的select屬性將Menu標籤的節點取出,再使用XSL語法的value-of取出MenuTitle屬性的內容並取代原本的標題字串,如下列語法:
< xsl:for-each select="//Menu" >
< DIV class="parent" onmouseover="me.style.color='red'" onmouseout="me.style.color='black'" >
< IMG src="images/blue.gif" style="CURSOR: default" / >
  < xsl:value-of select="@MenuTitle" / >< br / >
< DIV class="child" style="DISPLAY: none" >
< A href="MCDBA(全套).htm" >MCDBA(全套)< /A >< br >
< A href="MCSD(全套).htm" >MCSD(全套)< /A >< br >
< A href="W2K MCSE升級(全套).htm" >W2K MCSE升級(全套)< /A >< br >
< A href="W2K MCSE(全套).htm" >W2K MCSE(全套)< /A >< br >
< /DIV >
< /DIV >
< /xsl:for-each >

第二步驟:XML文件套用XSL展現

第二個步驟修改MenuBar.xml套用我們剛出爐的XSL文件,如下列語法:
< ?xml version="1.0"? >
< ?xml-stylesheet type="text/xsl" href="MenuBar.xsl"? >
< MenuList >
………
………
< /MenuList >
MenuBar.xml
如此就能產生兩個標題,如下:

第三步驟:取得大綱資料

不過我們也注意到大綱的內容是錯誤的,所以第三個步驟我們再透過一層迴圈取出所有的MenuItem資料,也就是大綱資料(xml檔案中的MenuItem標籤內容),程式如下:
< xsl:for-each select="//Menu" >
< DIV class="parent" onmouseover="me.style.color='red'" onmouseout="me.style.color='black'" >
< IMG src="images/blue.gif" style="CURSOR: default" / >
< xsl:value-of select="@MenuTitle" / >< br / >
< DIV class="child" style="DISPLAY: none" >
  < xsl:for-each select="MenuItem" >
  < A href="MCDBA(全套).htm" > < xsl:value-of / > < /A >< br / >
  < /xsl:for-each >
< /DIV >
< /DIV >
< /xsl:for-each >

第四步驟:取得超連結資料並展現

但是這樣所有的超連結不就都一樣了嗎?所以第四個步驟我們必須將超連結的網址加進去才對,但是不能直接將< xsl:value-of select="@url" / >語法塞進超連結的href屬性當中,否則會發生錯誤,因為這會造成標籤符號的衝突,如下列情況:
< A href="< xsl:attribute name="HREF" >" > < xsl:value-of select="@url" / >< /A >
這樣的方式會造成兩個標籤起始符號"< "相鄰,這樣的標籤語法是不備允許的,所以必須使用XSL的attribute語法幫超連結標籤< a >新增屬性"HREF"再將資料塞進屬性當中,程式如下:
< xsl:for-each select="//Menu" >
< DIV class="parent" onmouseover="me.style.color='red'" onmouseout="me.style.color='black'" >
< IMG src="images/blue.gif" style="CURSOR: default" / >
< xsl:value-of select="@MenuTitle" / >< br / >
  < A >< xsl:attribute name="HREF" >
< xsl:value-of select="@url" / >
< /xsl:attribute >
< xsl:value-of / >
< /A >< br / >
< /DIV >
< /xsl:for-each >


經過四個步驟的修改,整個程式便完成了,接下來看看結果吧:


讀者可以看到網址列是使用XML檔案資料,經過XSL語言轉換後產生同樣具有展開收合功能的MenuBar,並且擁有正確的超連結,當然課程標題可能不只兩個,只要在XML資料檔案中再加上其他的課程資料就一樣能夠展現了,相當地方便。

轉換過程的注意事項

然而轉換的過程中其實也不是那麼順利,主要是因為HTML對標籤的使用比較不嚴謹,而XML的使用則恰好相反,例如原本HTML網頁中的< br >標籤放到XSL文件的時候必須要改成< br / >才行,因為XML文件要求標籤的使用必須要有起始標籤以及結尾標籤,如果開始及結尾標籤中沒有存放內容則可以使用空標籤表示,如下:
< book >< /book > 等於 < book / >

所以在轉換及測試的過程中其實會面臨到相當多這樣類似的問題,有時也很難找出錯在哪裡?畢竟規定的使用方式差異頗大,所以網路上大部分的運用還是在資料的交換處理上,不過讀者還是可以看見它的優點,除了網頁較為容易維護外,想要修改展現的效果或新增資料都容易得多,而且同一份資料也能做不同樣式的展現,這是HTML頁面做不到的。

如下範例,我們可以再將同一份XML文件套用另一份XSL文件,如此就能夠使資料再利用,讀者在這裡就可以看到XML的造型大師XSL的能力了:

結合DOM物件更具彈性及能力的展現方式

除了使用XML文件直接套用XSL的方式以外,其實還有另外一種方式可以讓展現更具彈性及能力,那就是結合XML DOM物件(Document Object Model),動態套用XML文件達成相同的MenuBar功能,這種方式將同時結合XML、XSL、DOM以及HTML頁面,雖然看起來好像很複雜,但是看完修正後的結果,讀者應該會覺得更清爽了。
首先將XSL文件轉換的範圍所小至只轉換< Body >標籤內的資料,差不多是前面第四步驟完成後的結果,如下:
< ?xml version="1.0" encoding="big5"? >
< xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" >
< xsl:template match="/" >
< DIV class="title" >< b >恆逸課程查詢< /b >< /DIV >
< xsl:for-each select="//Menu" >
< DIV class="parent" onmouseover="VBScript:me.style.color='red'" onmouseout="VBScript:me.style.color='black'" >
< IMG src="images/blue.gif" style="CURSOR: default" / >
< xsl:value-of select="@MenuTitle" / >< br/ >
< DIV class="child" style="DISPLAY: none" >
< xsl:for-each select="MenuItem" >
< A >< xsl:attribute name="HREF" >
< xsl:value-of select="@url" / >
< /xsl:attribute >
< xsl:value-of / >
< /A >< br / >
< /xsl:for-each >
< /DIV >
< /DIV >
< /xsl:for-each >
< /xsl:template >
< /xsl:stylesheet >
這段XSL語法與MenuBar.xsl差別在只轉換MenuBar.htm的灰底部分的資料,接下來要配合將原本的MenuBar.htm稍加修改,如下:
< HTML >
< HEAD >
< META name="VI60_DefaultClientScript" Content="VBScript" >
< TITLE >MenuBar< /TITLE >
< SCRIPT ID=clientEventHandlersVBS LANGUAGE=vbscript > Sub document_onclick
if window.event.srcElement.className="parent" then
if window.event.srcElement.children(2).style.display="none" then
window.event.srcElement.children(0).src="images/red.gif"
window.event.srcElement.children(2).style.display="block"
else
window.event.srcElement.children(0).src="images/blue.gif"
window.event.srcElement.children(2).style.display="none"
end if
end if
End Sub
Sub window_onload
'取得XML檔案資料 set
doc=createobject("microsoft.xmldom")
doc.async=false doc.load "MenuBar.xml"
'取得XSL檔案資料
set ss=createobject("microsoft.xmldom")
ss.async=false
ss.load "MenuBar2.xsl"
'使用DOM物件動態套用XSL轉換XML文件
menubar.innerHTML= doc.transformnode(ss)
End Sub
< /SCRIPT >
< style >
.parent { cursor:hand;FONT-WEIGHT: bold;height:20px }
.child { height:30px }
.title { color:maroon;font-size:14px;height:20px }
a { TEXT-DECORATION: none; height:14px }
< /style >
< /HEAD >
< BODY rightmargin="0" style="FONT-FAMILY: Verdana; FONT-SIZE: 12px" >
< div id="menubar" >< /div >
< /BODY >
< /HTML >
上列程式經過了兩部分修改,第一部份是將原本MenuBar資料的部分修改至只剩下以下標籤:
< div id="menubar" >< /div >
然後加入程式的部分,當文件載入(Window_OnLoad)的時候先取得XML文件及XSL文件的資料後,使用XML DOM物件動態套用產生MenuBar資料得結果,然後將產生的結果插入上列的標籤當中,如此一來也能夠得到相同的結果,讀者可以自行試試看。

結論

網頁的技術運用何止千變萬化,有許多種方式都能夠達到相同的目的,就在於根據環境來取決,而一種技術並不能滿足使用者的種種需求。這時候當然要搭配多種不同的技術來解決不同的需求,聽起來好像在饒舌,不過Internet的環境就是如此,更好的技術不斷地更新演進,解決問題的方式也就跟著越來越多。
例如第一個範例中的XSL與XML的搭配展現,第二個範例中DOM物件、XML、XSL的結合,讀者或許覺得這樣的MenuBar還是不夠方便,因為大部分的人都會將資料存放在資料庫而並非存放在XML檔案中,而又該如何來運用呢?
假設有一家書店的網站將書籍分門別類存入資料庫之後,希望以MenuBar的方式展現出來,如何從資料庫取出並轉換成為XML資料?又如何將之展現在網頁上呢?這其中需要注意什麼呢?又有哪些特殊技巧呢?下一期將會繼續跟大家一起討論。

XML xsl转换

  • 2017年11月22日 13:43
  • 601KB
  • 下载

XML转换XSL工具

  • 2011年02月27日 22:24
  • 155KB
  • 下载

PHP使用XSL stylesheets解析转换XML文件

PHP与XSL stylesheets相结合来处理XML文档,似乎大家不常用,不过这却是一个很有用的技巧,在众多大型php web应用中,你肯定见到过与XSL stylesheets结合的例子,只是你...
  • dahuzix
  • dahuzix
  • 2015年06月06日 16:16
  • 448

XML+XSL-&gt;HTML(transformer)

  • 2006年02月23日 09:05
  • 504KB
  • 下载

根据xsl模板及xml数据文件生成pdf(文字内容复制不乱码)

使用FOP技术,配合xsl模板及XML数据生成PDF报表和线上打印业务

XML HTML CSS XSL Web编程实作教程

  • 2007年09月17日 08:37
  • 18.72MB
  • 下载

xsl与xml转化的实例

  • 2010年04月10日 20:17
  • 21KB
  • 下载

如何用XSL对XML的数据进行按节点排序?

今天工作当中,遇到一个问题,XML的Schema文件中定义的complexType是一个Sequence,这就要求符合这个Schema定义的XML的数据节点,必须要按照Schema中Sequence定...

XML HTML CSS XSL Web编程实作教程

  • 2011年04月24日 06:10
  • 16.32MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:XML第二篇 XML的造型大師--XSL[转载]
举报原因:
原因补充:

(最多只允许输入30个字)