SaxonJS在Chrome控制台出现Uncaught TypeError: Cannot read properties of null (reading 'hashCode')错误排查求助
解决SaxonJS中"Cannot read properties of null (reading 'hashCode')"错误
这个Cannot read properties of null (reading 'hashCode')错误在SaxonJS里挺常见的,大多是空值处理不当或者编译兼容性问题导致的。结合你的代码和场景——XSLT在Oxygen的Saxon 9.8 EE能正常跑,但SaxonJS运行报错,其他SEF文件没问题——我帮你梳理下排查和修复的思路:
错误核心原因
这个错误本质是SaxonJS尝试访问一个null对象的hashCode属性,通常触发场景和你代码里的map操作、变量引用空值,或者SEF编译时的版本兼容性有关。
具体排查修复步骤
1. 给Map操作加上空值防护
看你代码里的几个map变量,很容易出现空引用:
$map_staves_order是map的序列,要是某个循环里没有找到staffDef,就会生成空map;后续map:keys操作空map就可能出问题。$map_new_old_staves里的map:get($map_staves_order, $current_key)如果找不到对应key,会返回空值,直接赋值给map-entry的value会埋下隐患。
修改建议:
- 给生成
$map_staves_order的循环加过滤,确保只处理有staffDef的节点:
<variable as="map(xs:string, item())*" name="map_staves_order"> <for-each select="$global-context-item//choice[@type = 'scoring']/*[@corresp = concat('#', $source)]/scoreDef[exists(descendant::staffDef)]"> <map> <for-each select="descendant::staffDef"> <map-entry key="string(@n)" select="@dme.parts"/> </for-each> </map> </for-each> </variable>
- 用XPath 3.1的
map:get默认值语法,避免空值:
<!-- 找不到key时返回空字符串,而不是null --> map:get($map_staves_order, $current_key, '')
2. 确认$global-context-item的有效性
你的XSLT严重依赖$global-context-item,但在SaxonJS运行时,这个参数可能没正确绑定到源文档:
- 如果
$global-context-item是null,后续所有基于它的节点查询都会返回空,直接导致map变量为空,触发错误。
修改建议:
- 要么在JS调用时明确传递这个参数:
var options = { stylesheetLocation: "./assets/xsl/origScoring.sef.json", sourceText: xmlString, stylesheetParams: { "source": "source_A", "global-context-item": SaxonJS.getDocument(xmlString) }, destination: "document" }
- 要么修改XSLT的参数定义,直接绑定到
$source参数(如果$source就是目标文档):
<param name="global-context-item" select="$source"/>
3. 确保SEF编译的兼容性
你用Node的xslt3工具编译,但要注意SaxonJS和Saxon 9.8 EE的特性支持差异:
- Saxon 9.8 EE支持的部分扩展特性,SaxonJS可能不兼容;而且编译时必须明确指定目标为SaxonJS。
编译建议:
- 用
xslt3编译时加上-t:JS参数,生成SaxonJS专属的SEF文件:
xslt3 -xsl:your-transform.xsl -export:origScoring.sef.json -t:JS -s:your-test-source.xml
- 检查代码里有没有用Saxon EE特有的扩展(非标准XSLT 3.0或SaxonJS支持的扩展),如果有就替换成标准语法。
4. 验证xsl:include/xsl:import的路径
编译SEF时,如果xi:include、xsl:include的路径不正确,依赖的代码没被正确打包进SEF,运行时就会缺失逻辑导致空引用。
验证方法:
- 编译时确保所有依赖的XSLT文件路径正确(相对于编译时的工作目录);
- 临时把所有包含的XSLT内容合并到主文件里测试,如果错误消失,就是路径问题导致的。
5. 开启SaxonJS调试日志定位问题
在Chrome控制台开启SaxonJS的详细日志,能精准定位到哪个模板或变量触发的错误:
SaxonJS.setLogLevel(2); // 开启详细调试日志 var result = SaxonJS.transform(options);
根据日志里的调用栈,直接找到出错的代码位置,针对性修复。
总结
优先排查map变量的空值处理和**$global-context-item的有效性**,这两个是最可能的诱因;再确认SEF编译的兼容性和依赖路径问题,应该就能解决这个错误了。
内容的提问来源于stack exchange,提问作者oleksii.sapov-erlinger
相关产品推荐
相关产品推荐

