java - 如何将节点附加到Java中的现有XML文件
Posted
技术标签:
【中文标题】java - 如何将节点附加到Java中的现有XML文件【英文标题】:How do I append a node to an existing XML file in java 【发布时间】:2018-06-30 01:51:36 【问题描述】: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);
这是我需要帮助的功能:
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);
原文:
<Servers>
<server>
<name>something</name>
<port>port</port>
</server>
</Servers>
通缉:
<Servers>
<server>
<name>something</name>
<port>port</port>
</server>
<server>
<name>something</name>
<port>port</port>
</server>
<Servers>
【问题讨论】:
【参考方案1】:下面的完整示例将从当前目录读取一个现有 server.xml
文件,追加一个新服务器并将文件重新写入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完全相同。有什么意义? 是的,看起来像一个错误。如果需要,请随时使用更正的代码进行更新。如果我有时间我会自己更新。 @andyb 你注意到你在循环中做了两次root.appendChild(newServer);
吗?这是故意的吗?
@alfasin 我没有!也许我在四月份的编辑引入了一个缺陷。我会调查和编辑。谢谢你让我知道:)【参考方案2】:
要附加一个新的数据元素,只需这样做......
Document doc = docBuilder.parse(is);
Node root=doc.getFirstChild();
Element newserver=doc.createElement("new_server");
root.appendChild(newserver);
easy.... 'is' 是一个 InputStream 对象。 rest 和你的代码很相似……刚刚试了一下……
【讨论】:
【参考方案3】:您可以将现有的 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).*/
【讨论】:
【参考方案4】:如果您需要在某个特定位置插入节点/元素,您可以执行后续步骤
-
将原始xml分成两部分
将您的新节点/元素作为子节点添加到 first(第一部分应以元素结尾,然后您要添加元素)
将第二部分附加到新文档中。
这是一个简单的算法,但应该可以工作......
【讨论】:
【参考方案5】:您可以使用 DOM4j 来执行此操作。
【讨论】:
只能使用库的 org.w3c.dom.* , javax.xml.*, org.xml.sax.* :(以上是关于java - 如何将节点附加到Java中的现有XML文件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 java / kotlin 中的注释处理将方法附加到现有类?