2012-06-16 138 views
0

我正在写一个HTTP服务器,我将在HTTP PUT中接收XPATH并在请求正文中接收数据。用Java中的字符串替换XML文档中的元素

我将需要更换与在HTTP请求的数据的数据XPATH表达式的结果的XML文档

例如在

XML文档是

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

的HTTP请求是例如类似的东西

PUT /pidf-manipulation/users/sip:[email protected]/index/ 
    ~~/presence/tuple%[email protected]='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> 

这上面应该用一个PUT请求替换XML中的note元素。客户可以通过这种方式发送任何XPATH并替换XML文档的内容。

请帮助我们如何在Java代码中完成此操作。

+0

我只是在寻找应用的XPath,得到的结果,然后替换它明确的部分,一切只是细节 – user1461001

回答

1

基本上你需要做的是:

  1. 加载XML改变;
  2. 加载要在替换中使用的片段;
  3. 采用您在[1]中加载的文档[2]中加载的节点;
  4. 使用XPath查找要替换的节点;
  5. 从您在[4]中找到的父节点获取父节点,从父节点中删除在[4]中找到的节点,然后添加您采用的节点。

你可以使用类似的东西:

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

} 
+0

谢谢,这个工作非常好。 – user1461001

0

而不是删除旧节点和增加新的节点,你也可以使用: parentNode.replaceChild(injectedNode, nodeFound)。 有了这个功能,你会保持你的节点在一个良好的秩序

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

你能更好的格式化吗? – adao7000