天天看点

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>