user1461001 user1461001 - 1 year ago 39
Java Question

Replacing Elements in a XML document with String in Java

I am writing an HTTP server where i will receive an XPATH in an HTTP PUT and the data in the request body.

I will need to replace the result of the XPATH expression with the data in the HTTP request data in an XML document

For example

the XML document is

<tuple id="x8eg92n">
<note> i am reading email 3 times a day </note>

The HTTP request is for example something like

PUT /pidf-manipulation/users/
~~/presence/tuple%5b@id='x8eg92n'%5d/note HTTP/1.1
If-Match: "xyz"
Content-Type: application/xcap-el+xml

<note>I'm reading mails on Tuesdays and Fridays</note>

This above should replace the note element in the XML with the one the PUT request. Clients can this way send any XPATH and replace contents of the XML document.

Please help in how this can be done in Java Code.

Answer Source

Basically what you need to do is:

  1. Load the xml to be changed;
  2. Load the fragment you want to use in the replacement;
  3. Adopt node you loaded in [2] in the document you loaded on [1];
  4. Find the node to replace using XPath;
  5. Get the parent node from the one you found in [4], remove the node found in [4] from the parent, and add the node you adopt.

You could use something similar with:


import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

public class XmlXPathReplace {

    public static void main(final String[] args) throws SAXException, IOException, ParserConfigurationException,
            XPathExpressionException, TransformerException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true); // never forget this!
        DocumentBuilder builder = factory.newDocumentBuilder();

        // step 1.
        Document doc = builder.parse(new ByteArrayInputStream(( //
                "<?xml version=\"1.0\"?>" + //
                        "<people>" + //
                        "<person><name>First Person Name</name></person>" + //
                        "<person><name>Second Person Name</name></person>" + //
                        "</people>" //

        // step 2
        String fragment = "<name>Changed Name</name>";
        Document fragmentDoc = builder.parse(new ByteArrayInputStream(fragment.getBytes()));

        // step 3
        Node injectedNode = doc.adoptNode(fragmentDoc.getFirstChild());

        // step 4
        XPath xPath = XPathFactory.newInstance().newXPath();
        XPathExpression expr = xPath.compile("//people/person[2]/name");
        Element nodeFound = (Element) expr.evaluate(doc, XPathConstants.NODE);

        // step 5
        Node parentNode = nodeFound.getParentNode();

        DOMSource domSource = new DOMSource(doc);
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        StreamResult result = new StreamResult(new StringWriter());
        transformer.transform(domSource, result);