java - 如何通过 XPATH 更新 Java 中需要不同值的多个节点?

标签 java xml xpath

当需要处理不同名称的字段时,如何通过一个 XPATH 语句更新多个节点?

最佳答案

我不确定您发布此问题的目的是什么,但我发现您自己的答案存在几个问题。

  • XPath 是一个将谓词应用于 DOM 树的工具。使用 XPath 选择比您需要的更大的节点集,然后将您自己的谓词应用于它返回的节点列表是没有意义的。
  • 您的 XPath 表达式包含多个正交项。这评估效率较低,并且当您添加其他术语时很快就会变得难以管理。
  • 您使用的表达式(检索文本节点然后导航到父元素)没有多大意义。我想您只想选择已经有文本的节点,但如果您正在进行全局搜索并替换,我不确定这是一个合理的假设。如果我要继承您的代码,我当然希望看到演示这两种行为的测试,以表明您想要该行为。
  • 长长的 if/else 语句链非常难以理解。它们也很难测试,因为您必须制作一个测试套件来执行代码中所有可能的路径。
  • if 语句的正文是重复代码,违反了 DRY 原则。鉴于您需要从选定的节点向上导航,这可能会导致错误,或者如果您更改指定表达式的方式,则必须在多个位置更改复制粘贴代码。

在我看来,最好提取一个选择节点并一次对单个表达式执行更改的方法。从你的代码开始,让我的 IDE 修复一些语法错误,我最终得到了这个(但是,我还没有编写测试用例):

public static void main(String[] args) throws Exception  
{  
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
     DocumentBuilder builder = factory.newDocumentBuilder();  
     Document doc = builder.parse(new File("path/to/file.xml"));  

     changeNodeText(doc, "/PersonList/Person/Age", "42");
     changeNodeText(doc, "/PersonList/Person/Name", "Batman");
}  


public static void changeNodeText(Node context, String xpath, String value)
throws XPathExpressionException
{
    XPathFactory xFactory = XPathFactory.newInstance();
    XPath xPath = xFactory.newXPath();
    XPathExpression expression = xPath.compile(xpath);
    NodeList nodes = (NodeList)expression.evaluate(context, XPathConstants.NODESET);
    for (int i = 0; i < nodes.getLength(); i++)
    {
        Node node = nodes.item(i);
        node.setTextContent(value);
    }
}

一些关键功能(除了我上面所做的 XPath 特定评论之外):

  • 函数名称清楚地表明您正在更改节点的文本。
  • 您可以轻松查看正在更新的路径;您不必浏览代码即可弄清楚它在做什么。
  • 您可以使用两个测试用例(正面和负面)对此进行测试,并推断它在任何地方都适用。
  • 它使用 setTextContent() 方法,IMO 比 setNodeValue() 有更好的规范(除非您传递文本节点,否则它将失败)。
  • 如果您必须添加命名空间映射,您可以在一个地方完成。如果您决定只想更改已经具有文本节点的元素,则同上。

关于java - 如何通过 XPATH 更新 Java 中需要不同值的多个节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17282954/

相关文章:

xml - 如何从XPath包含变量的Powershell中的Xml文档中选择单个节点?

java - 如何将这个 JSON 响应转换为 POJO?

java - JSON NO_REFERENCES

java - Spring转换器、 validator 和DataBinder : how to handle multivalued bean fields individually?

excel - 运行 powershell 命令时出错

java - 元素 "xsd"的前缀 "xsd:element"未绑定(bind)。 [11]

java - 通用 XML 解析器设计分析

java - 在 java 中进行 URLEncode,在 ruby​​ 中进行解码

java - 从 xml 文件检索值的 JAXB 程序

xslt - 查找具有特定名称且不具有特定属性的在前同级