Reputation: 703
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
<presence>
<tuple id="x8eg92n">
<note> i am reading email 3 times a day </note>
</tuple>
</presence>
The HTTP request is for example something like
PUT /pidf-manipulation/users/sip:[email protected]/index/
~~/presence/tuple%5b@id='x8eg92n'%5d/note HTTP/1.1
If-Match: "xyz"
Host: xcap.example.com
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.
Upvotes: 1
Views: 10114
Reputation: 21
Node importedTemplateChildNode = targetDoc.importNode(templateChildNode, true);
// Importing template node to the target document(this solves wrong_DOCUMENT_ERR:)
targetParentNode.replaceChild(importedTemplateChildNode, targetChildnode);
// Replace target child node with the template node
Transformer tranFac =TransformerFactory.newInstance().newTransformer();
tranFac.transform(new DOMSource(targetDoc), new StreamResult(new FileWriter(targetXmlFile)));
Upvotes: 1
Reputation: 919
Instead of removing old node and adding new node, you could also use :
parentNode.replaceChild(injectedNode, nodeFound)
.
With this function, you'll keep your nodes in a good order
Upvotes: 0
Reputation: 23903
Basically what you need to do is:
You could use something similar with:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
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.transform.stream.StreamResult;
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>" //
).getBytes()));
// 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");
System.out.println();
Element nodeFound = (Element) expr.evaluate(doc, XPathConstants.NODE);
// step 5
Node parentNode = nodeFound.getParentNode();
parentNode.removeChild(nodeFound);
parentNode.appendChild(injectedNode);
DOMSource domSource = new DOMSource(doc);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(domSource, result);
System.out.println(result.getWriter().toString());
}
}
Upvotes: 2