在兩部分組成的關於 XSLT 的系列文章的第一期中,介紹了 XSLT 2.0 的一些新特性,並說明了如何從抽象資料模型產生代碼。為了示範這一過程,我建立了項目,開發一個健壯的代碼產生器,為資料庫伺服器產生 SQL,並為 Web 服務器產生用於訪問資料庫的 PHP。我使用多層轉換通過 XSL 構建 SQL。首先將抽象模型轉化成資料庫物理模式模型,然後使用該模式模型構建 SQL 代碼。
接下來就要構建代碼模型並從這個模型產生 PHP。在結束項目時,您將擁有系統的抽象模型、構建資料庫的 SQL 代碼和用於每個表的 PHP 封裝器。但是在深入討論 PHP 產生之前,我想首先回顧一下影響 XSL 模板設計及使用的 XSL 和 XSLT 2.0 的新特性。
對 XSL 模板的增強
要產生成功的代碼則需要對目標語言(這裡是 PHP)和代碼產生語言(該例中即 XSLT)有充分的瞭解。第 1 部分的重點放在代碼產生的基本原理上。本文對代碼產生等式中的 XSL 一端進行了更深入的分析。
從本質上說,XSLT 是一種模板化的語言。它接受 XML 作為輸入,然後使用一組模板將 XML 轉化成 XML、HTML 或文本。產生器是相關模板的集合,使用兩種模式 —— XML 模式和 Text 模式 —— 將原來輸入的 XML 轉化成代碼。位於抽象模型和代碼模板之間的中間模型使用 XML 模式,產生 PHP 和 SQL 的代碼模板則使用文字模式。
這個代碼產生系統使用 Saxon XSLT 引擎和一組自訂模板。為了方便起見,這些模板和輸入放在同一個目錄中。模板輸出分別放到 PHP 和 SQL 代碼目錄中。不需要對 Saxon 作專門的擴充,雖然如果發現基本安裝所提供的 XSL 標籤或 XPath 函數不敷使用,那麼可以用 Java? 擴充模板引擎。
XSL 模板的入口是與輸入 XML 的根節點匹配的 XSL 模板。在 XSL 引擎啟動時,它將輸入 XML 應用於模板庫。如果有與根節點(/)匹配的特殊模板,則首先執行它。下面是產生器中的主模板標籤:
<xsl:template match="/">
這個匹配系統很重要,因為 XSL 要查看應用於當前正在處理節點的可用模板的列表,然後應用最匹配的模板。看一下清單 1 中的代碼,這是上一期文章中的一個例子。
清單 1. 帶有模式類型的模板
<xsl:template match="create" mode="sql">
DROP TABLE IF EXISTS <xsl:value-of select="@name" />;
CREATE <xsl:value-of select="@name" /> (
<xsl:apply-templates mode="sql" select="field" />
PRIMARY KEY ( <xsl:value-of select="@primary-key" /> )
);
</xsl:template>
代碼告訴 XSL 這個模板應用於 create 標籤。因此,當 XSL 遇到 create 標籤時,它就會執行該模板。此外,還要注意該模板指定了模式。需要像清單 2 那樣在 xsl:apply-templates 標籤中指定模式。
清單 2. 應用模板的標籤
<xsl:apply-templates mode="sql" select="$sql-model/sql" />
XSL 中的模式
模式是 XSL 的一個重要概念。因為記憶體中可能同時有多個 XML 分層結構,需要有一種方法對特定分層結構應用一組特殊的模板,或者可用於單個 XML 摘要的一群組轉換。於是就引入了模式。這個代碼產生器中有一組模板以 PHP 作為模式,另一組則用 SQL 作為模式。通過使用模式將這兩種語言的模板邏輯區分開來。
xsl:apply-templates 標籤告訴 XSL 將可以用的模板應用於 XML 模型中 select 標籤所指定的那一部分。此外,還規定了模式 sql,因此 XSL 只尋找那些採用 sql 模式的模板。這是一種方便的模板名稱空間機制。