如何使用Java编辑文件对象中的XML节点 [英] How do I edit a XML node in a file object, using Java

查看:105
本文介绍了如何使用Java编辑文件对象中的XML节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

There are a lot of examples on the internet of "reading" files but I can't find anything on "editing" a node value and writing it back out to the original file.

我有一个非工作 xml编写器类,如下所示:

I have a non-working xml writer class that looks like this:

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>


推荐答案

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

You use the Document object to create new nodes. Adding nodes as you suggest involves creating a node, setting its content and then appending it to the root element. In this case your code would look somehting like this:

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

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

This will add the C node as a new child of A right after the B node.

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

Additionally, Element has some convenience functions that reduce the amount of required code. The second line above could have been replaced with

e.setTextContent("new");

涉及非根元素的更复杂的工作将涉及您使用XPath来获取要编辑的目标节点。如果您确实开始使用XPath来定位节点,请记住JDK XPath性能非常糟糕。避免使用@ foo的XPath,支持 e.getAttribute(foo)等构造可以。

More complicated efforts involving non root elements will involve you using XPath to fetch the target node to be edited. If you do start to use XPath to target nodes, bear in mind that the JDK XPath performance is abysmal. Avoid using an XPath of "@foo" in favor of constructs like e.getAttribute("foo") whenever you can.

编辑:将文档格式化为可以写入文件的字符串可以使用以下代码完成。

Formatting the document back to a string which can be written to a file can be done with the following code.

 Document xmlDocument;
 StringWriter writer = new StringWriter();
 TransformerFactory.newInstance().transform(new DOMSource(xmlDocument), new StreamResult(writer));
 writer.close();
 String xmlString = writer.toString();

编辑:回复:带代码的更新问题。

Re: updated question with code.

您的代码不起作用,因为您正在混淆路径和元素名称。 Document.createElement()的参数是新节点的名称,而不是放置它的位置。在我编写的示例代码中,我没有找到适当的节点,因为您特别询问了如何向文档父元素添加节点。如果您希望 addElement()按照我认为您期望它的行为方式运行,则必须为目标父节点的xpath添加另一个参数。

Your code doesn't work because you're conflating 'path' and 'element name'. The parameter to Document.createElement() is the name of the new node, not the location in which to place it. In the example code I wrote I didn't get into locating the appropriate node because you were asking specifically about adding a node to the document parent element. If you want your addElement() to behave the way I think you're expecting it to behave, you'd have to add another parameter for the xpath of the target parent node.

您的代码的另一个问题是您的writeDoc()函数没有任何输出。我的示例显示将XML写入String值。您可以通过调整代码将其写入任何您想要的编写器,但在您的示例代码中,您使用StringWriter但从不从中提取写入的字符串。

The other problem with your code is that your writeDoc() function doesn't have any output. My example shows writing the XML to a String value. You can write it to any writer you want by adapting the code, but in your example code you use a StringWriter but never extract the written string out of it.

我建议你重写这样的代码

I would suggest rewriting your code something like this

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

这篇关于如何使用Java编辑文件对象中的XML节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆