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

Java使用XPath修改XML节点值时出现NullPointerException问题求助

问题根因

空指针异常核心原因是Java XPath默认无法直接解析带自定义命名空间的XML,代码存在两处关键缺失:

  1. 没有开启DOM解析器的命名空间感知能力
  2. 没有给XPath实例注册命名空间前缀与对应URI的映射规则
    这就导致写好的XPath路径无法匹配到对应节点,evaluate方法返回null,后续调用SENummer.setTextContent(tests)时触发空指针。
修复步骤

1. 开启命名空间感知

创建DocumentBuilderFactory后立即开启命名空间支持:

DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
f.setNamespaceAware(true); // 新增这行,必须开启才能处理带命名空间的XML

2. 实现自定义命名空间上下文

自定义NamespaceContext实现类,绑定XML中用到的前缀和对应URI:

class CustomNamespaceContext implements NamespaceContext {
    @Override
    public String getNamespaceURI(String prefix) {
        switch (prefix) {
            case "urn": return "urn:xxx";
            case "ns1": return "xxx";
            case "urn1": return "urn:xxx";
            default: return XMLConstants.NULL_NS_URI;
        }
    }

    @Override
    public String getPrefix(String namespaceURI) {
        return null; // 不需要用到可以不实现
    }

    @Override
    public Iterator<String> getPrefixes(String namespaceURI) {
        return null; // 不需要用到可以不实现
    }
}

3. 给XPath设置命名空间上下文

创建XPath实例后绑定自定义上下文:

XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setNamespaceContext(new CustomNamespaceContext()); // 新增这行

4. 补充节点非空判断

拿到节点后先判断是否为null,避免异常:

Node SENummer = (Node) xPath.compile("/urn:receive/urn:give/urn:giveNumber/ns1:number").evaluate(doc, XPathConstants.NODE);
if (SENummer != null) {
    SENummer.setTextContent(tests);
}

dateFrom、dateTo的更新逻辑

两个字段的XPath路径分别为:

  • dateFrom: /urn:receive/urn:give/urn:giveDates/urn1:dateFrom
  • dateTo: /urn:receive/urn:give/urn:giveDates/urn1:dateTo
    和number字段的修改逻辑一致,直接复用上下文即可。
完整修复代码
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;

public class test {

    static class CustomNamespaceContext implements NamespaceContext {
        @Override
        public String getNamespaceURI(String prefix) {
            switch (prefix) {
                case "urn": return "urn:xxx";
                case "ns1": return "xxx";
                case "urn1": return "urn:xxx";
                default: return XMLConstants.NULL_NS_URI;
            }
        }
        @Override
        public String getPrefix(String namespaceURI) {return null;}
        @Override
        public Iterator<String> getPrefixes(String namespaceURI) {return null;}
    }

    public void receiveFunc() {
        String tests = "12344321";
        String newDateFrom = "2024-01-01";
        String newDateTo = "2024-03-31";
        try {
            File xmlFile = new File("{name}.xml");
            DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
            f.setNamespaceAware(true);
            DocumentBuilder b = f.newDocumentBuilder();
            Document doc = b.parse(xmlFile);
            doc.getDocumentElement().normalize();

            XPath xPath = XPathFactory.newInstance().newXPath();
            xPath.setNamespaceContext(new CustomNamespaceContext());

            // 更新number
            Node numberNode = (Node) xPath.compile("/urn:receive/urn:give/urn:giveNumber/ns1:number").evaluate(doc, XPathConstants.NODE);
            if (numberNode != null) {
                numberNode.setTextContent(tests);
            }
            // 更新dateFrom
            Node dateFromNode = (Node) xPath.compile("/urn:receive/urn:give/urn:giveDates/urn1:dateFrom").evaluate(doc, XPathConstants.NODE);
            if (dateFromNode != null) {
                dateFromNode.setTextContent(newDateFrom);
            }
            // 更新dateTo
            Node dateToNode = (Node) xPath.compile("/urn:receive/urn:give/urn:giveDates/urn1:dateTo").evaluate(doc, XPathConstants.NODE);
            if (dateToNode != null) {
                dateToNode.setTextContent(newDateTo);
            }

            Transformer tf = TransformerFactory.newInstance().newTransformer();
            tf.setOutputProperty(OutputKeys.INDENT, "yes");
            tf.setOutputProperty(OutputKeys.METHOD, "xml");
            tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

            DOMSource domSource = new DOMSource(doc);
            StreamResult sr = new StreamResult(new File("{name}.xml"));
            tf.transform(domSource, sr);

        } catch (ParserConfigurationException | IOException | SAXException | XPathExpressionException | TransformerException e) {
            e.printStackTrace();
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:24:04