Java HTML / XML How to - Use xpath to find a node value or attribute in an xml and replace it with another value








Question

We would like to know how to use xpath to find a node value or attribute in an xml and replace it with another value.

Answer

To find text

//*[text()='TEXT-TO-BE-FOUND']

To find all attributes with the same value, you must use the following XPath expression:

//*/@*[.='TEXT-TO-BE-FOUND']

TEXT-TO-BE-FOUND must be escaped, it may not contain ' as it will affect the XPath expression.

import java.io.File;
//from w ww  .  j  a  va  2 s. c  o m
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class Main {

  public static void main(String argv[]) throws Exception {
    String next = "keyword,123";
    String[] input = next.split(",");

    String textToFind = input[0].replace("'", "\\'"); // "CEO";
    String textToReplace = input[1].replace("'", "\\'"); // "Chief Executive Officer";
    String filepath = "root.xml";
    String fileToBeSaved = "root2.xml";

    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
    Document doc = docBuilder.parse(filepath);

    XPath xpath = XPathFactory.newInstance().newXPath();
    // change ELEMENTS

    String xPathExpression = "//*[text()='" + textToFind + "']";
    NodeList nodes = (NodeList) xpath.evaluate(xPathExpression, doc,
        XPathConstants.NODESET);

    for (int idx = 0; idx < nodes.getLength(); idx++) {
      nodes.item(idx).setTextContent(textToReplace);
    }

    // change ATTRIBUTES
    String xPathExpressionAttr = "//*/@*[.='" + textToFind + "']";
    NodeList nodesAttr = (NodeList) xpath.evaluate(xPathExpressionAttr, doc,
        XPathConstants.NODESET);

    for (int i = 0; i < nodesAttr.getLength(); i++) {
      nodesAttr.item(i).setTextContent(textToReplace);
    }
    System.out.println("Everything replaced.");

    // save xml file back
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    DOMSource source = new DOMSource(doc);
    StreamResult result = new StreamResult(new File(fileToBeSaved));
    transformer.transform(source, result);
  }
}