Saxon 9.7版本XSLT调用Java方法报错问题求助
解决Saxon 9.7升级后XSLT调用Java方法的节点类型转换错误
错误原因
Saxon 9.7及后续版本默认采用XDM(XPath Data Model)节点模型,不再自动将XPath表达式返回的节点转换为W3C标准的org.w3c.dom.Node类型。而你的Java方法myMethod参数要求的是W3C DOM节点,因此出现类型不匹配的报错。
解决思路与实现
1. 显式转换XDM节点为W3C DOM Node
通过Saxon提供的工具类手动转换节点类型,无需修改Java方法:
- 首先在XSLT中声明Saxon DOM工具类的命名空间:
xmlns:dom="java:net.sf.saxon.dom.NodeOverNodeInfo" - 修改Java方法调用,添加转换逻辑:
注意:<xsl:when test="boolean($callFunction)"> <xsl:value-of select="jfunc:myMethod(dom:wrap(n1:ParentNode/node()[1]))"/> </xsl:when>node()可能返回多个节点,需用[1]确保传递单个节点(如果myMethod仅支持单个参数)。
2. 修改Java方法适配XDM节点模型
直接将myMethod的参数类型改为Saxon的XDM节点类型net.sf.saxon.om.NodeInfo,避免模型转换开销:
public class MyFunction { public static String myMethod(net.sf.saxon.om.NodeInfo node) { // 原逻辑适配NodeInfo类型,如需W3C DOM可在方法内转换 // 示例:org.w3c.dom.Node domNode = net.sf.saxon.dom.NodeOverNodeInfo.wrap(node); // ... 业务逻辑 } }
这种方式性能最优,是Saxon推荐的做法。
3. 配置Saxon默认使用W3C DOM模型
如果要完全保留原有代码,可在初始化Saxon时强制使用W3C DOM作为节点模型:
net.sf.saxon.Configuration config = new net.sf.saxon.Configuration(); // 设置DOM为默认树模型 config.setTreeModel(net.sf.saxon.Configuration.TREE_MODEL_DOM); TransformerFactory factory = new net.sf.saxon.TransformerFactoryImpl(config);
但此方法会降低处理性能,仅建议在无法修改XSLT或Java代码的场景下使用。
内容的提问来源于stack exchange,提问作者TheUltimateHack
相关产品推荐
相关产品推荐

