如何在Java中向现有的XML文件追加节点

28
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>
5个回答

41

下面的完整示例将从当前目录读取一个 已存在的 server.xml 文件,追加一个新的 Server 并重新写入到 server.xml 文件中。它不能在没有现有的 .xml 文件的情况下正常工作,因此您需要修改代码来处理该情况。

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

示例 server.xml 文件:

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

您代码的主要更改内容是 不需要 创建一个新的“根”元素。以上示例仅使用现有的server.xml中的当前根节点,然后只是附加了一个新的 Server 元素并重新编写文件。


变量 root 和 rootElement 是完全相同的。这有什么意义? - Zoomzoom
是的,看起来是错误。如果你愿意,可以更新为更正后的代码。如果我有时间,我会自己更新它。 - andyb
@andyb 你有没有注意到你在循环内两次执行了 root.appendChild(newServer);?这是有意为之吗? - Nir Alfasi
@alfasin 我没有!也许我的四月份编辑引入了一个缺陷。我会调查并进行编辑。谢谢你告诉我 :) - andyb

7
为了添加新的数据元素,只需执行以下操作...
Document doc = docBuilder.parse(is);        
Node root=doc.getFirstChild();
Element newserver=doc.createElement("new_server");
root.appendChild(newserver);

很简单......'is'是一个InputStream对象。其余的与你的代码类似......我刚试过了。


1
你可以将现有的 XML 文件解析为 DOM,并向 DOM 中添加新元素。这与创建全新的 XML 非常相似。我假设你不必担心重复服务器。如果你确实需要担心这个问题,那么你就需要遍历 DOM 中的元素来检查是否存在重复。
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).*/

0

如果您需要在特定位置插入节点/元素,则可以执行以下步骤:

  1. 将原始XML分成两部分
  2. 将新节点/元素作为第一部分的子节点附加到第一个元素(第一部分应以您想要添加元素之后的元素结尾)
  3. 将第二部分附加到新文档中。

这是一个简单的算法,但应该有效...


在尝试重写整个 XML 文件时,可能会出现一些导致内存溢出的问题。您能提供一些避免此问题的提示吗? - undefined

-1
你可以使用 DOM4j 来完成这个任务。

1
只能使用库 org.w3c.dom.、javax.xml. 和 org.xml.sax.* :( - stackoverflow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接