Can one cope XML nodes from one XML stream to another

What I hope to do is to copy two XML Elements datastreams out of two separate files to create a third new XML stream that consists of the elements from both of the files. I found this article on the internet but have not been able to make it work.

http://www.velocityreviews.com/forums/t132945-xml-copy-childnodes-from-one-document-to-another.html

when I run my implementation (see attached code) I get this

org.w3c.dom.DOMException: DOM005 Wrong document
at org.apache.xerces.dom.ParentNode.internalInsertBefore(ParentNode.java:388)
at org.apache.xerces.dom.ParentNode.insertBefore(ParentNode.java:320)
at org.apache.xerces.dom.CoreDocumentImpl.insertBefore(CoreDocumentImpl.java:444)
at org.apache.xerces.dom.NodeImpl.appendChild(NodeImpl.java:267)
at com.mm.DocMerge.mergeDocument(DocMerge.java:41)
at com.mm.DocMerge.execute(DocMerge.java:85)

if launched the code froma Junit project with the following stub....
      

import java.io.File;
import java.io.IOException;
import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

import com.fja.pm.ceta.util.IOUtil;

public class DocMerge {
	
public Document mergeDocument(Document tx111Document, Document tx203Document) {
Document targetDocument = null;		
Element root = tx111Document.getDocumentElement();
Node tx111sourceNode = root.getFirstChild();
	try {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();	        
		DocumentBuilder builder = dbf.newDocumentBuilder();
		targetDocument = builder.newDocument();
	} catch (ParserConfigurationException e) {
		System.err.println(e);
		System.exit(1);
	} 

Node importedNodes = tx203Document.importNode(tx111sourceNode, true);
targetDocument.appendChild(importedNodes);
		
return targetDocument;
	}
	
public Document parse4Generator(String xml) throws Exception {

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

SAXErrorHandler errorHandler = new SAXErrorHandler();

		// Get parser
DocumentBuilder db = dbf.newDocumentBuilder();
db.setErrorHandler(errorHandler);	

// Get input source
InputSource isrc = getInputSource(xml);
// Parse input source
Document document = db.parse(isrc);
return document;	
}
	
	// Get XML to parse and wrap it as an InputSource
protected InputSource getInputSource(String testcase) throws IOException {	    	
String xmlToParse = IOUtil.writeFileToString(new File(testcase));
StringReader sreader = new StringReader(xmlToParse);
InputSource result = new InputSource(sreader);
return result;
	}
	
public Document execute() {
	Document tx111Document = null;
	Document tx203Document = null;
		
	String sourcepath = "C:\\xmlbeans-2.5.0\\sales_illustrations\\";
	String tx111XML = "MMLifeSITrad111.xml";
	String tx203XML = "legacy_203tran.xml";	
	try {
		tx111Document = parse4Generator(sourcepath + tx111XML);
		tx203Document = parse4Generator(sourcepath + tx203XML);			
	} catch (Exception e) {
			
	}

	Document txMergeDocument = mergeDocument(tx111Document, tx203Document);
		return txMergeDocument;
	}

Open in new window

legacy-203tran.xml
MMLifeSITrad111.xml
dan4goodAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CEHJCommented:
>>Node importedNodes = tx203Document.importNode(tx111sourceNode, true);

should be


Node importedNodes = targetDocument.importNode(tx111sourceNode, true);

although it looks like you should be importing from the other Document too ...
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dan4goodAuthor Commented:
changed my implementation to:

public class DocMerge {
      
      public Document mergeDocument(Document tx111Document, Document tx203Document) {
            Document targetDocument = null;            
//            Element root = tx111Document.getDocumentElement();
            Node tx111sourceNode = tx111Document.getDocumentElement().getFirstChild();
            Node tx203sourceNode = tx203Document.getDocumentElement().getFirstChild();
            try {
                  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();             
                  DocumentBuilder builder = dbf.newDocumentBuilder();
                  targetDocument = builder.newDocument();
            } catch (ParserConfigurationException e) {
                  System.err.println(e);
                  System.exit(1);
            }

//            Node importedNodes = tx203Document.importNode(tx111sourceNode, true);
            Node importedNodes = targetDocument.importNode(tx111sourceNode, true);
            targetDocument.appendChild(tx203sourceNode);
            
            return targetDocument;
      }

but still got:

org.w3c.dom.DOMException: DOM005 Wrong document
at org.apache.xerces.dom.ParentNode.internalInsertBefore(ParentNode.java:388)
at org.apache.xerces.dom.ParentNode.insertBefore(ParentNode.java:320)
at org.apache.xerces.dom.CoreDocumentImpl.insertBefore(CoreDocumentImpl.java:444)
at org.apache.xerces.dom.NodeImpl.appendChild(NodeImpl.java:267)
at com.mm.DocMerge.mergeDocument(DocMerge.java:43)
at com.mm.DocMerge.execute(DocMerge.java:87)
at com.mm.unittest.JunitTestStart.testCodeStub(JunitTestStart.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

0
CEHJCommented:

>>  targetDocument.appendChild(tx203sourceNode);

You haven't imported that Node first
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

dan4goodAuthor Commented:
I must be dense!!!!! I still don't get it. I changed impl to:

      public Document mergeDocument(Document tx111Document, Document tx203Document) {
            Document targetDocument = null;            
//            Element root = tx111Document.getDocumentElement();
            Node tx111sourceNode = tx111Document.getDocumentElement().getFirstChild();
            Node tx203sourceNode = tx203Document.getDocumentElement().getFirstChild();
            try {
                  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();             
                  DocumentBuilder builder = dbf.newDocumentBuilder();
                  targetDocument = builder.newDocument();
            } catch (ParserConfigurationException e) {
                  System.err.println(e);
                  System.exit(1);
            }

//            Node importedNodes = tx203Document.importNode(tx111sourceNode, true);
            Node importedNodes111 = targetDocument.importNode(tx111sourceNode, true);
            Node importedNodes203 = targetDocument.importNode(tx203sourceNode, true);
            targetDocument.appendChild(tx111sourceNode);
            targetDocument.appendChild(tx203sourceNode);
            
            return targetDocument;
      }
and am still getting the same exception.
org.w3c.dom.DOMException: DOM005 Wrong document
at org.apache.xerces.dom.ParentNode.internalInsertBefore(ParentNode.java:388)
at org.apache.xerces.dom.ParentNode.insertBefore(ParentNode.java:320)
at org.apache.xerces.dom.CoreDocumentImpl.insertBefore(CoreDocumentImpl.java:444)
at org.apache.xerces.dom.NodeImpl.appendChild(NodeImpl.java:267)
at com.mm.DocMerge.mergeDocument(DocMerge.java:44)
at com.mm.DocMerge.execute(DocMerge.java:89)
at com.mm.unittest.JunitTestStart.testCodeGenerator(JunitTestStart.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
0
dan4goodAuthor Commented:
ooops fixed the typo: I recogized it shouldhave been:

      targetDocument.appendChild(importedNodes111);
      targetDocument.appendChild(importedNodes203);


but still got:

org.w3c.dom.DOMException: DOM006 Hierarchy request error
at org.apache.xerces.dom.ParentNode.internalInsertBefore(ParentNode.java:392)
at org.apache.xerces.dom.ParentNode.insertBefore(ParentNode.java:320)
at org.apache.xerces.dom.CoreDocumentImpl.insertBefore(CoreDocumentImpl.java:444)
at org.apache.xerces.dom.NodeImpl.appendChild(NodeImpl.java:267)
at com.mm.DocMerge.mergeDocument(DocMerge.java:43)
at com.mm.DocMerge.execute(DocMerge.java:88)
at com.mm.unittest.JunitTestStart.testCodeGenerator(JunitTestStart.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
0
dan4goodAuthor Commented:
Also, noticed that the XML was not well-formed. Replacing MMLifeSITrad111.xml See attached file with description "New correcr version of 111."
MMLifeSITrad111.xml
0
CEHJCommented:
Make sure what you're trying to do is consistent with the DTD/schema of the document
0
dan4goodAuthor Commented:
Sorry it took me so long to catch on, your comment "Make sure what you're trying to do is consistent with the DTD/schema of the document" while not the answer was helpful in getting my code to work. thanks again
0
CEHJCommented:
:-)

Can you say, for the benefit of future visitors, what exact solution you used?
0
dan4goodAuthor Commented:
Sure, I won't be able to put the whole post together now because I am up against a deadline, but should be able too later this afternoon. please keep this thread open until then.
0
dan4goodAuthor Commented:
Here is what I came up with....hope others find it helpful., I enhanced it to process any possible 1 to N nodes from either file, rather than just a single node ....

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import com.fja.pm.ceta.util.IOUtil;

public class XMLUtil {
      
      private final String rootElement = "LifeSI";         // probably should be in a properties
                                                                              // file; placed here for demonstration
                                                                              // clarity only.
      
      public Document mergeDocument(Document tx111Document, Document tx203Document) {
            List<Node> the111Nodes = new ArrayList<Node>();
            List<Node> the203Nodes = new ArrayList<Node>();
            Document targetDocument = null;
            
            NodeList root111 = tx111Document.getElementsByTagName(rootElement);      
            Node element = root111.item(0);
            
            NodeList tx111Childlist = element.getChildNodes();
            for (int idx = 0; idx < tx111Childlist.getLength(); idx++) {      
                  the111Nodes.add(tx111Childlist.item(idx));
            }
            
            NodeList tx203Childlist = tx203Document.getChildNodes();
            for (int idx = 0; idx < tx203Childlist.getLength(); idx ++) {            
                  the203Nodes.add( tx203Childlist.item(idx));
            }
            
            try {
                  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();             
                  DocumentBuilder builder = dbf.newDocumentBuilder();
                  targetDocument = builder.newDocument();
            } catch (ParserConfigurationException e) {
                  System.err.println(e);
                  System.exit(1);
            }
            /**
             * create the root element of the newly created target file...
             */
            Element root = targetDocument.createElement( rootElement);
            Node importedRoot = targetDocument.importNode(root, true);
            targetDocument.appendChild(importedRoot);
            /**
             * add in all the child elements of the 111 source file...
             */      
            Iterator <Node> it111 = the111Nodes.iterator();
            while (it111.hasNext()) {
                  targetDocument.importNode( it111.next(), true);            
            }
            /**
             * add in all the child elements of the 203 source file...
             */
            Iterator <Node> it203 = the203Nodes.iterator();
            while (it203.hasNext()) {            
                  targetDocument.importNode(it203.next(), true);            
            }
            return targetDocument;
      }
      
      private Document parseDocument(String xml) throws Exception {
            
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            SAXErrorHandler errorHandler = new SAXErrorHandler();
            
            // Get parser
            DocumentBuilder db = dbf.newDocumentBuilder();
            db.setErrorHandler(errorHandler);      
            
            // Get input source
            InputSource isrc = getInputSource(xml);
            
            // Parse input source
            Document document = db.parse(isrc);
            return document;      
      }
      
      // Get XML to parse and wrap it as an InputSource
      private InputSource getInputSource(String testcase) throws IOException {                
            String xmlToParse = IOUtil.writeFileToString(new File(testcase));
            StringReader sreader = new StringReader(xmlToParse);
            InputSource result = new InputSource(sreader);
            return result;
      }
      
      public Document executeMerge() {
            Document tx111Document = null;
            Document tx203Document = null;
            /**
             * the following string variables also should be in properties file, initialized as shown
             * only for purposes of demonstration clarity...  
             */
            String sourcepath = "C:\\xmlbeans-2.5.0\\sales_illustrations\\";
            String txSourceFile1 = "LifeSITrad111.xml";
            String txSourceFile2 = "legacy_203tran.xml";      
            try {
                  tx111Document = parseDocument(sourcepath + txSourceFile1);
                  tx203Document = parseDocument(sourcepath + txSourceFile2);                  
            } catch (Exception e) {
                  e.printStackTrace();
            }
            
            Document txMergeDocument = mergeDocument(tx111Document, tx203Document);
            return txMergeDocument;
      }
}
0
CEHJCommented:
Thanks
0
objectsCommented:
thats all unnecessary, you can copy the entire tree in one line

and can you explain why you accepted that answer, it does not appear to explain the key problem you had doing the copy

0
CEHJCommented:
>>it does not appear to explain the key problem you had doing the copy

That's not the case
0
objectsCommented:
> That's not the case

sorry but it is, as shown in the posted solution
0
objectsCommented:
And the accepted solution was shown to *not* work

dan4good, can you please reply so we can resolve this
0
dan4goodAuthor Commented:
Sorry but I don't know what time zone you are both in, but in my time zone it was for dinner and I am just finishing.
                      Here's what I am trying to accomplish
I have two XML files. I 'll call the first the 'master' and call the second the 'transaction'. I want to combine these files in such a way that if the master was this
<LifeSI>
 <Node1>
</Node1>
 <Node2>
</Node2>
</LifeSI>

and for the sake of illustration the transaction would be assumed to be

<Node3>
</Node3>

I want to combin the nodes from both files into a NEW THIRD file, without altering the contents of EITHER source file resulting in a NEW THIRD FILE that contains.....
<LifeSI>
   <Node1>
   </Node1>
   <Node2>
   </Node2>
   <Node3>
   </Node3>
</LifeSI>

CEHJ's assistence enabled me to do this. The reason I had trouble with my copy initiallly, was that I was using the .importNode against an incorrect object. Was the code was changed to  

targetDocument.importNode( it111.next(), true);
         and
targetDocument.importNode(it203.next(), true);

resulting in both the nodes from the original master (the 111 transaction) AND the transaction
(the 203 transaction) being replicated into the newly created document without affecting or modifying either source document. I hope this helps....By the way, the reason you may be having trouble is please note that about halfway in the discussion I posted the following..."Also, noticed that the XML was not well-formed. Replacing MMLifeSITrad111.xml See attached file with description "New correcr version of 111."". Did you try the code using that version of the 111 file as your 'master' ?

0
objectsCommented:
And what I posted showed you exactly how to do that.  You're problem was with the creation of the root node.

If you have a look at the link I posted you will see that it is pretty much exactly what you ended up with.

0
CEHJCommented:
You'll note that i mentioned that the result should be consistent with the document definition
0
objectsCommented:
document definition has nothing to do with the issue, not sure why you would think it does

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.