简体   繁体   中英

Merge mutiple xml files and set the common root element of each xml file as the root of the merged file

I need to merge mutilpe xml files in a directory to a single xml file. Below is the description of what I am trying to achieve:

xml-1:

<?xml version="1.0" encoding="UTF-8"?>
<products>
      <product>
            <id>0569054</id>
            <ProviderName>John</ProviderName>
      </product>
</products>

xml-2

<?xml version="1.0" encoding="UTF-8"?>
<products>
  <product>
        <id>1002363</id>
        <ProviderName>Paul</ProviderName>
  </product>
</products>

Merge output:

<?xml version="1.0" encoding="UTF-8"?>

<products>
      <product>
            <id>0569054</id>
            <ProviderName>John</ProviderName>
      </product>
      <product>
            <id>1002363</id>
            <ProviderName>Paul</ProviderName>
      </product>
</products>

This is the Java code, I am trying with: Edit: tried with StAX. Now what needs to be added here to remove the products? went through Stax today to implement this, correction advices are also most welcome.

File dir = new File("/opt/dev/common");
File[] rootFiles = dir.listFiles();

Writer outputWriter = new FileWriter("mergedFile1.xml");
XMLOutputFactory xmlOutFactory = XMLOutputFactory.newFactory();
XMLEventWriter xmlEventWriter = xmlOutFactory.createXMLEventWriter(outputWriter);
XMLEventFactory xmlEventFactory = XMLEventFactory.newFactory();

xmlEventWriter.add(xmlEventFactory.createStartDocument());
xmlEventWriter.add(xmlEventFactory.createStartElement("", null, "products"));
XMLInputFactory xmlInFactory = XMLInputFactory.newFactory();
for (File rootFile : rootFiles) {
    XMLEventReader xmlEventReader = xmlInFactory.createXMLEventReader(new StreamSource(rootFile));
    XMLEvent event = xmlEventReader.nextEvent();

    while (event.getEventType() != XMLEvent.START_ELEMENT) {
        event = xmlEventReader.nextEvent();
    }

    do {
        xmlEventWriter.add(event);
        event = xmlEventReader.nextEvent();
    } while (event.getEventType() != XMLEvent.END_DOCUMENT);
    xmlEventReader.close();
}

xmlEventWriter.add(xmlEventFactory.createEndElement("", null, "products"));
xmlEventWriter.add(xmlEventFactory.createEndDocument());

xmlEventWriter.close();
outputWriter.close();

You really don't want to do this in Java. In XSLT 2.0 it's

<xsl:template name="main">
  <products>
    <xsl:copy-of select="collection('file://mydir')/*/*"/>
  </products>
</xsl:template>

Doing it in Java is very simple and straight forward... Below is the code to merge your files based on VTD-XML. It is basically appending bytes exclusive of the starting and ending tags. Imagine that you open up file and use mouse pointer to highlight the section of text then paste it to an output text editor.. this is exact what happens here.

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

public class simpleMerge {
    static VTDGen vg = new VTDGen();
    public static void main(String[] s) throws VTDException,IOException{
        FileOutputStream fos = new FileOutputStream("d:\\xml\\o.xml");
        // write header to 
        byte[] header=("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
        "<products>").getBytes();
        fos.write(header);
        appendSingleFile("d:\\xml\\xml-1.xml",fos);
        appendSingleFile("d:\\xml\\xml-2.xml",fos);
        fos.write("</products>".getBytes());

    }
    // write everything under root into output efficiently, ie. direct byte copying
    public static void appendSingleFile(String fileName,FileOutputStream fos) throws VTDException,IOException{
        if (!vg.parseFile(fileName, false)){
            System.out.println("invalid file:"+fileName);
            System.exit(1);
        }
        VTDNav vn = vg.getNav();
        long l = vn.getContentFragment();
        fos.write(vn.getXML().getBytes(),(int)l,(int)(l>>32));
        vg.clear();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM