从变量加载XML与XSL并在浏览器中转换出错求助
问题分析与解决方案
嘿,我来帮你搞定这个XSLT转换的问题!
一、为什么会报错?
你看到的 TypeError 核心原因很简单:XSLTProcessor.importStylesheet() 和 transformToFragment() 都要求传入已经解析好的XML DOM节点,而不是原始的字符串。你现在直接把XML/XSL的文本字符串传进去,浏览器自然会告诉你参数类型不对啦。
二、修复后的跨浏览器代码(兼容IE)
下面是修正后的代码,重点是先把字符串转换成浏览器能识别的DOM文档对象,再进行转换,同时兼顾了现代浏览器和IE的差异:
// 封装一个跨浏览器的XML字符串解析函数 function parseXmlString(xmlStr) { var xmlDoc; if (window.DOMParser) { // 现代浏览器用DOMParser var parser = new DOMParser(); xmlDoc = parser.parseFromString(xmlStr, "text/xml"); } else { // IE浏览器用ActiveX对象 xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = false; xmlDoc.loadXML(xmlStr); } return xmlDoc; } var xsltProcessor, resultDocument, xmlDoc, xslDoc; var xml = '<?xml version="1.0" encoding="UTF-8"?><catalog><cd><title>Empire Burlesque</title></cd></catalog>'; var xsl = '<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/"> <h2>My CD Collection</h2> <table border="1"> <tr bgcolor="#9acd32"> <th style="text-align:left">Title</th> <th style="text-align:left">Artist</th> </tr> <xsl:for-each select="catalog/cd"> <tr> <td><xsl:value-of select="title" /></td> </tr> </xsl:for-each> </table></xsl:template></xsl:stylesheet>'; // 先把字符串解析成DOM文档 xmlDoc = parseXmlString(xml); xslDoc = parseXmlString(xsl); try { if (window.XSLTProcessor) { // 现代浏览器的处理逻辑 xsltProcessor = new XSLTProcessor(); xsltProcessor.importStylesheet(xslDoc); // 现在传的是DOM节点,不是字符串! resultDocument = xsltProcessor.transformToFragment(xmlDoc, document); } else { // IE浏览器的专属处理(用XSLTemplate和Processor) var xslt = new ActiveXObject("Msxml2.XSLTemplate.6.0"); xslt.stylesheet = xslDoc; var xslProc = xslt.createProcessor(); xslProc.input = xmlDoc; xslProc.transform(); resultDocument = xslProc.output; } console.log(resultDocument); // 如果要把结果插入页面,直接append就行 // document.body.appendChild(resultDocument); } catch (error) { console.log('err=' + error); }
三、关于现代前端替代方案
你说得没错,客户端XSLT确实在2014年后关注度下降了。如果要做跨浏览器兼容(包括IE),可以考虑这些方向:
- 原生API封装:就像上面的代码一样,自己封装兼容逻辑,没有额外依赖,轻量化。
- jQuery插件:比如
jquery-xslt这类插件,已经帮你封装好了跨浏览器的转换逻辑,调用起来更省心。 - 模板引擎替代:如果不需要严格遵循XSLT标准,也可以把XML转换成JSON,然后用Handlebars、Mustache这类现代模板引擎渲染HTML,这种方式更符合当前前端开发的习惯,兼容性也更好。
需要注意的是,IE下的ActiveX对象可能需要用户开启对应的安全设置,这是IE环境下无法避免的小问题。
内容的提问来源于stack exchange,提问作者Vanquished Wombat
相关产品推荐
相关产品推荐

