Saxonia s9api集成扩展函数节点元素访问越界问题求助
问题描述
我们尝试通过集成扩展函数提交一个Node,该Node本身显示正常,但无法访问其根元素下的单个元素,始终触发数组越界(OutOfBound)异常。请问应如何正确访问根元素下的单个元素?
现有代码示例
public ExtensionFunction updateTempNode = new ExtensionFunction() { public QName getName() { return new QName("de.dkl.dymoServer.util.ExternalFunctions", "updateTempNode"); } public SequenceType getResultType() { return SequenceType.makeSequenceType( ItemType.BOOLEAN, OccurrenceIndicator.ONE ); } public net.sf.saxon.s9api.SequenceType[] getArgumentTypes() { return new SequenceType[]{ SequenceType.makeSequenceType( ItemType.STRING, OccurrenceIndicator.ONE), SequenceType.makeSequenceType( ItemType.DOCUMENT_NODE, OccurrenceIndicator.ONE)}; } public XdmValue call(XdmValue[] arguments) { String sessionId = arguments[0].itemAt(0).getStringValue(); SaplingElement tempNode = TransformationService.tempNodes.get(sessionId); ItemTypeFactory itemTypeFactory = new ItemTypeFactory(((XdmNode) arguments[1]).getProcessor()); tempNode.withChild( arguments[1].stream().map(xdmValue -> Saplings.elem(xdmValue.getStringValue()).withText(xdmValue.itemAt(0).getStringValue())).toList() .toArray(SaplingElement[]::new) ); System.out.println(tempNode); return new XdmAtomicValue(true); } };
错误场景
迭代处理文档节点时触发数组越界异常,传入的document_node数据结构符合预期(包含根元素,根元素下存在子元素)。
解决方案
问题根源
现有代码错误地将**文档节点(Document Node)**直接当作元素节点处理:
arguments[1]是文档节点,它本身不是元素,直接调用xdmValue.getStringValue()得到的是文档所有文本内容的拼接,而非元素名称。- 文档节点作为序列中的单个项,调用
xdmValue.itemAt(0)会尝试访问它的子项,导致数组越界。
修正后的代码
public XdmValue call(XdmValue[] arguments) { String sessionId = arguments[0].itemAt(0).getStringValue(); SaplingElement tempNode = TransformationService.tempNodes.get(sessionId); // 获取文档节点(参数为单文档节点,itemAt(0)安全) XdmNode docNode = (XdmNode) arguments[1].itemAt(0); // 获取文档的根元素(文档节点的直接子节点就是根元素) XdmNode rootElement = docNode.children().findFirst().orElseThrow(() -> new IllegalArgumentException("文档无根元素")); // 遍历根元素的子元素,或直接访问单个子元素 List<SaplingElement> childElements = rootElement.children() .map(childNode -> Saplings.elem(childNode.getNodeName().getLocalName()) .withText(childNode.getStringValue())) .toList(); tempNode.withChild(childElements.toArray(SaplingElement[]::new)); System.out.println(tempNode); return new XdmAtomicValue(true); }
关键注意点
- 文档节点是容器节点,必须先获取其根元素,再处理根元素的子节点。
- 使用
XdmNode.children()方法获取子节点流,避免手动索引操作导致的越界问题。 - 如果确定根元素下只有单个子元素,可通过
rootElement.children().findFirst()直接获取,无需遍历。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

