You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 16:46:08