【问题标题】:How do I edit a XML node in a file object, using Java如何使用 Java 编辑文件对象中的 XML 节点
【发布时间】:2009-10-30 01:09:31
【问题描述】:

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

我有一个 不工作 xml writer 类,如下所示:

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 节点内)

 <A>
   <B>Original</B>
 </A>

【问题讨论】:

标签: java xml


【解决方案1】:

您使用 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 写入字符串值。您可以通过调整代码将其写入您想要的任何作家,但在您的示例代码中,您使用 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();
    }
}

【讨论】:

  • 我支持 XPath 性能问题:我在一个应用程序中使用了少量,并将运行时间从几秒缩短到四分钟。令人惊讶。
  • 这几乎就是我一直在寻找的答案。如何提交对文件系统对象的更改?
  • @djangofan - 查看这个答案以写出 XML 数据:stackoverflow.com/questions/1137488/… (用 System.out 替换 FileOutputStream
  • Jherico,我最终无法让您的建议发挥作用。我修改了问题。知道我的代码有什么问题吗?
  • 那里有几个错别字,但您的一般建议肯定解决了它。谢谢。
【解决方案2】:

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

有关 Xerces 的更多信息,read this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 2015-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多