如何使用Java编辑文件对象中的XML节点

互联网上有很多关于“阅读”文件的例子,但我找不到任何关于“编辑”节点值并将其写回原始文件的内容。

我有一个非工作的 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,我想添加一个包含值“New”的“C”节点(在A节点内)

   Original  

您使用Document对象来创建新节点。 按照建议添加节点包括创建节点,设置其内容,然后将其附加到根元素。 在这种情况下,您的代码看起来像这样:

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

这将在B节点之后将C节点添加为A的新子节点。

此外,Element还有一些便利function,可以减少所需的代码量。 上面的第二行可以替换为

 e.setTextContent("new"); 

涉及非根元素的更复杂的工作将涉及您使用XPath来获取要编辑的目标节点。 如果您确实开始使用XPath来定位节点,请记住JDK XPath性能非常糟糕。 "@foo"避免使用XPath的"@foo"来支持像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写入String值。 您可以通过调整代码将其写入任何您想要的编写器,但在您的示例代码中,您使用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(); } } 

为了将文档写回文件,您需要一个XML序列化程序或编写自己的序列化程序。 如果您使用的是Xerces库,请查看XMLSerializer 。 对于样本用法,您还可以查看DOMWriter示例页面。

有关Xerces的更多信息, 请阅读此内容