數據XML文檔是一個很簡單的XML文檔,此處不加 說明了。重點說說XSLT樣式表文檔,可以看到XSLT樣式表文檔本身一個XML文檔。它采用XML 的樹狀結構來描述遞歸處理過程,也比較好理解。
在樣式表文檔中,根元素為 xsl:stylesheet ,裡面定義了一個名為xsl的名稱空間,這個根節點及其屬性值都是固定的 。
xsl:output 元素是可選的,它的method屬性用於指定輸出文檔的格式,可以設置 為XML,Html或text值。此處使用xml輸出樣式,說明輸出的文檔是XML格式的,XSLT轉換會盡 量生成XML文檔,但不作保證,因此仍然有可能生成不合格的XML文檔。
xsl:template 用於定義一個XSLT模板,模板類似編程語言中的函數,可實現XSLT代碼的重用。模板可以使 用name屬性定義名稱,也可以使用match屬性定義匹配的XPath路徑,這個模板使用了match屬 性來匹配XML文檔本身。
然後是 html 元素,由於Html元素沒有使用xsl的前綴,因此 不屬於xslt代碼,因此將原樣輸出,跟著後面的body,table元素也是一樣的。
xsl:for-each 元素類似C#中的foreach 語法結果,表示循環遍歷元素,它使用 select屬性指定一個XPath相對路徑,XSLT使用這個相對路徑查詢所有要遍歷的XML節點,此 時當前節點就是XML文檔本身,因此XSLT處理器會調用XmlDocument的SelectNodes 函數來獲 得要遍歷的XML節點,函數的參數就是Table/Record。於是我們開始循環遍歷所有的Record元 素了。
在循環遍歷Record元素時,對每一個Record元素都要輸出xsl:for-each的子節 點,首先是 tr 元素,這不是XSLT元素,因此原樣輸出。這裡還套嵌定義了另外一個for- each元素,於是我們又開始了一個新的循環遍歷了,新的循環指定的相對XPath路徑是一個星 號,表示匹配所有名稱的子元素,這類似DOS命令Dir中使用星號匹配所有文件。此處表示循 環遍歷Record元素下面所有的字段元素。
對每一個字段元素,首先輸出td 元素,然 後處理xsl:value-of 元素,xsl:value-of 表示輸出指定相對路徑的節點的值,這裡指定的 XPath是一個點號,表示當前節點本身,由於當前節點是XML元素,因此也就輸出元素的文本 內容,相當於輸出XMLElement的InnerText 屬性值。
為了讓大家 更清楚的了解XSLT執行過程,我寫了一段C#代碼來模擬實現這個XSLT轉換過程,代碼在演示 程序的 codexslt.ASPx 中。代碼如下
// 此處代碼動態構造 xml 文檔對象結 構來輸出XML文檔
System.Xml.XmlDocument XmlDoc = new System.Xml.XMLDocument ();
-------------- 查詢數據庫,填充XMLDoc --------------------------
// 保存輸出結果的緩沖區
System.IO.StringWriter myResult = new System.IO.StringWriter();
myResult.WriteLine("<Html>");
myResult.WriteLine(" <body>");
myResult.WriteLine (" <table border='1'>");
// 模擬 <xsl:for -each select="Table/Record">
foreach( System.Xml.XmlNode node in XMLDoc.SelectNodes("Table/Record"))
{
myResult.WriteLine(" <tr>");
// 模擬 <xsl:for -each select="*">
foreach( System.Xml.XMLNode node2 in node.SelectNodes("*"))
{
myResult.Write(" <td>");
// 模擬 <xsl:value-of select="." />
myResult.Write( node2.InnerText );
myResult.WriteLine("</td>");
}
myResult.WriteLine(" </tr>");
}
myResult.WriteLine(" </table>");
myResult.WriteLine(" </body>");
myResult.WriteLine ("</Html>");
myResult.Close();