How to update XML using XPath and Java

71,329

Solution 1

Use setNodeValue. First, get a NodeList, for example:

myNodeList = (NodeList) xpath.compile("//MyXPath/text()")
           .evaluate(myXmlDoc, XPathConstants.NODESET);

Then set the value of e.g. the first node:

myNodeList.item(0).setNodeValue("Hi mom!");

More examples e.g. here.

As mentioned in two other answers here, as well as in your previous question: technically, XPath is not a way to "update" an XML document, but only to locate nodes within an XML document. But I presume the above is what you want.

EDIT: Responding to your comment... Are you asking how to write your DOM to an XML file after you've finished editing the DOM? If so, here are two examples of how to do it:

http://www.java2s.com/Code/Java/XML/WriteDOMout.htm

http://download.oracle.com/javaee/1.4/tutorial/doc/JAXPXSLT4.html

Solution 2

You can delete the file and create a new one.

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
    new InputSource("data.xml"));

XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("//employee/name[text()='old']", doc,
    XPathConstants.NODESET);

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

Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(new DOMSource(doc), new StreamResult(new File("data_new.xml")));

Solution 3

XPath is used to select parts of an XML document.It has no provision for updating. But since it returns DOM objects (Elements, if memory serves, or maybe Nodes) you can then use DOM methods for altering the document.

Solution 4

XPath can be used to select nodes in a document, not for modification

You apply the xpath expression to your document and get an element (in your case). Once you have this Element, you can use the Element methods to change values (name and age in your case)


Starting from a NodeList it should work like that:

NodeList nodes = getNodeListFromXPathExpression();  // you know how
if (nodes.length == 0)
   return;  // empty nodelist, xpath didn't select anything

Node first = node.getItem(0);    // take the first from the list, your element

// this is a shortcut for your example:
//  first is the actual selected element (a node)
//  .getFirst() returns the first child node, the "text node" (="Jasmine", ="28")
//  .setNodeValue() replace the actual value of that text node with a new string
first.getFirstChild().setNodeValue("New Name or new age");

Solution 5

Consider using XQuery Update instead of XPath. This allows you to write

replace value of node //PersonList/Person[2]/Name with "Anonymous"

This is much easier than using the Java DOM API.

Share:
71,329
samash
Author by

samash

Updated on February 05, 2021

Comments

  • samash
    samash over 3 years

    I have an XML document, and an XPath expression for that doc. I have to update the doc by using XPath at runtime.

    How can I do this using Java?

    The below is my xml:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <PersonList>
        <Person>
            <Name>Sonu Kapoor</Name>
            <Age>24</Age>
            <Gender>M</Gender>
            <PostalCode>54879</PostalCode>
        </Person>
        <Person>
            <Name>Jasmin</Name>
            <Age>28</Age>
            <Gender>F</Gender>
            <PostalCode>78745</PostalCode>
        </Person>
        <Person>
            <Name>Josef</Name>
            <Age>232</Age>
            <Gender>F</Gender>
            <PostalCode>53454</PostalCode>
        </Person>
    </PersonList>
    

    I have to change the values of name and age under //PersonList/Person[2]/Name.