简体   繁体   English

用Java中的String替换XML文档中的元素

[英]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. 我正在编写一个HTTP服务器,在该服务器中我将在HTTP PUT中接收XPATH,并在请求正文中接收数据。

I will need to replace the result of the XPATH expression with the data in the HTTP request data in an XML document 我将需要用XML文档中HTTP请求数据中的数据替换XPATH表达式的结果

For example 例如

the XML document is XML文档是

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

The HTTP request is for example something like HTTP请求例如

  PUT /pidf-manipulation/users/sip:someone@example.com/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. 以上内容应将XML中的note元素替换为PUT请求。 Clients can this way send any XPATH and replace contents of the XML document. 客户端可以通过这种方式发送任何XPATH并替换XML文档的内容。

Please help in how this can be done in Java Code. 请帮助如何使用Java代码完成此操作。

Basically what you need to do is: 基本上,您需要做的是:

  1. Load the xml to be changed; 加载要更改的xml;
  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]; 在[1]中加载的文档中采用[2]中加载的节点;
  4. Find the node to replace using XPath; 使用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. 从您在[4]中找到的节点获取父节点,从父节点中移除[4]中的节点,然后添加您采用的节点。

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());
    }

}

Instead of removing old node and adding new node, you could also use : parentNode.replaceChild(injectedNode, nodeFound) . 除了删除旧节点并添加新节点,您还可以使用: parentNode.replaceChild(injectedNode, nodeFound) With this function, you'll keep your nodes in a good order 使用此功能,您可以使节点保持良好状态

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)));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM