# javascript快速入門27--XSLT基礎
## XSL 與 XSLT
XSL 指擴展樣式表語言(EXtensible Stylesheet Language)。它主要被用來對XML文檔進行格式化,與CSS不同,XSL不僅僅是樣式表語言XSL主要包括三個部分:
* XSLT 一種用于轉換 XML 文檔的語言。 它可以將一個XML文件轉換成另一種格式的XML文件或XHTML文件.
* XPath 一種用于在 XML 文檔中導航,定位元素的語言。
* XSL-FO , 可擴展樣式表語言格式化對象(Extensible Stylesheet Language Formatting Objects) ,用于格式化供輸出的 XML 數據。XSL-FO 目前通常被稱為 XSL (盡管這算是一種誤解,但這樣說是可以的,因為在格式化XML方面,XSL-FO起著和CSS一樣的作用!)
XSLT 指 XSL 轉換(XSL Transformations)。 它是 XSL 中最重要的部分。通過 XSLT,您可以向或者從輸出文件添加或移除元素和屬性。您也可重新排列元素,執行測試并決定隱藏或顯示哪個元素,等等。描述轉化過程的一種通常的說法是,XSLT 把 XML 源樹轉換為 XML 結果樹。
## 書寫 XSLT
XSLT 文件本身也是XML 文件,一般 以.xml .xsl .xslt幾種文件后綴名保存.XSLT遵循XML的語法,文件開頭一般都加有XML聲明,XML聲明之后是文檔根元素stylesheet或transform(兩者之一),并且使用version屬性聲明XSLT版本,目前版本是1.0,2.0還在草案中,XSLT的所有內置元素都從屬于"http://www.w3.org/1999/XSL/Transform"命名空間,所以應該在文檔根元素上聲明一個xsl或xs的命名空間!
```
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" />
```
上面創建了一個最基本的XSLT文件,將其應用于任何XML文檔,在支持XSLT的瀏覽器打開該XML文檔,會看到所有的文檔顯示了出來,而標簽沒有了!事實上,在瀏覽器中真正顯示的是HTML,XSLT將XML轉換成了HTML.我們可以更進一步指定轉換成HTML的版本,比如轉換成XHTML!
```
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />
</xsl:stylesheet>
```
output元素定義輸出文檔的格式。method屬性可接受xml,html,text,name四種格式;version設置輸出格式的 W3C 版本號(僅在 method="html" 或 method="xml" 時使用); encoding設置輸出中編碼屬性的值(對于HTML將會輸出成charset的值); doctype-public規定 DTD 中要使用的公共標識符; doctype-system規定 DTD 中要使用的系統標識符; indent 規定在輸出結果樹時是否要增加空白,該值必須為 yes 或 no。
### template 模版
可以用template來定義模版.template元素必須有match或name兩個屬性之一或兩者都有,match屬性用以并聯XML中的元素,其值為一個XPath表達式,XPath表達式所選取的元素會被應用模版而進行轉換. name屬性為模版定義名稱,用以在其它地方引用.一個template元素里面包含的是一些將被輸出的HTML或XML標簽.
```
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/bank/p/name">
<strong>Name</strong>
</xsl:template>
</xsl:stylesheet>
```
對于使用一個沒有任何模版的XSLT的XML文件,在瀏覽器中顯示時只是簡單的將其中的文本顯示出來,應用了上面的XSLT之后,根元素bank下面子元素p的子元素name的值都將會顯示成一個加粗的Name!而其它的則只是普通的文本.但這樣并沒有什么意義,我們還可以更進一步,將被XPath表達式"/bank/p/name"選取的元素的值顯示出來-------value-of元素!value-of元素的select屬性是必須的,屬性值是一個XPath表達式,指定一個節點(如果是多節點,value-of中會獲取第一個節點的值),然后將其里面的文本輸出!將上面的模版替換成下面的,輸出后就會將所有的name加粗!
**注意,任何正文內容的輸出都應該放在template元素里面!**
```
<xsl:template match="/bank/p/name">
<strong><xsl:value-of select="." /></strong>
</xsl:template>
```
注意上面的value-of的select是使用的 "." ,而沒有使用"/bank/p/name",因為"/bank/p/name"返回的是所有的name元素," . "表示模版當前應用的那個元素!
可以定義多個模版,如下:
```
<xsl:template match="/bank/p/name">
<strong><xsl:value-of select="." />---</strong>
</xsl:template>
<xsl:template match="/bank/p/age">
<em><xsl:value-of select="." />---</em>
</xsl:template>
<xsl:template match="/bank/p/money">
<u><xsl:value-of select="." /></u><hr />
</xsl:template>
```
**當多個模版的match表達選取節點重疊時,后出現的模版的格式會覆蓋先出現的,可以使用template元素的priority屬性對模版的優先組進行編號,其值是一個數字,越大優先級越高!**
這樣,便給name,age,money這些元素都進行了格式化輸出,但現在輸出的HTML代碼順序仍然是按照在XML源文件中出現的順序出現的.當需要對整個XML文檔進行格式化輸出的時候,可以將match屬性設為"/"
```
<xsl:template match="/" />
```
使用上面的模版,將會使XML文檔在瀏覽器中沒有任何輸出.可以在應用于根節點的模版中加上HTML標簽,以輸出完整的HTML文檔!
```
<xsl:template match="/">
<html>
<head>
<title>XSLT</title>
</head>
<body> 一個HTML頁面 </body>
</html>
</xsl:template>
```
這樣,即使定義了其它模版,它們的輸出也不會出現在瀏覽器中,因為上面的模版覆蓋了其它應用于子節點的模版的輸出,要在其中包含其它模版的內容,可以使用XSLT的apply-templates元素來應用模版,該元素有兩個屬性,select屬性值是一個XPath表達式,XPath表達式選取的節點及其子節點將被應用模版. 如果沒有為這些節點定義模版,則直接輸出節點的值.如果apply-templates元素不指定select屬性,則將給當前節點(template元素的match屬性所匹配的節點)的所有后代節點應用模版,如果沒有定義模版,則直接輸出所有節點的值.
下面的代碼將直接輸出所有節點的值
**XSLT中有一個規定:如果一個節點沒有任何可用的template,則將這個節點中所有文本節點的值返回!**
```
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
```
可以指定select屬性,指明哪些節點將應用模版并輸出在這個地方,這樣就可以不以XML源文件中的順序輸出數據了!
```
<xsl:template match="/">
<xsl:apply-templates select="/bank/p/money" />
<hr />
<xsl:apply-templates select="/bank/p/name" />
</xsl:template>
```
還可以使用call-template調用指定的模版,call-template元素的name屬性指定要調用模版的name
### attribute 給元素添加屬性
使用attribute元素,可以在轉換時給元素動態添加屬性!其語法很簡單,下面是一個給img元素添加值為"test.jpg"的src屬性的代碼:
```
<img>
<xsl:attribute name="source">test.jpg</xsl:attribute>
</img>
```
### for-each 節點遍歷
XSLT中的for-each 元素允許您在 XSLT 中進行循環。該元素的select屬性與其它元素的select屬性一樣,其值是一個XPath表達式,被XPath表達式選取的元素將被遍歷!
```
<xsl:template match="/">
<xsl:for-each select="/bank/p/name">
<em><xsl:value-of select="." /></em><br />
</xsl:for-each>
</xsl:template>
```
上面的代碼將遍歷所有根元素bank的子元素p的name子元素并加以格式化后輸出它的值. 注意,value-of元素的select的值"."表示選取當前節點,在for-each的內部,當前節點為for-each當前遍歷到的節點!
### sort 排序
sort 元素用于對結果進行排序。sort元素需要放在for-each元素內部.sort元素的select屬性值為選取排序依據節點的XPath表達式,data-type屬性有兩個取值(text|number),指明是按字母順序排序還是按數字大小排序! 另外,它還有個order屬性,可以指定是按正順還是倒序排序,取值為(ascending|descending),默認是ascending(正序)!
```
<xsl:for-each select="/bank/p">
<xsl:sort select="./money" data-type="number" />
<xsl:value-of select="./money" /><br />
</xsl:for-each>
```
### if 條件測試
在XSLT中還可以使用if元素進行條件判斷,該元素的test屬性值為一個條件測試XPath表達式,當值計算結果是真的時候才處理if元素中的內容!
```
<xsl:for-each select="/bank/p">
<xsl:sort select="./money" data-type="number" order="descending" />
<xsl:if test="position() < 4 and age >=18">
<xsl:value-of select="./money" /><br />
</xsl:if>
</xsl:for-each>
```
上面的代碼用以輸出money排前三名的成年人. 注意,在if元素的test屬性中,XPath表達中的一些特殊字符(如大于和小于)必須寫成實體引用!
### choose when...otherwise...... 多重條件測試
出于習慣,見到if語句可能會想到if...else語句,但XSLT中并沒有if..else語句,取而代之的是即有if...else功能,又有switch..case功能的choose元素,choose元素有兩個子元素when與otherwise,相當于 else if 與else ,或者,when相當于case語句,otherwise相當于default.when元素的test屬性值同樣是一個XPath表達式,當這個表達式返回真的時候,when的子元素才會顯示!otherwise沒有test屬性,當所有的when元素的test都失敗后,處理otherwise子元素!
```
<xsl:choose>
<xsl:when test="name='PHPer'">PHPer就是PHP程序員的意思!</xsl:when>
<xsl:when test="name='CJ'">好好Coding,天天向上!</xsl:when>
<xsl:when test="name='DBD'">不懂!</xsl:when>
<xsl:otherwise>其它人</xsl:otherwise>
</xsl:choose>
```
## 瀏覽器中的 XSLT
只要有XML與XSLT解釋引擎,就可以在任何地方使用任何語言利用XSLT將XML轉換成HTML或其它文檔,并且使用不同的語言并不會影響轉換結果.也就是說,這種轉換是與語言無關的,既可以在服務器端進行轉換后,返回HTML頁面,也可以客戶端進行轉換,它們的效果都是一樣的.而且在客戶端對XML文件進行轉換,可以減輕服務器的負擔.
在一個引入了XSLT文件的XML文件,瀏覽器會自動對其進行轉換.但是,XML一般并不是在瀏覽器中顯示,而是用來讀取數據.當使用其它語言來手動轉換時,需要將xml-stylesheet這樣的PI去掉,這樣,XML 文件可使用多個不同的 XSL 樣式表來進行轉換,增加了靈活性。
### IE 中的XSLT
與IE支持XML DOM 一樣,IE中XSLT相關API顯得十分簡單,同時IE對XSLT的支持也很有限!下面是在IE 中將一個XMLDOM使用XSLT轉換成HTML的示例:
```
//載入XML數據文件
var xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.load("test.xml"); //載入XSLT文件,XSLT也是作為XML文件載入的
var xsl = new ActiveXObject("Microsoft.XMLDOM");
xsl.async = false;
xsl.load("test.xsl"); //直接在要轉換的DOM上調用transformNode方法,傳入XSLT DOM,返回字符串
document.write(xml.transformNode(xsl));
```
### Mozilla 中的XSLT
與Mozilla對XML DOM的支持一樣,它對XSLT的支持更標準但更復雜!Mozilla使用一個XSLTProcessor對象來處理與XSLT有關的轉換.
```
//載入XML數據
var xml = document.implementation.createDocument("","",null);
xml.async =false;
xml.load("test.xml"); //載入XSLT
var xsl = document.implementation.createDocument("","",null);
xsl.async =false;
xsl.load("test.xsl"); //創建XSLTProcessor
var xslPro = new XSLTProcessor();
xslPro.importStylesheet(xsl);//導入XSLT
//使用transformToDocument將XML按XSLT進行轉換,返回新文檔的DOM
var result = xslPro.transformToDocument(xml); //要將返回的DOM轉換成字符串,還要使用XMLSerializer對象
var serializer =new XMLSerializer(); var html = serializer.serializeToString(result);
document.write(html);
```
- 介紹
- HTML/CSS 教程
- 第 1 章 HTML5 概述
- 第 2 章 基本格式
- 第 3 章 文本元素
- 第 4 章 超鏈接和路徑
- 第 5 章 分組元素
- 第 6 章 表格元素
- 第 7 章 文檔元素
- 第 8 章 嵌入元素
- 第 9 章 音頻和視頻
- 第 10 章 表單元素[上]
- 第 10 章 表單元素[中]
- 第 10 章 表單元素[下]
- 第 11 章 全局屬性和其他
- 第 12 章 CSS 入門
- 第 13 章 CSS 選擇器[上]
- 第 14 章 CSS 顏色與度量單位
- 第 15 章 CSS 文本樣式[上]
- 第 15 章 CSS 文本樣式[下]
- 第 16 章 CSS 盒模型[上]
- 第 16 章 CSS 盒模型[下]
- 第 17 章 CSS 邊框與背景[上]
- 第 17 章 CSS 邊框與背景[下]
- 第 18 章 CSS 表格與列表
- 第 19 章 CSS 其他樣式
- 第 20 章 CSS3 前綴和 rem
- 第 21 章 CSS3 文本效果
- 第 21 章 CSS3 文本效果
- 第 23 章 CSS3 邊框圖片效果
- 第 24 章 CSS3 變形效果[下]
- 第 25 章 CSS3 過渡效果
- 第 26 章 CSS3 動畫效果
- 第 27 章 CSS 傳統布局[上]
- 第 27 章 CSS 傳統布局[下]
- 第 28 章 CSS3 多列布局
- 第 29 章 CSS3 彈性伸縮布局[上]
- 第 29 章 CSS3 彈性伸縮布局[中]
- 第 29 章 CSS3 彈性伸縮布局[下]
- 第 30 章 使用 Emmet 插件
- Bootstrap 教程
- 第 1 章 Bootstrap 介紹
- 第 2 章 排版樣式
- 第 3 章 表格和按鈕
- 第 4 章 表單和圖片
- 第 5 章 柵格系統
- 第 6 章 輔組類和響應式工具
- 第 7 章 圖標菜單按鈕組件
- 第 8 章 輸入框和導航組件
- 第 9 章 路徑分頁標簽和徽章組件
- 第 10 章 巨幕頁頭縮略圖和警告框組件
- 第 11 章 進度條媒體對象和 Well 組件
- 第 12 章 列表組面板和嵌入組件
- 第 13 章 模態框插件
- 第 14 章 下拉菜單和滾動監聽插件
- 第 15 章 標簽頁和工具提示插件
- 第 16 章 彈出框和警告框插件
- 第 17 章 按鈕和折疊插件
- 第 18 章 輪播插件
- 第 19 章 附加導航插件
- 第 20 章 項目實戰--響應式導航[1]
- 第 20 章 項目實戰--響應式輪播圖[2]
- 第 20 章 項目實戰--首頁內容介紹[上][3]
- 第 20 章 項目實戰--首頁內容介紹[下][4]
- 第 20 章 項目實戰--資訊內容[5,6]
- 第 20 章 項目實戰--案例和關于[7]
- javaScript 教程
- javascript快速入門1--JavaScript前世今生,HelloWorld與開發環境
- javascript快速入門2--變量,小學生數學與簡單的交互
- javascript快速入門3--分支判斷與循環
- javascript快速入門4--函數與內置對象
- javascript快速入門5--數組與對象
- javascript快速入門6--Script標簽與訪問HTML頁面
- javascript快速入門7--ECMAScript語法基礎
- javascript快速入門8--值,類型與類型轉換
- javascript快速入門9--引用類型
- javascript快速入門10--運算符,語句
- javascript快速入門11--正則表達式
- javascript快速入門12--函數式與面向對象
- javascript快速入門13--BOM——瀏覽器對象模型(Browser Object Model)
- javascript快速入門14--DOM基礎
- javascript快速入門15--節點
- javascript快速入門15--表單
- javascript快速入門16--表格
- javascript快速入門17--事件
- javascript快速入門18--樣式
- javascript快速入門19--定位
- javascript快速入門20--Cookie
- javascript快速入門21--DOM總結
- javascript快速入門22--Ajax簡介
- javascript快速入門23--XHR—XMLHttpRequest對象
- javascript快速入門24--XML基礎
- javascript快速入門25--瀏覽器中的XML
- javascript快速入門26--XPath
- javascript快速入門27--XSLT基礎
- PHP 教程
- 第一章 如何加載運行已發布的PHP項目
- 第二章 PHP基礎
- 第三章 操作符與控制結構
- 第四章 數學運算
- 第五章 數組
- 第六章 目錄與文件
- 第七章 自定義函數
- 第八章 字符串處理
- 第九章 正則表達式
- 第十章 日期與時間
- 第十一章 表單與驗證
- 第十二章 會話控制
- 第十三章 上傳文件
- 第十四章 處理圖像
- 第十五章 MySQL 數據庫
- 第十六章 PHP 操作MySQL
- 第十七章 面向對象基礎
- 第十八章 面向對象的特性
- 第十九章 面向對象的工具