XSLT
樣式表允許您非常自由地操作原始 XML 文檔中的資料。然而,有時候,當真正想進行一些實際編程時,XSLT
建議書設計成通過使用擴充允許這樣做。這些擴充採用函數和元素的形式,可以使用處理器支援的任何語言編寫。您的選擇之一是將 JavaScript
直接或作為外部檔案內建樣式表。
這篇技巧文章使用 Apache Project 的 Xalan Java 2 轉換引擎及其實現(請參閱參考資料)。總體概念對於任何實現都是相同的,XSLT 建議書並未要求任何特殊實現方法。除了 Xalan,在您的 CLASSPATH
上包含還需要 js.jar 檔案(參閱參考資料),它包含了 JavaScript 實現,還需要 bsf.jar
檔案,它是 Xalan 發行版的一部分。
來源文件
樣式表文檔樣本記載了猜數遊戲中的項,其中猜數者從 1 到 100 猜三個數。樣式表擷取這三個數並將它們與隨機數進行比較。樣本文檔含有兩組猜測數:
樣本文檔
<?xml version="1.0"?> <entries gameID="DWO"> <entry> <player>John</player> <guess>3</guess> <guess>9</guess> <guess>222</guess> </entry> <entry> <player>Mary</player> <guess>88</guess> <guess>76</guess> <guess>5</guess> </entry> </entries>
|
建立組件
使用擴充元素或函數的第一步是定義要執行的代碼。這涉及為代碼定義新的名稱空間及容器:
基本樣式表
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:lxslt="http://xml.apache.org/xslt" xmlns:result="http://www.example.com/results" extension-element-prefixes="result" version="1.0"> <lxslt:component prefix="result" elements="rules" functions="getResult"> <lxslt:script lang="javascript"> function getResult (thisGuess) { var thisResult = parseInt(Math.random()*100); if (thisResult == parseInt(thisGuess)) { return "Correct!"; } else { return "Wrong! The actual answer was "+thisResult+ ", not "+thisGuess+"."; } } </lxslt:script> </lxslt:component> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet>
|
表面上,這是一個添加了兩個新名稱空間的典型樣式表。第一個名稱空間的首碼是 lxslt
,告訴處理器哪個元素定義了新功能。第二個名稱空間的首碼是 result
,表明對新功能的一次調用。最後,extension-element-prefixes
屬性讓處理器知道哪個元素作為正常流的一部分不該被轉換。(如同我們將看到的一樣,它們仍然會返回一個值作為輸出。)
組件本身指定從 result
名稱空間首碼調用其內部的所有代碼。它也讓處理器知道哪些函數將從擴充元素調用,以及哪些函數將從擴充函數調用。指令碼元素描述函數本身。
在這個例子中,我們從一個函數開始,該函數擷取一個參數並將它與 1 到 100 間的隨機數進行比較,返回一個表示結果的字串。
擴充函數
在 XSLT 樣式表中,擴充函數實際擴充 XPath,因此,您可以像使用內建函數(如 translate()
或 round()
)一樣使用它們。
調用函數
... <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="entry"> Guesser: <xsl:value-of select="player"/> <xsl:apply-templates select="guess"/> </xsl:template> <xsl:template match="guess"> Guess: <xsl:value-of select="."/> Actual: <xsl:value-of select="result:getResult(string(.))"/> </xsl:template> </xsl:stylesheet>
|
本樣本將當前節點(guess
)的字串值傳遞給 getResult()
函數。名稱空間讓處理器知道觸發結果組件中的函數。
圖 1. 初步結果
使用元素
擴充元素比函數要複雜一點。我們不希望擴充元素簡單地返回一個值(雖然它們可以這樣做),而希望它們在樣式表處理過程中的特定“時刻”執行某個特定的操作。也不希望獲得一個隨機的參數列表(因為擴充函數也可以),擴充元素背後的代碼含有兩個良好定義的參數。
rules
元素觸發 rules()
函數的處理。該函數將 rules
元素本身(elem
)作為其參數之一,允許您檢索它擁有的任何定製屬性的值。
使用處理器上下文
擴充元素最強大的方面可能是通過 XSL 處理器上下文參數訪問來源文件本身的能力。
處理器上下文
... <lxslt:component prefix="result" elements="rules" functions="getResult"> <lxslt:script lang="javascript"> ... function rules(ctx, elem) { ctxNode = ctx.getContextNode(); gameID = ctxNode.getFirstChild().getAttribute("gameID"); return "Contest "+gameID+" is based on "+ elem.getAttribute("guessType")+" guesses."; } </lxslt:script> </lxslt:component> ...
|
rules
函數的第一個參數是 org.apache.xalan.extensions.XSLProcessorContext
對象形式的處理器上下文。這允許您檢索代表上下文節點、整個源樹、樣式表以及當前執行轉換的轉換程式的對象。訪問上下文節點是最常見的。一旦由 getContextNode()
方法返回,這就是一個可以使用典型 DOM 操作的典型 XML 節點。
圖 2. 最終輸出
參考資料
- 請參考 W3C 的 XSLT 建議書。
- 下載 Apache 的 Xalan-Java 2。
- 下載 js.jar 檔案。
- 在 developerWorks XML 專區上找到更多 XML 參考資料。
- IBM WebSphere Studio Application Developer 是一個便於使用的整合式開發環境,用於構建、測試並部署 Java Server Pages、servlet 和與 XML 相關的應用程式及網站。
關於作者 Nicholas Chase 曾參與為包括 Lucent Technologies、Sun Microsystems、Oracle 和 Tampa Bay Buccaneers 在內的多家公司的網站開發。Nick 曾是一名高中物理教師、低級放射性廢物設施管理員、線上科幻小說雜誌編輯、多媒體工程師和 Oracle 講師。最近,他成為佛羅里達州克利爾沃特市 Site Dynamics Interactive Communications 的首席技術官。他寫了三本有關 Web 開發的書,包括 Java and XML From Scratch(Que)和即將出版的 Primer Plus XML Programming(Sams)。他樂於傾聽讀者的意見,可以通過 nicholas@nicholaschase.com 和他聯絡。 |
轉自:http://www.cnblogs.com/sunsonbaby/archive/2005/01/17/93194.html