Domanda

Ho due documenti XML che ho creato e voglio combinare queste due all'interno di una nuova busta. Così ho

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

e

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

Quello che mi piacerebbe fare è combinare le due cose all'interno di un nodo principale: <> DataSet docs combinati

Ho cercato di creare un documento provvisorio e sostituendo i bambini con i nodi principali dei documenti:

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

E speravo di sostituire i due spazi vuoti con gli elementi radice dei due documenti, ma ottengo "WRONG_DOCUMENT_ERR: Un nodo viene utilizzato in un documento diverso da quello che lo ha creato." Ho provato l'adozione e l'importazione dei nodi principali ma ottengo lo stesso errore.

Non c'è un modo semplice di combinare documenti senza dover leggere e creare nuovi elementi per ogni nodo?

EDIT: frammenti di codice di esempio Sto solo cercando di spostare uno al documento "vuoto" per ora ... Le funzioni ImportNode e adoptNode non possono importare / adottare i nodi del documento, ma non possono importare il nodo elemento e la sua sotto-albero ... o se lo fa, lo fa non sembra funzionare per l'aggiunta / sostituzione ancora.

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

Tutte queste gettare la DOMException: WRONG_DOCUMENT_ERR: Un nodo viene utilizzato in un documento diverso da quello che lo ha creato

.

Credo che dovrò capire come utilizzare Stax o semplicemente rileggere i documenti e creare nuovi elementi ... che sembra un po 'come troppo lavoro solo per combinare documenti, però.

È stato utile?

Soluzione

E 'un po' complicato, ma il seguente esempio esegue:

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

Altri suggerimenti

So che hai il problema risolto già, ma ho ancora voglia di prendere una pugnalata a questo problema utilizzando il XOM libreria che sto testando fuori (relative a questa domanda ), e mentre si fa questo, offrono un approccio diverso rispetto a quello della risposta di Andreas_D.

(Per semplificare questo esempio, ho messo il tuo <alert-set> e <weather-set> in file separati, che ho letto in istanze 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());

La chiave è di fare una copia degli elementi da inserire in mainDoc; altrimenti si otterrà un lamentarsi che "bambino ha già un genitore".

L'output maindoc dà ora:

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

Per la mia gioia, questo si è rivelato essere molto straight-forward a che fare con XOM. Ci sono voluti solo pochi minuti per scrivere questo, anche se sono sicuramente non molto esperto con la libreria ancora. (Sarebbe stato ancora più facile senza gli elementi <blank/>, cioè, iniziano semplicemente <DataSet></DataSet>.)

Quindi, a meno che non si dispone di ragioni convincenti per utilizzando solo gli strumenti di JDK standard, vi consiglio vivamente di provare XOM in quanto può rendere la gestione in Java XML molto più piacevole.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top