Pregunta

Tengo dos documentos XML que he creado y quiero combinar estos dos en el interior de un sobre nuevo. Así que tengo

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

y

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

Lo que me gustaría hacer es combinar los dos dentro de un nodo raíz: <> DataSet documentos combinados

He intentado crear un documento temporal y la sustitución de los niños con los nodos raíz de los documentos:

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

Y esperaba para reemplazar los dos en blanco con los elementos fundamentales de los dos documentos, pero me sale "WRONG_DOCUMENT_ERR: Un nodo se utiliza en un documento diferente a la que lo creó." Probé la adopción y la importación de los nodos raíz pero me da el mismo error.

¿No hay alguna manera fácil de combinar documentos sin tener que leer y crear nuevos elementos para cada nodo?

EDIT: fragmentos de código de ejemplo Sólo tratando de mover una al documento "en blanco" por ahora ... Las funciones ImportNode y adoptNode no pueden importar / adoptar nodos del documento, pero no pueden importar el nodo de elemento y su sub-árbol ... o si lo hace, lo hace no parece funcionar para anexar / sustitución todavía.

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

Todo esto tire la DOMException: WRONG_DOCUMENT_ERR: Un nodo se utiliza en un documento diferente a la que lo creó

.

Creo que voy a tener que encontrar la manera de utilizar stax o simplemente volver a leer los documentos y crear nuevos elementos ... Esa clase parece como demasiado trabajo sólo para combinar documentos, sin embargo.

¿Fue útil?

Solución

Es un poco complicado, pero el ejemplo siguiente se ejecuta:

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

Otros consejos

Sé que tienes el problema ya resuelto, pero todavía quería tomar una puñalada en este problema mediante el XOM biblioteca que actualmente estoy probando (relacionado con esta pregunta ), y al mismo tiempo haciendo eso, ofrecen un enfoque diferente a la de la respuesta de Andreas_D.

(Para simplificar este ejemplo, puse su <alert-set> y <weather-set> en archivos separados, que leí en casos 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 clave es hacer una copia de los elementos a insertar en mainDoc; de lo contrario obtendrá un quejan de que "niño ya tiene un padre".

Dar salida mainDoc da ahora:

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

A mi placer, esto resultó ser muy recta de avance que ver con XOM. Sólo tomó unos minutos para escribir esto, a pesar de que estoy definitivamente no muy experimentado con la biblioteca aún. (Hubiera sido aún más fácil sin los elementos <blank/>, es decir, comenzando con simplemente <DataSet></DataSet>.)

Así que, a menos que tenga razones convincentes para utilizar sólo las herramientas del JDK estándar, recomiendo encarecidamente probar XOM ya que puede hacer el manejo de XML en Java mucho más agradable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top