Domanda

Ho cercato nel web e ho cercato StackOverflow su e giù. Nessuna soluzione. Anche se ho trovato soluzioni come fare questo all'interno di pura XSLT qui .

Ma il problema è che il codice XML risultante sarà diverse centinaia di MB di grandi dimensioni. Quindi devo farlo con SAX in Java. (Si prega di nessuna soluzione XSLT, anche se ho etichettato con XSLT; -))

Mi spiego meglio con maggiori dettagli. Ho diversi file XML multipli (preferibili InputSteam 's) che devono essere analizzati. I file o sguardi di InputStream come

inputstream1

<root>
  <doc>
    <tag>test1</tag>
  </doc>
  <doc>
    <tag>test2</tag>
  </doc>
  ...
</root>

inputstream2

<root>
  <doc>
    <tag>test3</tag>
  </doc>
  <doc>
    <tag>test4</tag>
  </doc>
  ...
</root>

inputstream1 + inputstream2 + ... + inputstreamN = XML risultante . Sembrerà

<root>
  <doc>
    <tag>test1</tag>
  </doc>
  <doc>
    <tag>test2</tag>
  </doc>
  ...
   <doc>
    <tag>test3</tag>
  </doc>
  <doc>
    <tag>test4</tag>
  </doc>
  ...
</root>

Fare qualcuno ha una soluzione o un link per questo? Questo è possibile tramite l'implementazione di un InputSource personalizzato o devo usare un ContentHandler personalizzato? O è possibile con Joost / STX ?

La cosa bella se potevo usare un ContentHandler sarebbe che ho potuto applicare alcune trasformazioni minori (ho già implementato questo). Ma allora il problema è che non so un modo per passare più file o InputStream di come InputSource:

XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.setContentHandler(customHandler);
xmlReader.parse(getInputSource()); // only one InputStream possible

o dovrei analizzare i InputStreams direttamente nel mio ContentHandler?

È stato utile?

Soluzione 3

sono finalmente riuscito questo tramite il seguente frammento:

  finalHandler = new StreamResult(new OutputStreamWriter(System.out));
  // customHandler extends DefaultHandler
  CustomTransformerHandler customHandler = new CustomTransformerHandler(
         finalHandler);
  customHandler.startDocumentExplicitly();
  InputStream is = null;
  while ((is = customHandler.createNextInputStream()) != null) {
    // multiple inputStream parsing
    XMLReader myReader = XMLReaderFactory.createXMLReader();
    myReader.setContentHandler(customHandler);
    myReader.parse(new InputSource(is));
  }
  customHandler.endDocumentExplicitly();

La parte importante è stato quello di lasciare lo startDocument e metodi EndDocument vuota. Tutti gli altri metodi (personaggi, startElement, endElement) saranno reindirizzati alla finalHandler. Il metodo customHandler.createNextInputStream restituisce null se tutti inputstreams vengono letti.

Altri suggerimenti

Non ho fatto io stesso, ma ho ricordato di aver visto un articolo developerWorks di IBM che sembrava fatto questo abbastanza facile.

E 'un po' vecchio, ma prova a http: / /www.ibm.com/developerworks/xml/library/x-tipstx5/index.html

Questa è StAX invece di SAX. Non sono sicuro di JDK correnti includono StAX. Se non è possibile probabilmente ottenere da http://stax.codehaus.org/

Si consiglia di avere uno sguardo alla versione a pagamento-per di Saxon. E 'in grado di gestire on-the-fly XSLT non aver bisogno della piena DOM in memoria.

il modo più efficace per unire i file sono di utilizzare livello di byte taglia e incolla funzionalità offerta da VTD-XML , per quanto ne so. Si prende entrambi i file, li analizzare in oggetti VTDNav, quindi un'istanza di un oggetto XMLModifier, afferrare i frammenti del secondo file, e li inserisce nel primo file ... che ha ottenuto di essere molto più efficiente di SAX .. Anche l'XML risultante ottiene la direzione scritta su un file - non v'è alcuna necessità di memorizzare nella memoria. Di seguito è riportato il codice completo in meno di 20 linee ...

import com.ximpleware.*;
import java.io.*;

public class merge {
    // merge second.xml into first.xml assuming the same encoding
    public static void main(String[] s) throws VTDException, IOException{
        VTDGen vg = new VTDGen();
        if (!vg.parseFile("d:\\xml\\first.xml", false))
            return;
        VTDNav vn1=vg.getNav();
        if(!vg.parseFile("d:\\xml\\second.xml", false))
            return;
        VTDNav vn2 = vg.getNav();
        XMLModifier xm = new XMLModifier(vn1);
        long l = vn2.getContentFragment();
        xm.insertBeforeTail(vn2, l);
        xm.output("d:\\xml\\merged.xml");   
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top