Java怎么用XPathFactory和XPath来查询XML节点

Java中XPath查询XML的核心是通过XPathFactory创建XPath实例,解析XML为Document(需禁用DTD和外部实体),再调用evaluate方法执行查询;命名空间需显式注册,返回类型须按需指定。

Java 中用 XPathFactoryXPath 查询 XML 节点,核心是先构建 XPath 工厂和表达式处理器,再加载 XML 文档,最后执行查询。关键在于正确设置命名空间(如有)、选择合适的返回类型,以及处理可能的异常。

创建 XPath 实例

不能直接 new XPath,必须通过 XPathFactory 获取:

  • XPathFactory factory = XPathFactory.newInstance();
  • XPath xpath = factory.newXPath();
  • 默认使用 JAXP 内置实现(com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl),无需额外依赖

加载 XML 文档为 Document 对象

XPath 查询需要一个 DOM 树,所以得先把 XML 字符串或文件解析成 Document

  • DocumentBuilder 解析(推荐关闭 DTD 和外部实体以防安全风险)
  • 示例:
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(new InputSource(new StringReader(xmlString)));
    

执行 XPath 查询

调用 xpath.evaluate(),注意三个关键参数:表达式、上下文节点、返回类型:

  • 查单个字符串值:xpath.evaluate("//book/title", doc, XPathConstants.STRING)
  • 查单个节点:xpath.evaluate("//book[1]", doc, XPathConstants.NODE)
  • 查节点列表:xpath.evaluate("//author", doc, XPathConstants.NODESET) → 返回 NodeList
  • 查布尔值:xpath.evaluate("count(//book) > 0", doc, XPathConstants.BOOLEAN)

处理带命名空间的 XML

如果 XML 有 namespace(如 ),必须注册命名空间前缀,否则查询失败:

  • 自定义 NamespaceContext 实现,或用简单匿名类:
  • xpath.setNamespaceContext(new NamespaceContext() {
        public String getNamespaceURI(String prefix) {
            return "http://purl.org/rss/1.0/".equals(prefix) ? "http://purl.org/rss/1.0/" : null;
        }
        public String getPrefix(String uri) { return null; }
        public Iterator getPrefixes(String uri) { return Collections.emptyIterator(); }
    });
    
  • 然后在 XPath 表达式中使用前缀:xpath.evaluate("//rss:channel/rss:title", doc, XPathConstants.STRING)

基本上就这些。不复杂但容易忽略命名空间和 Document 安全配置,实际用时建议封装成工具方法复用。