天天看點

xlst 應用系列二(轉載)

7.3.1  XSLT應用示例

在前面幾章的例子中,伺服器端傳回的資料集通常是DataSet類型的,在用戶端通過“for”循環周遊所有結果,然後輸出到頁面上。這樣的實作方法比較普遍,開發人員可能會在不同的應用中編寫這樣雷同的代碼,十分枯燥,在規模較大的項目中,這樣的代碼就顯得冗長而結構不清晰。在Garrett所定義的關于Ajax的7項技術中,XSLT常常被很多人忽略,但是實際上它的功能非常強大,可以幫助我們實作類似“模闆”的機制,在XSLT樣式表中可以定義頁面的布局、顯示樣式等,而在XML中提供資料,進而實作顯示和資料的完全分離。

考慮到XSLT技術對相當一部分讀者來說還比較陌生,這裡通過一些簡短的示例來說明XSLT的使用方法,相信會對讀者了解後面的代碼有所幫助。XSLT樣式表可以将XML格式的資料轉換為其他任何格式的内容,可以是XML,也可以是HTML,甚至進階語言(Java、C#)的代碼。以XML+XSLTHTML為例,XML檔案a.xml的内容如例7-6所示。

【例7-6】a.xml

<?xml version="1.0" encoding="UTF-8"?>
<articles>
<article>
<author>author1</author>
<title>title1</title>
<date>2005-2-25</date>
<content><![CDATA[hello
klfkdlskdf
dkfldksdfsd]]></content>
</article>
<article>
<author>author1</author>
<title>title1</title>
<date>2005-2-25</date>
<content><![CDATA[hello
klfkdlskdf
dkfldksdfsd]]></content>
</article>
<article>
<author>author1</author>
<title>title1</title>
<date>2005-2-25</date>
<content><![CDATA[hello
klfkdlskdf
dkfldksdfsd]]></content>
</article>
<article>
<author>author1</author>
<title>title1</title>
<date>2005-2-25</date>
<content><![CDATA[hello
klfkdlskdf
dkfldksdfsd]]></content>
</article>
<article>
<author>author1</author>
<title>title1</title>
<date>2005-2-25</date>
<content><![CDATA[hello
klfkdlskdf
dkfldksdfsd]]></content>
</article>
</articles>      

例7-6中描述的是一組文章的資訊,現在我們希望将它轉換成為HTML頁面,并且用表格的形式呈現出來。是以,編寫如例7-7所示的XSLT樣式表。

【例7-7】a.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>test</title>
</head>
<body>
<table border="1">
<tbody>
<tr>
<th>author</th>
<th>title</th>
<th>date</th>
</tr>
<xsl:for-each select="/articles/article">
<tr>
<td>
<xsl:value-of select="author"/>
</td>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="date"/>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>      

請讀者注意粗體的部分,它們的共同點是都以“<xsl:”開頭,它是XSLT的命名空間。任何一個XSLT樣式表都有<xsl:template match="/">節點,它表示和XML的根節點相比對。“<xsl:for-each select="/articles/article">"節點則表示開始一個循環,參與循環的節點是由“select”對應的XPath(/articles/article)決定的。在例7-6中,它對應于所有的article節點。<xsl:value-of select="author"/>表示author節點的值,類似的,title和date對應于title和date節點。最後,a.xml通過a.xslt轉換的結果如例7-8所示。

【例7-8】轉換結果

<html>
<head>
<title>test</title>
</head>
<body>
<table border="1">
<tbody>
<tr>
<th>author</th>
<th>title</th>
<th>date</th>
</tr>
<tr>
<td>author1</td>
<td>title1</td>
<td>2005-2-25</td>
</tr>
<tr>
<td>author1</td>
<td>title1</td>
<td>2005-2-25</td>
</tr>
<tr>
<td>author1</td>
<td>title1</td>
<td>2005-2-25</td>
</tr>
<tr>
<td>author1</td>
<td>title1</td>
<td>2005-2-25</td>
</tr>
<tr>
<td>author1</td>
<td>title1</td>
<td>2005-2-25</td>
</tr>
</tbody>
</table>
</body>
</html      

也可以在a.xml的第2行增加一句XSLT樣式表聲明,如下:

<?xml-stylesheet type="text/xsl" href="a.xslt"?>

這樣就可以在IE浏覽器中檢視到效果了,如圖7-4所示。

圖7-4  XSLT轉換後的XML

通過上面的示例,讀者可以對XSLT有一個大緻的了解,下面來介紹如何在用戶端JavaScript中實作XSLT轉換。對于IE浏覽器來說,通過XMLDOM元件可以比較容易地實作XSLT轉換。示例代碼如下:

<script language="javascript">
// Load XML 
var xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.load("a.xml");      
// Load the XSL
var xsl = new ActiveXObject("Microsoft.XMLDOM");
xsl.async = false;
xsl.load("a.xslt");      
// Transform
document.write(xml.transformNode(xsl));
</script>      

對于其他不支援ActiveX控件的浏覽器來說,就需要借助于第三方的腳本庫了,這裡介紹來自Google公司的google ajaxslt,它是基于JavaScript實作的,适用于任何浏覽器,并且還有比較實用的日志和調試功能。例7-9所示的就是應用google ajaxslt實作XSLT轉換的例子。

【例7-9】b.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Simple XSLT test</title>
<script src="misc.js" type="text/javascript"></script>
<script src="dom.js" type="text/javascript"></script>
<script src="xpath.js" type="text/javascript"></script>
<script src="xslt.js" type="text/javascript"></script>
</head>
<body>
<div id="content"></div>
</body>
<script type="text/javascript">
logging__ = true;
xsltdebug = true;

// 根據傳入的id擷取頁面中的對象
function el(id)
{
return document.getElementById(id);
}

// 進行xslt轉換:a.xml + a.xslt
function test_xslt()
{
var strXml = getXml("a.xml");
var strXsl = getXml("a.xslt");
var xml = xmlParse(strXml);
var xslt = xmlParse(strXsl);
var html = xsltProcess(xml, xslt);
return html;
}

//擷取xml檔案的内容,基于xmlhttp
function getXml(url)
{
var xmlhttp;
/*@cc_on
@if (@_jscript_version >= 5)
try
{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (E)
{
xmlhttp = false;
}
}
@else
xmlhttp = false;
@end @*/
if (!xmlhttp && typeof XMLHttpRequest != 'undefined')
{
try
{
xmlhttp = new XMLHttpRequest();
}
catch (e)
{
xmlhttp = false;
}
}

xmlhttp.open("GET", url);
xmlhttp.send(null);
return xmlhttp.responseXml.xml;

}

//顯示轉換的結果
el("content").innerHTML = test_xslt();

</script>
</html>