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

已添加MAVEN依赖时如何解决XPATH相关java.lang.RuntimeException报错

问题根本原因

该XPath执行失败的核心原因有两点:

  • XPath中用到的v:命名空间未提前注册,xmlbeans无法识别对应的前缀,导致路径解析失败
  • 你引入的xmlbeans-xpath 2.6.0版本和主流POI版本依赖的xmlbeans版本不兼容,额外引入的Saxon-HE也不是该场景的必要依赖

可行解决方案

第一步:调整POM依赖

首先删除你之前手动引入的xmlbeans-xpath和Saxon-HE依赖,POI 4.x及以上版本自带的xmlbeans依赖已经内置XPath支持,不需要额外引入扩展包,确保核心POI依赖版本稳定即可,示例如下:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.5</version>
</dependency>

第二步:修改水印读取代码

在XPath中补充命名空间声明后再执行查询,修改后的代码如下:

private String getWaterMark(XWPFDocument document) {
    try {
        XWPFHeader defaultHeader = document.getHeaderFooterPolicy().getDefaultHeader();
        if(defaultHeader == null) {
            return "";
        }
        // 提前声明v命名空间
        final String xpathFilter = "declare namespace v='urn:schemas-microsoft-com:vml'; data(//v:shape[contains(@id,'PowerPlusWaterMarkObject')]/v:textpath/@string)";
        XmlObject[] xmlobjects = defaultHeader._getHdrFtr().selectPath(xpathFilter);
        if(xmlobjects != null && xmlobjects.length > 0) {
            return xmlobjects[0].toString();
        }
        return "";
    } catch (Exception ex) {
        logger.error("Error while getting Watermark content from document: ", ex);
        return "";
    }
}

高兼容备选方案

如果上述方案依然不生效,可以不用XPath,直接遍历节点获取水印内容,适配性更强:

private String getWaterMark(XWPFDocument document) {
    try {
        XWPFHeader defaultHeader = document.getHeaderFooterPolicy().getDefaultHeader();
        if(defaultHeader == null) {
            return "";
        }
        QName shapeQName = QName.valueOf("urn:schemas-microsoft-com:vml", "shape");
        QName idQName = QName.valueOf("", "id");
        QName textpathQName = QName.valueOf("urn:schemas-microsoft-com:vml", "textpath");
        QName stringQName = QName.valueOf("", "string");

        XmlObject[] shapes = defaultHeader._getHdrFtr().selectChildren(shapeQName);
        for (XmlObject shape : shapes) {
            XmlObject idAttr = shape.selectAttribute(idQName);
            if (idAttr != null && idAttr.getStringValue().contains("PowerPlusWaterMarkObject")) {
                XmlObject[] textPaths = shape.selectChildren(textpathQName);
                if (textPaths.length > 0) {
                    XmlObject stringAttr = textPaths[0].selectAttribute(stringQName);
                    if (stringAttr != null) {
                        return stringAttr.getStringValue();
                    }
                }
            }
        }
        return "";
    } catch (Exception ex) {
        logger.error("Error while getting Watermark content from document: ", ex);
        return "";
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:15:04