Java将XML文档附加到现有文档

rav*_*vun 18 java xml merge append

我有两个我创建的XML文档,我想将这两个文档组合在一个新的信封中.所以我有

<alert-set>
  <warning>National Weather Service...</warning>
  <start-date>5/19/2009</start-date>
  <end-date>5/19/2009</end-date>
</alert-set>
Run Code Online (Sandbox Code Playgroud)

 <weather-set>
   <chance-of-rain type="percent">31</chance-of-rain>
   <conditions>Partly Cloudy</conditions>
   <temperature type="Fahrenheit">78</temperature>
 </weather-set>
Run Code Online (Sandbox Code Playgroud)

我想要做的是在根节点内组合两个:<DataSet>组合文档</ DataSet>

我已经尝试创建临时文档并用文档的根节点替换子项:

<DataSet>
  <blank/>
  <blank/>
</DataSet>
Run Code Online (Sandbox Code Playgroud)

我希望用两个文件的根元素替换这两个空格,但我得到"WRONG_DOCUMENT_ERR:一个节点用在与创建它的文档不同的文档中." 我尝试采用并导入根节点,但我得到了同样的错误.

是否有一些简单的方法来组合文档而无需通读并为每个节点创建新元素?

编辑:示例代码片段现在只是尝试将一个移动到"空白"文档... importNode和adoptNode函数不能导入/采用Document节点,但它们无法导入元素节点及其子树...或者如果它确实,它似乎不适用于追加/替换仍然.

    Document xmlDoc;     //created elsewhere
    Document weather = getWeather(latitude, longitude);
    Element weatherRoot = weather.getDocumentElement();

    Node root = xmlDoc.getDocumentElement();
    Node adopt = weather.adoptNode(weatherRoot);
    Node imported = weather.importNode(weatherRoot, true);
    Node child = root.getFirstChild();

    root.replaceChild(adopt, child);      //initially tried replacing the <blank/> elements
    root.replaceChild(imported, child);

    root.appendChild(adopt);
    root.appendChild(imported);
    root.appendChild(adopt.cloneNode(true));
Run Code Online (Sandbox Code Playgroud)

所有这些抛出DOMException:WRONG_DOCUMENT_ERR:节点用于与创建它的文档不同的文档中.

我想我将不得不弄清楚如何使用stax或只是重新阅读文档并创建新元素......但是,为了合并文档,这似乎太多了.

And*_*s_D 29

这有点棘手,但以下示例运行:

public static void main(String[] args) {

    DocumentImpl doc1 = new DocumentImpl();
    Element root1 = doc1.createElement("root1");
    Element node1 = doc1.createElement("node1");
    doc1.appendChild(root1);
    root1.appendChild(node1);

    DocumentImpl doc2 = new DocumentImpl();
    Element root2 = doc2.createElement("root2");
    Element node2 = doc2.createElement("node2");
    doc2.appendChild(root2);
    root2.appendChild(node2);

    DocumentImpl doc3 = new DocumentImpl();
    Element root3 = doc3.createElement("root3");
    doc3.appendChild(root3);

    // root3.appendChild(root1); // Doesn't work -> DOMException
    root3.appendChild(doc3.importNode(root1, true));

    // root3.appendChild(root2); // Doesn't work -> DOMException
    root3.appendChild(doc3.importNode(root2, true));   
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这很有效.我正在导入根节点自己的文档而不是我试图将所有内容组合到的文档.有时午休时间可以解决所有问题.谢谢. (3认同)

Jon*_*nik 7

我知道你已经解决了这个问题,但是我仍然希望使用我正在测试的XOM库(与这个问题相关)来解决这个问题,并且在这样做时,提供一种不同于Andreas_D的回答.

(为了简化这个例子中,我把你<alert-set><weather-set>成单独的文件,这是我读入nu.xom.Document的情况.)

import nu.xom.*;

[...]

Builder builder = new Builder();
Document alertDoc = builder.build(new File("src/xomtest", "alertset.xml"));
Document weatherDoc = builder.build(new File("src/xomtest", "weatherset.xml"));
Document mainDoc = builder.build("<DataSet><blank/><blank/></DataSet>", "");

Element root = mainDoc.getRootElement();
root.replaceChild(
    root.getFirstChildElement("blank"), alertDoc.getRootElement().copy());
root.replaceChild(
    root.getFirstChildElement("blank"), weatherDoc.getRootElement().copy());
Run Code Online (Sandbox Code Playgroud)

关键是要复制要插入的元素mainDoc; 否则你会抱怨"孩子已经有了父母".

现在输出mainDoc给出:

<?xml version="1.0" encoding="UTF-8"?>
<DataSet>
    <alert-set>
        <warning>National Weather Service...</warning>
        <start-date>5/19/2009</start-date>
        <end-date>5/19/2009</end-date>
    </alert-set>
    <weather-set>
        <chance-of-rain type="percent">31</chance-of-rain>
        <conditions>Partly Cloudy</conditions>
        <temperature type="Fahrenheit">78</temperature>
    </weather-set>
</DataSet>
Run Code Online (Sandbox Code Playgroud)

令我高兴的是,事实证明这与XOM非常直截了当.写这篇文章只花了几分钟,尽管我对图书馆的经验还不是很丰富.(没有<blank/>元素就更容易了,即从简单开始<DataSet></DataSet>.)

因此,除非您有充分理由仅使用标准JDK工具,否则我热烈建议您尝试使用XOM,因为它可以使Java中的XML处理更加愉快.