使用AJAX做XSL变换
1 什么是XSL
XSL,EXtensible Stylesheet Language,是可扩展样式表语言。它包含三部分:XSLT、XPath和XSL-FO。其中,XSLT,XSL Transformations,是XSL变换;XPath,XML Path Language,是XML路径描述语言;XSL-FO,XSL Formatting Objects,XSL格式对象。
其中XSLT是XSL最核心的部分,它用来对XML进行变换。XSLT可以把XML数据文件转换成HTML、其它结构的XML等,甚至可以是非DOM的文本文档。对于XSL的相关内容,这里不做详细介绍。如图1是XSLT变换的示意。
图1.XSLT变换原理
2 怎么用AJAX做变换
2.1 使用AJAX做什么
从上图可以看出,XSLT的实现是一件非常复杂的事情,既要实现XML解析(XSL文件也是XML文档格式),又要做XSLT变换。
然而幸运的是,浏览器(IE6.0以上及FireFox1.2以上)已经集成了XSL的变换器,我们要做的事情只是得到XML DOM和XSL DOM,然后交给变换器去做。这正是AJAX要做的事情。
2.2 使用AJAX做变换
2.2.1 标准实现机制
我们使用AJAX做的事情,就是使用XMLHttpRequest(AJAX的XML异步请求机制)得到XML DOM,然后交给XSLTProcessor(XSL变换器)处理,便得到了我们想要的输出结果。并且,XMLHttpRequest、XSLTProcessor的实现是符合W 3C 标准的。
XML DOM的得到过程
// load the xslt file
var myXMLHTTPRequest = new XMLHttpRequest();
myXMLHTTPRequest.open("GET", Xsl_Url, false);
myXMLHTTPRequest.send(null);
XSLTProcessor对象的创建过程
//create XSLTProcessor
var xsltProcessor = new XSLTProcessor();
//import XSL file
xsltProcessor.importStylesheet(xslStylesheet);
//set parameters, defined in XSL file
xsltProcessor.setParameter(null, "parameter", parameter);
所以,对于变换,我们可以很容易写出。例如,下面的一段代码就是由AJAX实现的XSLT变换:
var Xsl_Url='http://shdwfk.googlepages.com/example.xsl';
var Xml_Url='http://shdwfk.googlepages.com/example.xml';
var parameter='parameter';
function function_by_uniexplorer(){
// load the xslt file
var myXMLHTTPRequest = new XMLHttpRequest();
myXMLHTTPRequest.open("GET", Xsl_Url, false);
myXMLHTTPRequest.send(null);
//get XSL DOM
var xslStylesheet = myXMLHTTPRequest.responseXML;
//create XSLTProcessor
var xsltProcessor = new XSLTProcessor();
//import XSL file
xsltProcessor.importStylesheet(xslStylesheet);
//set parameters, defined in XSL file
xsltProcessor.setParameter(null, "parameter", parameter);
// load the xml file
myXMLHTTPRequest = new XMLHttpRequest();
myXMLHTTPRequest.open("GET", Xml_Url, false);
myXMLHTTPRequest.send(null);
//get XML DOM
var xmlDoc = myXMLHTTPRequest.responseXML;
//do XSLT transform
var fragment = xsltProcessor.transformToFragment(xmlDoc, document);
//insert the result to the html dom
document.getElementById(Container_Id).innerHTML = "";
document.getElementById(Container_Id).appendChild(fragment);
}
这样看来我们已经大功告成了,已经实现了此次变换。并且,变换过程相当简单。
2.2.2 IE中的实现机制
然而,很不幸的是,以上代码不能在IE Explorer里执行,在IE中XSLT有他自己的一套实现机制。所以,我们还必须的准备一套适用于IE的AJAX的代码。
IE并没有XMLHttpRequest对象,而是由一个名称为MSXML2.DOMDocument.*的ActiveX对象来实现。IE中XML DOM对象的生成代码如下所示:
function XmlDom(){
var arrSignatures = ["MSXML2.DOMDocument.5.0","MSXML2.DOMDocument.4.0","MSXML2.DOMDocument.3.0"];
for(var i=0; i<arrSignatures.length;i++) {
try{
var oXmlDom=new ActiveXObject(arrSignatures[i]);
return oXmlDom;
}catch(oError) {
}
}
alert("I am sorry, IE v6.0+ is required!");
throw new Error("IE v6.0+ is required!");
}
为了在XSL中能够使用参数,我们必须使用专门的XSL DOM对象:“MSXML2.FreeThreadedDOMDocument.*”,对象的生成代码如下所示:
function XslDom() {
var arrSignatures = ["MSXML2.FreeThreadedDOMDocument.4.0","MSXML2.FreeThreadedDOMDocument.3.0"];
for(var i=0; i<arrSignatures.length;i++) {
try{
var oXslDom=new ActiveXObject(arrSignatures[i]);
return oXslDom;
}catch(oError) {
}
}
alert("I am sorry, IE v6.0+ is required!");
throw new Error("IE v6.0+ is required!");
}
接下来,我们要做的事情是要实例化XSLTProcessor对象,这在IE中,是一个Msxml2.XSLTemplate.*的ActiveX对象,实例化为JavaScript对象,代码如下所示:
function XSLTemplate(){
var arrSignatures = ["Msxml2.XSLTemplate.4.0","MSXML2.XSLTemplate"];
for(var i=0; i<arrSignatures.length;i++) {
try{
var template=new ActiveXObject(arrSignatures[i]);
return tempalte;
}catch(oError) {
}
}
alert("I am sorry, IE v6.0+ is required!");
throw new Error("IE v6.0+ is required!");
}
接下来我们就可以来做变换了:
function function_by_iexplorer() {
//create xsl dom object
var oXslDom = new XslDom();
oXslDom.async=false;
oXslDom.load(Xsl_Url);
//create xml dom object
var oXmlDom = new XmlDom();
oXmlDom.async=false;
oXmlDom.load(Xml_Url);
//create xsl template
oXslTemplate=new XSLTemplate();
//set xsl-dom to stylesheet
oXslTemplate.stylesheet=oXslDom;
//use the template to create a processor
var oXslProcessor=oXslTemplate.createProcessor();
//set xml-dom to processor
oXslProcessor.input=oXmlDom;
//set parameter
oXslProcessor.addParameter("parameter", parameter);
//do transform
oXslProcessor.transform();
//insert the result text to html documnet
document.getElementById(Container_Id).innerHTML = "";
document.getElementById(Container_Id).innerHTML = oXslProcessor.output;
}
本节所有代码就是IE中进行XSLT变换的AJAX实现机制。
2.2.3 UNIVERSAL CODE
为了让XSLT能够在IE中或者Firefox中均能顺利执行,我们需要一个判断并且分支调用函数就可以了
function doXSLTranform()
{
if(window.XMLHttpRequest)
function_by_uniexplorer();
else if(window.ActiveXObject)
function_by_iexplorer();
else
alert("Unknown Browser, Please use IE or Mozilla in higher vision.");
}
3 An Example
一个例子,http://shdwfk.googlepages.com/test.html ,Html源码如下:
<!DOCTYPE HTML PUBLIC "-//W 3C //DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Test</title>
<script src="http://shdwfk.googlepages.com/xslt.js"></script>
<script>
window.οnlοad=function() {
doXSLTranform();
}
</script>
</head>
<body>
<div id="example_div" />
</body>
</html>
其中http://shdwfk.googlepages.com/xslt.js 便是上面描述的AJAX代码引用(可以下载)。
XML源码:http://shdwfk.googlepages.com/example.xml
XSL源码:http://shdwfk.googlepages.com/example.xsl
如果没有显示或者显示不正确,那么下载上述四个链接的源码,保存在同一目录,将html中csript src的引用改为xslt.js。且修改xslt.js,将
var Xsl_Url='http://shdwfk.googlepages.com/example.xsl'; 语句
改为: var Xsl_Url='example.xsl';
将var Xml_Url='http://shdwfk.googlepages.com/example.xml'; 语句
改为: var Xml_Url='example.xml';
4 总结
上面代码大体上搜、阐述了怎么用AJAX写XSLT变换的代码,其实原理很简单,也没有太大的工作量。
IE中使用ActiveX对象实现了XSLT,从而产生了浏览器兼容的问题。IE中实现的代码略微复杂,可以被封装成对象,方便再次应用。
关于XMLHttpRequest对象以及XSLTemplate等ActiveX对象的详细属性及方法,可以参照官方的文档,这里不在赘述。