Edge与Chrome中XSLTProcessor能否传递文档节点作为XSLT参数
问题原因
基于Chromium内核的Edge、Chrome浏览器原生XSLTProcessor不支持传入DOM节点作为XSLT转换参数,该能力是Firefox搭载的Gecko引擎的私有非标准实现,不属于W3C XSLT 1.0规范的要求,因此直接传入节点的写法会导致transformToFragment执行失败返回null。
兼容方案
以下两种方案均可在Edge/Chrome/Firefox全浏览器正常运行:
方案1:参数节点注入主文档(兼容性最优,无扩展依赖)
不需要通过setParameter传递节点,直接把参数节点导入到待转换的主XML文档中,XSLT直接从主文档读取对应节点即可,无需依赖任何XSLT扩展函数。
代码修改
- JS部分调整,将参数节点挂载到主XML文档:
// 原有参数节点创建逻辑保留 const docParam = parser.parseFromString("<PARAM><PARAMETER VALUE='5'/></PARAM>", "application/xml"); // 新增:把参数节点导入主文档,挂载到根节点下 const importedParam = docData.importNode(docParam.documentElement, true); docData.documentElement.appendChild(importedParam); // 删除原有的setParameter传节点逻辑
- XSLT部分调整,直接读取主文档内的参数节点:
<!-- 删除<xsl:param name='ntParam'/>声明 --> <!-- 变量取值直接从主文档查找节点 --> <xsl:variable name='numTransformLevel' select='//PARAM/PARAMETER/@VALUE'/>
方案2:序列化节点为字符串传参,XSLT内解析为节点集
如果必须通过参数传递节点,可先将节点序列化为XML字符串传入,再通过EXSLT通用扩展的node-set函数解析为节点集使用,主流浏览器的XSLT引擎均支持该扩展。
代码修改
- JS部分调整,序列化节点后传字符串参数:
const serializer = new XMLSerializer(); const paramNodeStr = serializer.serializeToString(docParam.documentElement); xsltProcessor.setParameter(null, "ntParam", paramNodeStr);
- XSLT部分调整,引入EXSLT命名空间解析参数:
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:exsl="http://exslt.org/common" xmlns="http://www.w3.org/1999/xhtml" extension-element-prefixes="exsl"> <!-- 原有参数声明保留 --> <xsl:param name='ntParam'/> <!-- 新增:将字符串参数转为节点集 --> <xsl:variable name="ntParamNode" select="exsl:node-set($ntParam)"/> <!-- 调整变量取值路径 --> <xsl:variable name='numTransformLevel' select='$ntParamNode/PARAMETER/@VALUE'/>
补充说明
Chromium内核的XSLT实现严格遵循XSLT 1.0标准,仅支持字符串、数字、布尔值三类基础类型作为setParameter的入参,不支持DOM节点、节点集这类复杂类型入参,开发时需要避免使用Firefox独有的私有XSLT特性。
内容的提问来源于stack exchange,提问作者BennyHilarious
相关产品推荐
相关产品推荐

