因为现在的项目用到 Ajax,服务器端返回 XML 到前台,然后通过 XSLT 转换成 HTML,这个组合的运用也有几个月了,一直没出现什么大的问题,或者说莫名其妙的问题,不过今天就遇到这么一个怪问题,XML 返回一个简单的元素标签,通过 XLST 解析把标签的内容显示出来,当然其中涉及到更多的业务逻辑,不过我现在把跟问题相关的部分提取出来,假设返回的 XML 文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="1.xslt"?>
<root>
<message>测试测试测试</message>
</root>
<?xml-stylesheet type="text/xsl" href="1.xslt"?>
<root>
<message>测试测试测试</message>
</root>
相关的 XSLT 文件内容如下(根据上面的 XML 保存成文件名为 1.xslt):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:template match="root">
<xsl:value-of select="message"/>
</xsl:template>
</xsl:stylesheet>
就是这么简单的一段文本,压根儿就不知道哪里会有问题,但在 IE 下可以正常显示 message 标签中的文本,放到 Firefox 下就死活读取不到内容,在页面上通过如下 JS 获取最终转换成的 HTML,但也只能取到空值:
function getHtml(xmlText, xsltFile){
var text;
if(typeof(window.ActiveXObject) != 'undefined'){
// 支持IE浏览器
try{
var xmlDoc=new ActiveXObject("Msxml2.DOMDocument.3.0");
xslDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
xmlDoc.async=false;
xslDoc.async = false;
xmlDoc.loadXML(xmlText);
xslDoc.load(xsltFile);
text = xmlDoc.documentElement.transformNode(xslDoc.documentElement);
}catch(e){
if (isDebug) alert(e.name + ": " + e.message);
alert("Unable to do xml/xsl processing");
alert(e.name + ": " + e.message);
}
}else if(document.implementation && document.implementation.createDocument){
// 支持Mozilla浏览器
try {
// 在Firefox的XML DOM实现中,并没有loadXML()方法,不过通过Firefox中的DOMParser类可以模拟loadXML()的行为
var oParser = new DOMParser();
var xmlDoc = oParser.parseFromString(xmlText,"text/xml");
xslDoc = document.implementation.createDocument("", "", null);
xslDoc.async = false;
xslDoc.load(xsltFile);
// 定义XSLTProcessor对象
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xslDoc);
// transformToDocument方式
var result = xsltProcessor.transformToDocument(xmlDoc);
var xmls = new XMLSerializer();
text = xmls.serializeToString(result);
}
catch(e) {
if (isDebug) alert(e.name + ": " + e.message);
alert("Unable to do xml/xsl processing");
}
}
return text;
}
var text;
if(typeof(window.ActiveXObject) != 'undefined'){
// 支持IE浏览器
try{
var xmlDoc=new ActiveXObject("Msxml2.DOMDocument.3.0");
xslDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
xmlDoc.async=false;
xslDoc.async = false;
xmlDoc.loadXML(xmlText);
xslDoc.load(xsltFile);
text = xmlDoc.documentElement.transformNode(xslDoc.documentElement);
}catch(e){
if (isDebug) alert(e.name + ": " + e.message);
alert("Unable to do xml/xsl processing");
alert(e.name + ": " + e.message);
}
}else if(document.implementation && document.implementation.createDocument){
// 支持Mozilla浏览器
try {
// 在Firefox的XML DOM实现中,并没有loadXML()方法,不过通过Firefox中的DOMParser类可以模拟loadXML()的行为
var oParser = new DOMParser();
var xmlDoc = oParser.parseFromString(xmlText,"text/xml");
xslDoc = document.implementation.createDocument("", "", null);
xslDoc.async = false;
xslDoc.load(xsltFile);
// 定义XSLTProcessor对象
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xslDoc);
// transformToDocument方式
var result = xsltProcessor.transformToDocument(xmlDoc);
var xmls = new XMLSerializer();
text = xmls.serializeToString(result);
}
catch(e) {
if (isDebug) alert(e.name + ": " + e.message);
alert("Unable to do xml/xsl processing");
}
}
return text;
}
不过问题终于在休息了一个中午后被解决了,原来是需要在 <xsl:value-of select="message"/> 两边加上一个标签对这样才能在 Firefox 中被正常显示出来,如 <span><xsl:value-of select="message"/></span>,这问题似乎来得有点不合常理,因为纯文件本来在 Firefox 本来就可以正常被显示出来的,为什么在这里就不行呢?
注:文中用到的 IE 为 IE 6.0 版本,Firefox 为 Firefox 2.0 版本