2009-10-30 126 views
1

在「讀取」文件的互聯網上有很多示例,但我無法找到關於「編輯」節點值並將其寫回的任何內容到原始文件。如何編輯文件對象中的XML節點,使用Java

我有一個非工作 XML作家類,看起來像這樣:

import org.w3c.dom.Document; 
public class RunIt { 

    public static Document xmlDocument; 

    public static void main(String[] args) 
      throws TransformerException, IOException { 
     try { 
      xmlDocument = DocumentBuilderFactory.newInstance() 
        .newDocumentBuilder().parse("thor.xml");    
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } catch (SAXException ex) { 
      ex.printStackTrace(); 
     } catch (ParserConfigurationException ex) { 
      ex.printStackTrace(); 
     } 
     addElement("A", "New"); 
     writeDoc(); 
    } 

    public static void addElement(String path, String val){ 
     Element e = xmlDocument.createElement(path); 
     e.appendChild(xmlDocument.createTextNode(val)); 
     xmlDocument.getDocumentElement().appendChild(e); 
    } 

    public static void writeDoc() throws TransformerException, IOException { 
     StringWriter writer = new StringWriter(); 
     Transformer tf; 
     try { 
      tf = TransformerFactory.newInstance().newTransformer(); 
      tf.transform(new DOMSource(xmlDocument), new StreamResult(writer)); 
      writer.close(); 
     } catch (TransformerConfigurationException e) { 
      e.printStackTrace(); 
     } catch (TransformerFactoryConfigurationError e) { 
      e.printStackTrace(); 
     } 
    } 
} 

在這個例子中,可以說這是XML,我想添加一個「C」節點(內在包含值「新」一個節點):

<A> 
    <B>Original</B> 
</A> 
+0

歸根結底,這是我想出了答案:http://thegreenoak.blogspot.com/2012/07/writing-string-value-to-xml-file -using.html – djangofan 2012-07-27 05:27:30

回答

6

您可以使用文檔對象來創建新的節點。您建議的添加節點涉及創建節點,設置其內容並將其附加到根元素。在這種情況下,你的代碼看起來服用點是這樣的:

Element e = xmlDocument.createElement("C"); 
e.appendChild(xmlDocument.createTextNode("new")); 
xmlDocument.getDocumentElement().appendChild(e); 

這將增加的C節點中的B點後右一新的孩子。

此外,元素有一些便利功能,可以減少所需的代碼量。第二條線上面的程序可以被替換

e.setTextContent("new"); 

涉及非根元素更復雜的工作將涉及您使用XPath來獲取目標節點進行編輯。如果您確實開始使用XPath來定位節點,請記住JDK XPath的性能很糟糕。只要有可能,就避免使用"@foo"的XPath來支持像e.getAttribute("foo")這樣的構造。

編輯:將文檔格式化回可以寫入文件的字符串可以用下面的代碼完成。

Document xmlDocument; 
StringWriter writer = new StringWriter(); 
TransformerFactory.newInstance().transform(new DOMSource(xmlDocument), new StreamResult(writer)); 
writer.close(); 
String xmlString = writer.toString(); 

編輯:回覆:用代碼更新問題。

您的代碼不起作用,因爲您正在混淆'路徑'和'元素名稱'。 Document.createElement()的參數是新節點的名稱,而不是放置它的位置。在我寫的示例代碼中,我沒有找到合適的節點,因爲您特意詢問是否將節點添加到文檔父元素。如果您希望addElement()按照我認爲您期望的方式行事,您必須爲目標父節點的xpath添加另一個參數。

你的代碼的另一個問題是你的writeDoc()函數沒有任何輸出。我的例子顯示了將XML寫入字符串值。您可以通過修改代碼將其寫入任何需要的編寫器,但是在您的示例代碼中,您使用了StringWriter,但從不提取寫入的字符串。

我建議重寫你的代碼是這樣的

public static void main(String[] args) { 
    File xmlFile = new File("thor.xml"); 
    Document xmlDocument = DocumentBuilderFactory.newInstance() 
      .newDocumentBuilder().parse(xmlFile); 
    // this is effective because we know we're adding to the 
    // document root element 
    // if you want to write to an arbitrary node, you must 
    // include code to find that node 
    addTextElement(xmlDocument.getDocumentElement(), "C", "New"); 
    writeDoc(new FileWriter(xmlFile); 
} 

public static Element addTextElement(Node parent, String element, String val){ 
    Element e = addElement(parent, element) 
    e.appendChild(xmlDocument.createTextNode(val)); 
    return e; 
} 

public static Element addElement(Node parent, String element){ 
    Element e = xmlDocument.createElement(path); 
    parent.appendChild(e); 
    return e; 
} 

public static void writeDoc(Writer writer) { 
    try { 
     Transformer tf = TransformerFactory.newInstance().newTransformer(); 
     tf.transform(new DOMSource(xmlDocument), new StreamResult(writer)); 
    } finally { 
     writer.close(); 
    } 
} 
+0

我第二次遇到XPath性能問題:我在一個應用程序中使用了少數幾個應用程序,並將運行時間從幾秒到四分鐘。驚人。 – 2009-10-30 01:48:52

+0

這幾乎是我正在尋找的答案。如何將更改提交給文件系統對象? – djangofan 2009-10-30 02:31:14

+0

@djangofan - 看到這個答案寫出XML數據:http://stackoverflow.com/questions/1137488/ways-of-producing-xml-in-java/1137922#1137922 _(替代'System.out' 'FileOutputStream')_ – McDowell 2009-10-30 10:36:35

1

爲了您的文檔寫回文件中,你需要一個XML序列化或自己編寫。如果您使用的是Xerces庫,請查看XMLSerializer。有關示例使用情況,還可以查看DOMWriter示例頁面。

有關Xerces的更多信息,read this