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

Java如何通用实现按指定XPath将XML字符串转为List<String>

通用实现方案

直接用JDK内置的XML解析API实现即可,不需要引入任何第三方依赖,只要传入XML字符串和目标XPath,就能返回匹配节点对应的XML字符串列表,适配任意结构的无命名空间XML(如果要支持带命名空间的XML,只需额外补充命名空间上下文配置即可)。

核心实现代码

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

public class XmlNodeExtractor {
    /**
     * 按XPath提取XML中匹配的节点,返回每个节点对应的完整XML字符串列表
     * @param xmlStr 原始XML字符串
     * @param xpathExpr 目标节点的XPath表达式
     * @return 匹配节点的XML字符串列表
     */
    public static List<String> extractNodesByXpath(String xmlStr, String xpathExpr) throws Exception {
        List<String> result = new ArrayList<>();
        // 1. 将XML字符串解析为Document对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        // 关闭DTD校验,提升解析速度,避免外部实体访问问题
        dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        Document doc = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(xmlStr)));

        // 2. 执行XPath匹配,拿到所有符合条件的节点
        NodeList nodeList = (NodeList) XPathFactory.newInstance().newXPath()
                .evaluate(xpathExpr, doc, XPathConstants.NODESET);

        // 3. 初始化序列化工具,把Node转成XML字符串
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        // 省略XML声明头,只输出节点本身内容
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        // 保留缩进格式,和原始XML排版一致
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");

        // 4. 遍历所有匹配节点,序列化后加入结果集
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            StringWriter writer = new StringWriter();
            transformer.transform(new DOMSource(node), new StreamResult(writer));
            result.add(writer.toString().trim());
        }
        return result;
    }
}

使用示例

针对你给出的图书目录XML,直接传入XPath /catalog/book 即可拿到所有book节点的字符串列表:

public class Test {
    public static void main(String[] args) throws Exception {
        // 示例XML字符串
        String xml = """
                <catalog>
                <book id="bk101">
                <author>Gambardella, Matthew</author>
                <publish_date>2000-10-01</publish_date>
                <description>An in-depth look at creating applications with XML.</description>
                </book>

                <book id="bk102">
                <author>Ralls, Kim</author>
                <publish_date>2000-12-16</publish_date>
                <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description>
                </book>

                <book id="bk103">
                <author>Corets, Eva</author>
                <publish_date>2000-11-17</publish_date>
                <description>After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society.</description>
                </book>

                </catalog>
                """;
        // 传入XPath获取结果
        List<String> bookList = XmlNodeExtractor.extractNodesByXpath(xml, "/catalog/book");
        // 遍历打印,和预期输出效果完全一致
        for (int i = 0; i < bookList.size(); i++) {
            System.out.println("element number " + i);
            System.out.println(bookList.get(i));
            System.out.println();
        }
    }
}

注意事项

  • 这个实现逻辑完全通用,不管XML是什么结构,只要传入对应节点的合法XPath表达式,就能正确提取对应节点的完整XML内容
  • 如果需要处理带命名空间的XML,只需要给XPath实例设置对应NamespaceContext即可,核心逻辑不需要改动
  • 代码里已经做了格式保留,输出的节点字符串会保留缩进排版,和预期展示效果一致
  • 示例代码里的文本块(三个双引号包裹的字符串)是Java 15+的语法,如果使用低版本JDK,把XML字符串换成普通转义的字符串即可,核心提取逻辑在Java 8及以上版本都能正常运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:27:22