Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Merge two XMLs in Java

Tags:

java

merge

xml

stax

I am trying to merge two xmls in Java. I am using STaX API to write these XMLs. I searched a lot on internet on how to merge xmls but none seems as straight forward as C#. Is there any straight-forward way of doing this in Java using StAX? Probably xslt would not be the right solution since the file size can be big.

File1.xml

<TestCaseBlock>
    <TestCase TestCaseID="1">
        <Step ExecutionTime="2011-03-29 12:08:31 EST">
            <Status>Passed</Status>
            <Description>foo</Description>
            <Expected>foo should pass</Expected>
            <Actual>foo passed</Actual>
        </Step>
       </TestCase>
</TestCaseBlock> 

File2.xml

<TestCaseBlock>
    <TestCase TestCaseID="2">
        <Step ExecutionTime="2011-03-29 12:08:32 EST">
            <Status>Failed</Status>
            <Description>test something</Description>
            <Expected>something expected</Expected>
            <Actual>not as expected</Actual>
        </Step>
    </TestCase>
</TestCaseBlock>

Merged.xml

<TestCaseBlock>
<TestCase TestCaseID="1">
    <Step ExecutionTime="2011-03-29 12:08:33 EST">
        <Status>Passed</Status>
        <Description>foo</Description>
        <Expected>foo should pass</Expected>
        <Actual>foo passed</Actual>
    </Step>
</TestCase>
<TestCase TestCaseID="2">
    <Step ExecutionTime="2011-03-29 12:08:34 EST">
        <Status>Failed</Status>
        <Description>test something</Description>
        <Expected>something expected</Expected>
        <Actual>not as expected</Actual>
    </Step>
</TestCase>
</TestCaseBlock>
like image 417
nilesh Avatar asked Apr 15 '11 19:04

nilesh


People also ask

How can I merge two XML files online?

To add files click anywhere in the blue area or on the Browse for file button to upload or drag and drop them. You can also add the documents by entering their URL in the URL cell. Click on the Merge button. Your MPP file will be uploaded and combined to the result format.

What is XML in Java with example?

XML (Extensible Markup Language) is a very popular simple text-based language that can be used as a mode of communication between different applications. It is considered as a standard means to transport and store data.


3 Answers

I have a solution that works for me. Now experts, please advise if this is the way to go.

Thanks, -Nilesh

    XMLEventWriter eventWriter;
    XMLEventFactory eventFactory;
    XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
    XMLInputFactory inputFactory = XMLInputFactory.newInstance();
    eventWriter = outputFactory.createXMLEventWriter(new FileOutputStream("testMerge1.xml"));
    eventFactory = XMLEventFactory.newInstance();
    XMLEvent newLine = eventFactory.createDTD("\n");                
    // Create and write Start Tag
    StartDocument startDocument = eventFactory.createStartDocument();
    eventWriter.add(startDocument);
    eventWriter.add(newLine);
    StartElement configStartElement = eventFactory.createStartElement("","","TestCaseBlock");
    eventWriter.add(configStartElement);
    eventWriter.add(newLine);
    String[] filenames = new String[]{"test1.xml", "test2.xml","test3.xml"};
    for(String filename:filenames){
           XMLEventReader test = inputFactory.createXMLEventReader(filename,
                             new FileInputStream(filename));
        while(test.hasNext()){
            XMLEvent event= test.nextEvent();
        //avoiding start(<?xml version="1.0"?>) and end of the documents;
        if (event.getEventType()!= XMLEvent.START_DOCUMENT && event.getEventType() != XMLEvent.END_DOCUMENT)
                eventWriter.add(event);         
        eventWriter.add(newLine);
            test.close();
        }           
    eventWriter.add(eventFactory.createEndElement("", "", "TestCaseBlock"));
    eventWriter.add(newLine);
    eventWriter.add(eventFactory.createEndDocument());
    eventWriter.close();
like image 65
nilesh Avatar answered Sep 28 '22 04:09

nilesh


General solution still would be XSLT, but you'd need to combine two files into one big XML first with a wrapper element (XSLT works with one input source).

<root>
    <TestCaseBlock>
        <TestCase TestCaseID="1">
        ...
        </TestCase>
    </TestCaseBlock>
    <TestCaseBlock>
        <TestCase TestCaseID="2">
        ...
        </TestCase>
    </TestCaseBlock>
</root>

Then just do XSLT for match="//TestCase", and dump all test cases out, ignoring what test case block they belong to.

And don't worry about performance until you have tried. XML APIs in JAva are getting much better than in 2003.

This is stylesheet you need:

<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">
            <TestCaseBlock>
                <xsl:apply-templates/>
            </TestCaseBlock>
    </xsl:template>

    <xsl:template match="//TestCase">
          <xsl:copy-of select="."/> 
    </xsl:template>

</xsl:stylesheet>

Tested, it works.

BTW, this XSLT was compiled and executed on this (small) example in 1ms.

like image 27
Vladimir Dyuzhev Avatar answered Sep 28 '22 06:09

Vladimir Dyuzhev


If structure is regular enough so you can use data binding, I would actually consider binding XML from both files into objects using JAXB, then merging objects, serializing back as XML. If file sizes are big you can also just bind sub-trees; for this you use XMLStreamReader (from Stax api, javax.xml.stream) to iterate to element that is the root, bind that element (and its children) to object you want, iterate to next root element.

like image 43
StaxMan Avatar answered Sep 28 '22 04:09

StaxMan