xsltprocessor 是现代浏览器唯一原生支持的 xslt 处理方案,仅限同源 xml/xslt 文件,要求输入为 application/xml 解析的 document,输出可选 transformtofragment(推荐用于 dom 插入)或 transformtodocument,并支持通过 setparameter 注入字符串参数。

浏览器中 XSLTProcessor 是唯一可行的原生方案
现代浏览器(chrome、firefox、safari、edge)都支持 XSLTProcessor API,但仅限于同源 XML + XSLT 文件,且不支持 xsl:import / xsl:include 中的跨域引用。它不能处理字符串形式的 XSLT(除非先解析为 Document),也不能直接作用于 HTML 文档树——输入必须是 XMLDocument 或 Document(且被当作 XML 处理)。
常见错误现象:XSLTProcessor.importStylesheet() 报错 “NotSupportedError: Cannot import stylesheet from non-XML document”,通常是因为传入了用 DOMParser 解析 HTML 字符串得到的 Document(MIME 类型不是 application/xml 或 text/xml)。
- 确保 XSLT 文件响应头含
Content-Type: application/xml或text/xml - 用
fetch(url).then(r => r.text()).then(str => new DOMParser().parseFromString(str, "application/xml"))加载 XSLT - XML 源也必须用相同 MIME 类型解析,例如:
new DOMParser().parseFromString(xmlStr, "application/xml") - 若 XML 字符串含
<?xml version="1.0"?>,确保开头无 bom 或空白字符,否则parseFromString可能静默失败
transformToFragment 和 transformToDocument 的选择逻辑
二者决定输出形态:transformToFragment 返回 DocumentFragment(适合插入到现有 HTML 节点),transformToDocument 返回新 XMLDocument(需再用 document.adoptNode 或 innerHTML 渲染)。
性能影响:若目标是更新页面某区域,优先用 transformToFragment;若需进一步遍历结果节点(如绑定事件),transformToFragment 更轻量,避免额外文档对象创建。
立即学习“Java免费学习笔记(深入)”;
-
transformToFragment要求传入一个Document实例作为上下文(通常是document),否则报错 “InvalidAccessError” -
transformToDocument返回的XMLDocument无法直接appendChild到 HTMLbody,必须先提取子节点或用innerHTML = doc.documentElement.outerHTML - 若 XSLT 输出为 HTML 片段(如
<div><p>...</p></div>),transformToFragment是最简路径
XSLT 中访问 javaScript 变量需靠 setParameter 注入
浏览器端 XSLT 不支持直接调用 js 函数,但可通过 XSLTProcessor.setParameter(NULL, "name", value) 向 XSLT 的 xsl:param 注入值。注意:参数类型固定为字符串,数字/布尔/对象都会被强制转为字符串。
使用场景:动态控制模板分支(如 <if test="$debug = 'true'">...</if>)、替换占位符(<value-of select="$base_url"></value-of>)。
- XSLT 中必须显式声明
<param name="base_url">,否则setParameter无效 - 参数名区分大小写,且不能含连字符(
-)或空格 - 若需传入数组或结构化数据,建议 JSON.stringify 后在 XSLT 中用
substring-before等函数解析(不推荐复杂逻辑) - 多次调用
setParameter会覆盖前值,无批量设置方法
const xslt = `<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="title" /> <xsl:template match="/"> <h1><xsl:value-of select="$title"/></h1> </xsl:template> </xsl:stylesheet>`; const xml = `<root/>`; const xsltDoc = new DOMParser().parseFromString(xslt, "application/xml"); const xmlDoc = new DOMParser().parseFromString(xml, "application/xml"); const processor = new XSLTProcessor(); processor.importStylesheet(xsltDoc); processor.setParameter(null, "title", "Hello from JS"); const resultFragment = processor.transformToFragment(xmlDoc, document); document.body.appendChild(resultFragment);
兼容性边界容易被忽略:IE 完全不支持 XSLTProcessor(它用旧版 MSXML),而 Safari 对 transformToFragment 的 Document 上下文检查更严格——若传入 shadow root 内的 document,可能失败。真实项目中,建议对 typeof XSLTProcessor !== 'undefined' 做降级处理(如改用纯 JS 模板)。