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

如何使用Saxon S9API在org.w3c.dom.Document上执行XPath 2.0表达式?

解决Saxon XPathSelector在org.w3c.dom.Document上执行查询的问题

你遇到的核心问题是没有将原生的org.w3c.dom.Document转换为Saxon能识别的XdmNode对象,也没有为XPathSelector设置查询的上下文节点。Saxon的XPath API依赖自身的XDM(XPath Data Model)对象模型,直接调用evaluate()而不指定上下文文档自然会抛出异常。

下面是修正后的完整代码,我会标注关键修改点:

import net.sf.saxon.s9api.*;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import com.sun.org.apache.xerces.internal.parsers.DOMParser;
import javax.xml.transform.dom.DOMSource;
import java.io.FileInputStream;
import java.util.ArrayList;

public class XPath2Test {
    public static void main(String[] args) throws Exception{
        String assemblyXPathString="/child::AssemblyBase/child::Assembly[attribute::roles='ALL' or contains(attribute::roles,$role)]";
        
        // 原有的DOM解析部分
        DOMParser parser=new DOMParser();
        FileInputStream fis=new FileInputStream("E:\\workspaces\\dev_werewolf\\Platform_Manual\\manual\\UIFramework\\RoleBasedUIAssembly2.xml");
        InputSource inputSource=new InputSource(fis);
        parser.parse(inputSource);
        Document document=parser.getDocument();
        
        // Saxon初始化部分
        Processor processor=new Processor(false);
        XPathCompiler compiler=processor.newXPathCompiler();
        compiler.declareVariable(new QName("role"));
        XPathExecutable executable=compiler.compile(assemblyXPathString);
        XPathSelector selector=executable.load();
        
        // 设置变量
        ArrayList<String> values=new ArrayList<>();
        values.add("CIO");
        selector.setVariable(new QName("role"), XdmItem.makeSequence(values));
        
        // ------------------- 关键修改部分 -------------------
        // 1. 将org.w3c.dom.Document转换为Saxon的XdmNode
        DOMSource domSource = new DOMSource(document);
        XdmNode xdmNode = processor.newDocumentBuilder().build(domSource);
        
        // 2. 将XdmNode设置为XPathSelector的上下文节点
        selector.setContextItem(xdmNode);
        // ---------------------------------------------------
        
        // 执行查询并处理结果
        XdmValue result = selector.evaluate();
        // 遍历结果示例
        for (XdmItem item : result) {
            System.out.println(item.getStringValue());
        }
    }
}

关键知识点说明:

  • DOM到XDM的转换:Saxon提供了DocumentBuilder.build(DOMSource)方法,可以把原生DOM对象转换成Saxon的XdmNode,这是让Saxon能识别并处理你现有DOM文档的核心步骤。
  • 设置上下文节点:XPathSelector.setContextItem()方法指定了XPath查询的根节点(也就是你的整个文档),没有这个步骤,Selector不知道要在哪个文档上执行查询。
  • 结果处理:evaluate()方法返回XdmValue,你可以遍历这个对象来获取匹配到的所有节点或值。

另外,注意如果你的项目中使用的是较新版本的Saxon(比如10+),可能需要调整导入的包路径,但核心逻辑是一致的。

内容的提问来源于stack exchange,提问作者Ironluca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:42:03