2012-06-16 67 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