Java-Anfügen von XML-Dokumenten an vorhandene Dokumente

Nur versuchen, eine in das "leere" Dokument für jetzt zu bewegen... Die Funktionen importNode und adoptNode können keine Dokumentknoten importieren/annehmen, aber sie können den Elementknoten und seine Unterstruktur nicht importieren... oder wenn dies der Fall ist, scheint es nicht zum Anhängen/Ersetzen noch zu funktionieren.

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

Alle diese auslösen die DOMAusnahme: WRONG_DOCUMENT_ERR: Ein Knoten wird in einem anderen Dokument als dem, das ihn erstellt hat, verwendet.

Ich denke, ich muss herausfinden, wie man Stax verwendet oder einfach die Dokumente noch einmal liest und neue Elemente erstellt... Diese Art scheint jedoch zu viel Arbeit zu sein, nur um Dokumente zu kombinieren.

Ich habe zwei XML-Dokumente, die ich erstellt habe, und ich möchte diese beiden innerhalb eines neuen Umschlags kombinieren. Also habe ich

<alert-set>
  <warning>National Weather Service...</warning>
  <start-date>5/19/2009</start-date>
  <end-date>5/19/2009</end-date>
</alert-set>

und

 <weather-set>
   <chance-of-rain type="percent">31</chance-of-rain>
   <conditions>Partly Cloudy</conditions>
   <temperature type="Fahrenheit">78</temperature>
 </weather-set>

Was ich gerne tun würde, ist die beiden innerhalb eines Stammknotens zu kombinieren: < DataSet> kombinierte Dokumente < /DataSet>

Ich habe versucht, ein temporäres Dokument zu erstellen und untergeordnete Elemente durch die Stammknoten der Dokumente zu ersetzen:

<DataSet>
  <blank/>
  <blank/>
</DataSet>

Und ich hoffte, die beiden Leerzeichen durch die Stammelemente der beiden Dokumente zu ersetzen, aber ich erhalte "WRONG_DOCUMENT_ERR: Ein Knoten wird in einem anderen Dokument als dem, das ihn erstellt hat, verwendet." Ich habe versucht, die Stammknoten zu übernehmen und zu importieren, aber ich erhalte den gleichen Fehler.

Gibt es nicht eine einfache Möglichkeit, Dokumente zu kombinieren, ohne für jeden Knoten durchlesen und neue Elemente erstellen zu müssen?

EDIT: Beispielcodeausschnitte

Antwort auf "Java-Anfügen von XML-Dokumenten an vorhandene Dokumente " 2 von antworten

Es ist ein bisschen schwierig, aber das folgende Beispiel läuft:

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

Ich weiß, dass Sie das Problem bereits gelöst haben, aber ich wollte immer noch einen Stich gegen dieses Problem mit der XOM library that I'm currently testing out (related to Bibliothek machen, die ich gerade teste (im Zusammenhang mit this question), and while doing that, offer a different approach than that of Andreas_D's answer. ), und dabei einen anderen Ansatz als die Antwort von Andreas_D anbieten.

(Um dieses Beispiel zu vereinfachen, habe ich Ihre <alert-set> and und <weather-set> into separate files, which I read into in separate Dateien eingefügt, die ich in nu.xom.Document instances.)-Instanzen gelesen habe.)

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

Der Schlüssel ist, eine Kopie der Elemente zu erstellen, die in mainDoc; otherwise you'll get a complain that "child already has a parent". eingefügt werden sollen; Andernfalls werden Sie beschwert, dass "Kind bereits ein Elternteil hat".

Outputting mainDoc gibt jetzt:

<?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>

Zu meiner Freude stellte sich heraus, dass dies sehr geradlinig mit XOM zu tun hatte. Es dauerte nur ein paar Minuten, um dies zu schreiben, obwohl ich definitiv nicht sehr erfahren mit der Bibliothek noch. (Ohne die <blank/> elements, i.e., starting with simply Elemente wäre es noch einfacher gewesen, d.h. mit einfach <DataSet></DataSet>.) zu beginnen.)

Also, es sei denn, Sie haben zwingende Gründe für die Verwendung nur der Standard-JDK-Tools, empfehle ich dringend, XOM auszuprobieren, da es die XML-Handhabung in Java viel angenehmer machen kann.