改進 XSLT 編碼的五種方法::使您成為更優秀的 XSLT 程序員的技巧
級別: 初級
Benoit Marchal, 軟件工程師, Pineapplesoft
2001 年 1 月 01 日
無 論是 XSLT 的初學者還是經驗豐富的程序員,都一定會發現 Benoit Marchal 的這五種技巧將改進編碼并帶來新的思路。這些技巧涵蓋了利用 XSL 樣式表(包括 HTML 實體)使用 CSS、合并客戶機端 JavaScript、使用多個輸入文檔,以及使用 XSLT 自動生成樣式表。本文包括了供您改編和再使用的樣本代碼。
XML 和 XSLT 的組合已在大中型網站的網站管理員之間逐漸流行起來。在 XSLT 出現之前,更改網站顯示是一項重要任務:有一個人必須重新訪問并更改站點上的每一個頁面。但 XSLT 可以自動執行這個過程,這就大大節省了時間。
在討論 XSLT 的文章中以關于 CSS 的技巧作為開始似乎有些奇怪,但有人經常問我“這兩種樣式表語言是否兼容?”答案是響亮的“是”。
清單 1 中的 products.xml 說明了這一點,它是以 XML 格式編寫的產品列表。請花一點時間來熟悉 products.xml,因為我將使用它來說明這五種技巧。
清單 1. products.xml,XML 格式的產品清單
|
要將此文檔的格式轉換成 HTML,可以使用清單 2 中的 table.xsl。將 table.xsl 應用到 products.xml的結果如 圖 1 所示。可以看到,每隔一行都有一個灰色背景,這就提高了可讀性。在 table.xsl 中,這是由于使用了級聯樣式表而實現的。
清單 2. table.xsl,使用 CSS 的 XSLT 樣式表
|
![]() |
|
Name | Price | Description |
Playfield Text | 299 | Faster than the competition. |
Playfield Virus | 199 | Protect against malicious code. |
Playfield Calc | 299 | Clear picture on your data. |
Playfield DB | 599 | Organize your data. |
它是如何工作的?
table.xsl 樣式表將 HTML
<link>
元素插入到輸出中。
<link>
會裝入級聯樣式表:
|
CSS 和 XSLT 之間沒有沖突,因為不會同時使用它們。首先將 XSLT 樣式表應用到 XML 文檔 products.xml 。這會生成傳遞給瀏覽器的 XML 文檔。實際上,HTML 文檔裝入級聯樣式表與此階段無關。僅當瀏覽器裝入 HTML 文檔時,才會使用 CSS。
為了使用 CSS,XSLT 樣式表
table.xsl
會在適當的位置再插入
class
屬性。實際上,表中的元素被標記成
odd
或
even
類。那如何識別 XSLT
中的奇數行呢?只要將一個條件添加到
match
屬性,如從清單 2 中的樣式表中摘錄的這些行中所示:
|
清單 3 中的簡單級聯樣式表 table.css 在表的偶數行上放置灰色背景。
清單 3. table.css,圖 1 中表的 CSS
|
什么時候應該混合 CSS 和 XSLT?我認為此組合適用于以下情況:
- 要獲取更多的顯示控制,因為 CSS 的功能比原始 HTML 更強大
- 要生成更小的 HTML 文件,以便可以更快地下載
但是請注意,當組合這兩種樣式表時,在可維護性方面就會有所損失。事實上,設計人員最初是因為用一個文件就能控制整個網站的設計才會鐘情于 CSS。在那方面,XSLT 與 CSS 一起使用簡直就是多余,XSLT 就已經可以使一次性重新格式化幾個文檔變得很容易。
小心! table.xsl 和本文中的其它樣式表需要使用符合標準的 XSLT 處理器。Internet Explorer 5.0 和 5.5 附帶的處理器并不符合標準。如果需要一個合適的 XSLT 處理器,可以嘗試使用 Xalan,它是 Apache 項目中的 XSLT 處理器,或者將 IE 中的處理器升級到版本 3.0(請參閱 參考資料)。
![]() ![]() |
![]()
|
開發人員常問的另一個有關編寫 XSLT 樣式表的問題是如何插入 HTML
實體。尤其是,如何插入
實體(不可中斷空格)。在其它樣式表中,
空格用于在表中創建非空單元。
糟糕的是,這種直觀的解決方案不起作用:
|
為什么?XSLT 樣式表是一個 XML
文檔。對它進行分析時,會解析實體,而且會將
實體當作 XML 實體來進行解析。由于沒有在 HTML 中定義
,因此它會導致一個錯誤。
在清單 4 的 nbsp.xsl 中說明了變通方法,并且以紅色突出顯示了有關元素。可以看到,每次編寫 HTML 格式的實體時,它使用的字符比您預期輸入的字符要多。但如果您知道了代碼之后,只要在適當位置剪貼這段代碼即可。
清單 4. nbsp.xsl,演示如何在樣式表中插入 HTML 實體
|
如清單 4 中所摘錄的,不可中斷空格實體的正確代碼是:
|
那行代碼中發生了什么?訣竅是使用
<xsl:text>
元素以及
disable-output-escaping="yes"
屬性。
<xsl:text>
在輸出 HTML
中創建了一些文本。屬性告訴處理器不要將文本內容轉義。文本本身只是
和要轉義成 XML 格式的
&
字符。
再次聲明,樣式表是當作 XML 文檔讀取的,因此
就是
。如果告訴處理器不要轉義輸出 HTML 中的
&
,那么它會寫下
。
![]() |
|
![]() ![]() |
![]()
|
典型的 XSLT 樣式表將一個 HTML 文檔轉換成另一個 XML 文檔,或者轉換成 HTML 文檔。有時,這太過于局限性。(有關如何處理相反情況的簡要介紹,請參閱側欄 多個輸出文檔。)
例如,請注意在
products.xml
中,
<price>
元素有一個
currency
屬性。貨幣不是用普通文字表示,而是使用代碼(例如,
usd
代表美元,或者
cad
代表加元)。您可能想要在顯示代碼之前先轉換代碼。
由于全世界有一百多種貨幣,而許多應用程序會處理這些貨幣,的確應該在一個獨立的 XML 文檔中存儲貨幣符號列表。清單 5 中的 codes.xml摘錄了這樣的文件。
清單 5. codes.xml,帶貨幣符號代碼的 XML 文檔
|
實際上,現在示例有兩個 XML 文件, products.xml和 codes.xml ,您需要組合這兩個文件來創建 HTML 文檔。幸好,XSLT 使組合幾個輸入文件變得更容易,如清單 6 中 multi.xsl所說明的。
multi.xsl 中有兩個重要步驟。首先,樣式表打開
codes.xml (使用
document()
函數),然后將它賦值給
currencies
變量:
|
然后,樣式表可以通過變量從代碼清單中抽取信息。當然,可以使用 XPath 來查詢貨幣文檔:
|
清單 6. multi.xsl,組合幾個 XML 文檔的樣式表
|
![]() ![]() |
![]()
|
雖然 XSLT 功能強大,但它還不能應付一些情況。例如,您也許想要使用客戶機端腳本,如 JavaScript、JScript 或 VBScript。
如同 CSS,XSLT 并沒有對所生成的 HTML 有所限制 -- 它還可以使用腳本。而且,正如清單 7 中 javascript.xsl 所說明的,可以將值從 XSLT 傳遞到 JavaScript。
清單 7. javascript.xsl,生成客戶機端 JavaScript 的樣式表
|
再次聲明,要理解
javascript.xsl ,需要記住在哪個位置發生了什么事。首先應用
XSLT,生成 HTML 文件。文件包括了由 XSLT 生成其內容的
<script>
元素。接著,瀏覽器裝入 HTML
文件,并執行腳本。請記住,腳本是由瀏覽器執行的,而不是樣式表。
例如,在 javascript.xsl 中以紅色突出顯示的行中,樣式表初始化 JavaScript 數組;實際上,是將值傳遞給腳本。
稍后,樣式表在函數中生成調用,并再次將值傳遞給腳本(通過 XSLT
position()
函數),如
清單 7
中以藍色突出顯示的行所示。
清單 8 顯示了在 HTML 中生成的內容。當用戶單擊
<a>
標記時,瀏覽器將執行這個腳本,如下所示:
清單 8. 根據 javascript.xsl 生成的 HTML
|
能否從 XSLT 樣式表中,而非 HTML 文檔中調用 JavaScript 腳本?當然可以,但要使用 XSLT 擴展名。糟糕的是,XSLT 1.0 中并沒有完全標準化 XSLT 擴展名。XSLT 1.1 將改進這個支持。
![]() ![]() |
![]()
|
這種技巧是所有這五種技巧中最具挑戰性的。
有些情況下,您必須編寫許多樣式表,但似乎可以使用一個樣式表來創建它們。其實,這并不如您認為的那樣困難,它特別適用于用不同語言編寫的網站,或者那些擁有大量網頁、但僅是具體內容有所區別的站點。
清單 9 中的
start.xsl
樣式表說明了這一點。乍一看,它有點象典型的 XSLT
樣式表。如果仔細觀察,將會發現諸如
<link>
和
<para>
之類的特殊元素并不是 HTML 元素(HTML
元素應該是
<a>
或
<p>
)。而且,
<xsl:output>
元素沒有
method
屬性。
清單 9. start.xsl,普通 XSLT 樣式表
|
訣竅是使用清單 10 中的另一個樣式表 generate_html.xsl將 start.xsl轉換成更典型的樣式表。
清單 10. generate_html.xsl,用于將 start.xsl 改寫成 HTML 的樣式表
|
generate_html.xsl樣式表將
start.xsl 當作 XML
文檔處理,并將它轉換成另一個 XML 文檔。實際上,start.xsl
本身就是一個 XSLT 樣式表,并且對于 generate_html.xsl
沒有意義。例如,以下規則將
<link>
元素轉換成
<a>
:
|
這段代碼通過添加
method
屬性來修正
<xsl:output>
元素:
|
不經修改復制樣式表中的其它元素(包括
<xsl:template>
、
<xsl:for-each>
和其它 XSLT 指令):
|
將 generate_html.xsl 應用到 start.xsl 會生成一個樣式表 generated.xsl 。創建 HTML 文檔的是 generated.xsl,而不是 start.xsl。
這個技巧并不是帶著您繞圈子,它是個非常好的示例,體現了使 XSLT 的邏輯達到最大化帶來的好處。實際上,由于 XSLT 非常適用于將 XML 文檔轉換成其它 XML 文檔,當然它也適用于轉換 XSLT 樣式表本身。
清單 11. generated.xsl,演示如何將 start.xsl 轉換成 HTML
|
當網站需要創建許多樣式表時,您可能想要應用這個技巧。例如,通過將 generate_html.xsl替換成 generate_wml.xsl,可以自動將 start.xsl 改編成 WML 格式(WML 是無線智能電話的標記語言)。
清單 12. generate_wml.xsl,它將 start.xsl 改編成 WML
|
本文寓意:如果尋求大型網站的最大自動化,根據 XML 文檔自動生成 HTML 文檔是不夠的,還應該自動生成 XSLT 樣式表。
![]() ![]() |
![]()
|
- 您可以參閱本文在 developerWorks 全球站點上的
英文原文.
-
Xalan XSLT
處理器 是以開放源碼的形式分發的。它可以在 Java 和 C++
中使用。
-
XT 是用 Java
編寫的另一個流行的 XSLT 處理器。在
XT
用戶社區上有更多關于 XT 的參考資料。
- 要利用 Internet Explorer 來使用符合標準的樣式表,需要升級到
MSXML
3.0。
-
XSLT
1.0是在撰寫本文時最新的 XSLT 正式版本。
-
XSLT 1.1
目前還在開發中。它增加了一些必需的改進。
- W3C
XSLT
頁面提供了許多 XSLT 參考資料的鏈接。
-
Making teams work, via XML and XSL 說明了在企業中部署 XSLT
的好處。
![]() ![]() |
![]()
|
![]() |
||
|
![]() |
Benoit Marchal 是居住在比利時納慕爾市的一位軟件工程師兼撰稿人,他的工作領域是 Java 和 XML。他撰寫了兩本有關 XML 的書籍: XML by Example和 Applied XML Solutions 。他在 Pineapplesoft(一家咨詢公司)任職,參與了許多電子貿易項目。他的網站是 www.pineapplesoft.com。 |
posted on 2006-03-21 23:28 Vincent.Chen 閱讀(288) 評論(0) 編輯 收藏 所屬分類: XML