使用 XPath 更改文本内容

Posted

技术标签:

【中文标题】使用 XPath 更改文本内容【英文标题】:Change text content with XPath 【发布时间】:2015-02-17 18:52:46 【问题描述】:

虽然我可以使用下面的代码在节点内设置文本值

private static void setPhoneNumber(Document xmlDoc, String phoneNumber) 
    Element root = xmlDoc.getDocumentElement();     
    Element phoneParent = (Element) root.getElementsByTagName("gl-bus:entityPhoneNumber").item(0);      
    Element phoneElement = (Element) phoneParent.getElementsByTagName("gl-bus:phoneNumber").item(0);    
    phoneElement.setTextContent(phoneNumber);       

我不能对 XPath 做同样的事情,因为我得到了节点对象的 null

private static void setPhoneNumber(Document xmlDoc, String phoneNumber) 
    try 
        NodeList nodes = (NodeList) xPath.evaluate("/gl-cor:entityInformation/gl-bus:entityPhoneNumber/gl-bus:phoneNumber", xmlDoc, XPathConstants.NODESET);
        Node node = nodes.item(0);
        node.setTextContent(phoneNumber);
     catch (XPathExpressionException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    
 

【问题讨论】:

【参考方案1】:

您使用的是非命名空间感知方法getElementsByTagName(),并传递了一个包含冒号的元素名称,这表明您在解析 XML 时没有正确处理命名空间。如果您的 XML 是以命名空间感知的方式解析的,那么这应该不起作用,但是类似于

String namespace = // the namespace URI bound to the gl-bus prefix in your doc
Element phoneParent = (Element) root.getElementsByTagNameNS(namespace, "entityPhoneNumber").item(0);

可以正常工作。请注意,标准 Java DocumentBuilderFactory 默认情况下是 命名空间感知的,您必须先调用工厂的 setNamespaceAware(true),然后再向其请求 newDocumentBuilder

XPath 需要命名空间感知解析,如果你想通过 XPath 访问命名空间中的元素,那么你必须向 XPath 对象提供一个 NamespaceContext 来告诉它使用什么前缀绑定 - 它没有从原始 XML 继承前缀绑定。令人烦恼的是,核心 Java 库中没有提供 NamespaceContext 的默认实现,因此您必须自己编写或使用第三方实现,例如 Spring's SimpleNamespaceContext。有了这个:

SimpleNamespaceContext ctx = new SimpleNamespaceContext();
ctx.bindNamespaceUri("g", namespace); // the same URI as before
ctx.bindNamespaceUri("c", ...); // the namespace bound to gl-cor:
xPath.setNamespaceContext(ctx);

NodeList nodes = (NodeList) xPath.evaluate("/c:entityInformation/g:entityPhoneNumber/g:phoneNumber", xmlDoc, XPathConstants.NODESET);

【讨论】:

以上是关于使用 XPath 更改文本内容的主要内容,如果未能解决你的问题,请参考以下文章

使用 XPath,如何根据节点的文本内容和属性值来选择节点?

XPath匹配时如何去掉空格换行只保留文本内容

XPath匹配时如何去掉空格换行只保留文本内容

Xpath轴与步长应用:取某节点下所有子孙节点里的文本内容

Python怎样获取XPath下的A标签的内容

XPath / XQuery:在节点中查找文本,但忽略特定后代元素的内容