XSLT學習


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() &lt; 4 and age &gt;=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);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM