Saxon HE 12实现返回Node的ExtensionFunctionDefinition遇配置兼容问题
Saxon HE 12扩展函数返回Node的兼容问题解决
问题根源
你遇到的SXXP0004错误,是因为扩展函数中创建的节点使用了独立的Configuration实例,和XSLT转换进程的Configuration不兼容。无论是最初手动new Processor(),还是后来用s9api的DocumentBuilder包装DOM,都没有正确复用当前转换的上下文配置。
解决方案
方案一:直接生成Saxon原生节点(推荐,无DOM依赖)
跳过W3C DOM的创建步骤,直接用当前转换上下文的Configuration生成Saxon原生NodeInfo节点,从根源避免配置不兼容问题。
修改ExtensionFunctionCall的call方法:
@Override public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException { // 获取当前转换使用的核心配置 Configuration config = context.getConfiguration(); // 初始化Saxon节点构建器 Builder nodeBuilder = config.newBuilder(); nodeBuilder.open(); // 创建<h1>元素节点并添加文本内容 NodeInfo h1Node = nodeBuilder.startElement(new StructuredQName("", "", "h1"), null); nodeBuilder.characters("my-content"); nodeBuilder.endElement(); nodeBuilder.close(); return h1Node; }
同时确保你的ExtensionFunctionDefinition子类正确声明返回类型:
@Override public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) { return SequenceType.SINGLE_NODE; }
方案二:适配已有W3C DOM节点到当前配置
如果必须保留W3C DOM的创建逻辑,使用Saxon底层的DOMAdapter将DOM节点适配到当前转换的Configuration:
修改call方法:
@Override public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException { Configuration config = context.getConfiguration(); Document domDoc = makeSomeDOM(); Element targetElement = (Element) domDoc.getFirstChild(); // 用当前配置包装DOM节点 DOMAdapter domAdapter = new DOMAdapter(targetElement, config); NodeInfo saxonCompatibleNode = domAdapter.getNodeInfo(); return saxonCompatibleNode; }
你的makeSomeDOM方法可以保持不变。
为什么之前的代码无效?
- 最初的
new Processor()创建了全新的配置实例,和XSLT转换的配置完全独立,导致节点无法跨配置使用。 - 后来尝试用s9api的DocumentBuilder包装DOM,属于混用了s9api高层API和底层XPathContext API,反而增加了复杂度,不如直接用底层的
DOMAdapter适配更直接。
内容的提问来源于stack exchange,提问作者Alice Oualouest
相关产品推荐
相关产品推荐

