互联网上有很多关于“阅读”文件的例子,但我找不到任何关于“编辑”节点值并将其写回原始文件的内容。
我有一个非工作 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节点内),其中包含值“New”:
<A>
<B>Original</B>
</A>
答案 0 :(得分:6)
使用Document对象创建新节点。按照建议添加节点包括创建节点,设置其内容,然后将其附加到根元素。在这种情况下,您的代码看起来像这样:
Element e = xmlDocument.createElement("C");
e.appendChild(xmlDocument.createTextNode("new"));
xmlDocument.getDocumentElement().appendChild(e);
这将在B节点之后将C节点添加为A的新子节点。
此外,Element还有一些便利功能,可以减少所需的代码量。上面的第二行可能已被替换为
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写入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();
}
}
答案 1 :(得分:1)
为了将文档写回文件,您需要一个XML序列化程序或自己编写。如果您使用的是Xerces库,请查看XMLSerializer。对于样本用法,您还可以查看DOMWriter样本页面。
有关Xerces的更多信息,read this