[java] How do I append a node to an existing XML file in java

public static void addALLToXML(Collection<Server> svr) throws IOException,
      ParserConfigurationException, TransformerException
{
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
        .newInstance();
    DocumentBuilder documentBuilder = documentBuilderFactory
        .newDocumentBuilder();
    Document document = documentBuilder.newDocument();

    // Root Element
    Element rootElement = document.createElement("Servers");
    document.appendChild(rootElement);

    for (Server i : svr)
    {
        // server elements
        Element server = document.createElement("server");
        rootElement.appendChild(server);

        Element name = document.createElement("name");
        name.appendChild(document.createTextNode(i.getName()));
        server.appendChild(name);

        Element port = document.createElement("port");
        port.appendChild(document.createTextNode(Integer.toString(i.getPort())));
        server.appendChild(port);
    }

    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    DOMSource source = new DOMSource(document);

    StreamResult result = new StreamResult("/home/user/server.xml");
    transformer.transform(source, result);
}

This is the function I need help with:

public static void addNodeToXML(String nameIn, String portIn)
      throws ParserConfigurationException, SAXException, IOException
{
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
            .newInstance();
    DocumentBuilder documentBuilder = documentBuilderFactory
            .newDocumentBuilder();

    /* parse existing file to DOM */
    Document document = documentBuilder
            .parse(new File("/home/user/server.xml"));

    // Root Element
    Element rootElement = document.createElement("Servers");
    document.appendChild(rootElement);

    // server elements
    Element server = document.createElement("server");
    rootElement.appendChild(server);

    Element name = document.createElement("name");
    name.appendChild(document.createTextNode(nameIn));
    server.appendChild(name);

    Element port = document.createElement("port");
    port.appendChild(document.createTextNode(portIn));
    server.appendChild(port);
}

Original:

<Servers>
 <server>
  <name>something</name>
  <port>port</port>
 </server>
 </Servers>

Wanted:

<Servers> 
  <server>
   <name>something</name>
   <port>port</port>
  </server>
  <server>
   <name>something</name>
   <port>port</port>
  </server>
<Servers>

This question is related to java xml

The answer is


The following complete example will read an existing server.xml file from the current directory, append a new Server and re-write the file to server.xml. It does not work without an existing .xml file, so you will need to modify the code to handle that case.

import java.util.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;

public class AddXmlNode {
    public static void main(String[] args) throws Exception {

        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse("server.xml");
        Element root = document.getDocumentElement();

        Collection<Server> servers = new ArrayList<Server>();
        servers.add(new Server());

        for (Server server : servers) {
            // server elements
            Element newServer = document.createElement("server");

            Element name = document.createElement("name");
            name.appendChild(document.createTextNode(server.getName()));
            newServer.appendChild(name);

            Element port = document.createElement("port");
            port.appendChild(document.createTextNode(Integer.toString(server.getPort())));
            newServer.appendChild(port);

            root.appendChild(newServer);
        }

        DOMSource source = new DOMSource(document);

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        StreamResult result = new StreamResult("server.xml");
        transformer.transform(source, result);
    }

    public static class Server {
        public String getName() { return "foo"; }
        public Integer getPort() { return 12345; }
    }
}

Example server.xml file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Servers>
  <server>
    <name>something</name>
    <port>port</port>
  </server>
</Servers>

The main change to your code is not creating a new "root" element. The above example just uses the current root node from the existing server.xml and then just appends a new Server element and re-writes the file.


You could use DOM4j doing that.


If you need to insert node/element in some specific place , you can to do next steps

  1. Divide original xml into two parts
  2. Append your new node/element as child to first first(the first part should ended with element after wich you wanna add your element )
  3. Append second part to the new document.

It is simple algorithm but should works...


You can parse the existing XML file into DOM and append new elements to the DOM. Very similar to what you did with creating brand new XML. I am assuming you do not have to worry about duplicate server. If you do have to worry about that, you will have to go through the elements in the DOM to check for duplicates.

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

/* parse existing file to DOM */
Document document = documentBuilder.parse(new File("exisgint/xml/file"));

Element root = document.getDocumentElement();

for (Server newServer : Collection<Server> bunchOfNewServers){
  Element server = Document.createElement("server");
  /* create and setup the server node...*/

 root.appendChild(server);
}

/* use whatever method to output DOM to XML (for example, using transformer like you did).*/

To append a new data element,just do this...

Document doc = docBuilder.parse(is);        
Node root=doc.getFirstChild();
Element newserver=doc.createElement("new_server");
root.appendChild(newserver);

easy.... 'is' is an InputStream object. rest is similar to your code....tried it just now...