XML: copy childNodes from one document to another?

L

lb

Hi



Anyone know if there's a fast way to copy childNodes from one XML document
to another using Oracle XML?

What about Apache XML?



Lars B.
 
M

Martin Honnen

lb said:
Anyone know if there's a fast way to copy childNodes from one XML document
to another using Oracle XML?

What about Apache XML?

If you use the W3C DOM Document object then you can use the method
importNode to import nodes from another document and you can then append
them to your document:

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

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class Test20040427 {
public static void main (String[] args) {
try {
DocumentBuilderFactory documentBuilderFactory =
DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder =
documentBuilderFactory.newDocumentBuilder();
Document xmlDocument1 = documentBuilder.parse("test20040427.xml");

Document xmlDocument2 = documentBuilder.newDocument();

xmlDocument2.appendChild(xmlDocument2.importNode(xmlDocument1.getDocumentElement(),
true));

System.out.println("xmlDocument2.getDocumentElement().getNodeName(): " +
xmlDocument2.getDocumentElement().getNodeName());
}
catch (Exception e) {
System.out.println("Error: " + e);
}
}
}

Both Apache and Oracle parsers should support JAXP
DocumentBuilderFactory/DocumentBuilder and the W3C Document interface
but you can simply work with the Sun JDK 1.4 as it has all that is needed
 
L

LB

Martin Honnen said:
If you use the W3C DOM Document object then you can use the method
importNode to import nodes from another document and you can then append
them to your document:

Thanks, but I meant moving/copying a NodeList from one document to another:

Doc 1:

<root>
<sections>
<section source="doc1"/>
<section source="doc1"/>
</sections
</root>

Doc 2:

<root>
<sections>
<section source="doc2"/>
<section source="doc2"/>
</sections
</root>

I want this result:

Doc 1:

<root>
<sections>
<section source="doc1"/>
<section source="doc1"/>
<section source="doc2"/>
<section source="doc2"/>
</sections
</root>

The problem is that I have about 20000 "section" nodes to be moved. I'm
looking for something like
sections1.appendChildNodes(section2.getChildNodes).
Do I really have to import and append 20000 times?

Lars
 
J

Jörn W. Janneck

LB wrote:
[snip]
The problem is that I have about 20000 "section" nodes to be moved. I'm
looking for something like
sections1.appendChildNodes(section2.getChildNodes).
Do I really have to import and append 20000 times?

lars:

have you considered the use of xslt for the task?

cheers,

-- j
 
L

lb

Jörn W. Janneck said:
LB wrote:
[snip]
The problem is that I have about 20000 "section" nodes to be moved. I'm
looking for something like
sections1.appendChildNodes(section2.getChildNodes).
Do I really have to import and append 20000 times?

lars:

have you considered the use of xslt for the task?

No, I can't really say that this is the first thing that comes to mind.

Do you think there's some performance to gain by using this method?

What did you have in mind?
 
M

Martin Honnen

LB said:
Thanks, but I meant moving/copying a NodeList from one document to another:

Doc 1:

<root>
<sections>
<section source="doc1"/>
<section source="doc1"/>
</sections
</root>

Doc 2:

<root>
<sections>
<section source="doc2"/>
<section source="doc2"/>
</sections
</root>

I want this result:

Doc 1:

<root>
<sections>
<section source="doc1"/>
<section source="doc1"/>
<section source="doc2"/>
<section source="doc2"/>
</sections
</root>

The problem is that I have about 20000 "section" nodes to be moved. I'm
looking for something like
sections1.appendChildNodes(section2.getChildNodes).
Do I really have to import and append 20000 times?

You could first copy the nodes into a DocumentFragment and then
insert/append that. However with 20000 nodes I wonder whether DOM is a
good solution at all, you might be better off with some SAX processing
 
L

lb

Martin Honnen said:
You could first copy the nodes into a DocumentFragment and then
insert/append that. However with 20000 nodes I wonder whether DOM is a
good solution at all, you might be better off with some SAX processing



Thanks for the suggestions. I have to think of an alternative since Oracle's
parses doesn't seem to be able to handle large numbers of nodes.



Example (see end) where results2 holds about 3600 childNodes:



Node newResults1 = doc.importNode(results2, true);

results1.getParentNode().appendChild(newResults1);

Node newResults2 = doc.importNode(results2, true);

results1.getParentNode().appendChild(newResults2);

Node newResults3 = doc.importNode(results2, true);

results1.getParentNode().appendChild(newResults3);



I'm calling this in a struts action of a web application and during the
third importNode call, some kind of error occurs. When debugging there's no
exception.The instruction pointer just vanishes into thin air.



However, if I create a XML file containing the above and then load it, there
's no error. Although there could be other reasons, this little experiment
indicates that something is not working properly in the Oracle XML parser.





Lars

----------------------------------------------------------------------------
------------



In the experiment above I'm just appending results as siblings so the end
result should be:



<root>

<results>

<sections>
<section source="doc1"/>
<section source="doc1"/>
</sections>

</results>

<results>

<sections>
<section source="doc2"/>
<section source="doc2"/>
</sections>

</results>

<results>

<sections>
<section source="doc2"/>
<section source="doc2"/>
</sections>

</results>

<results>

<sections>
<section source="doc2"/>
<section source="doc2"/>
</sections>

</results>
</root>
 
T

TechBookReport

Thanks for the suggestions. I have to think of an alternative since Oracle's
parses doesn't seem to be able to handle large numbers of nodes.



Example (see end) where results2 holds about 3600 childNodes:



Node newResults1 = doc.importNode(results2, true);

results1.getParentNode().appendChild(newResults1);

Node newResults2 = doc.importNode(results2, true);

results1.getParentNode().appendChild(newResults2);

Node newResults3 = doc.importNode(results2, true);

results1.getParentNode().appendChild(newResults3);



I'm calling this in a struts action of a web application and during the
third importNode call, some kind of error occurs. When debugging there's no
exception.The instruction pointer just vanishes into thin air.



However, if I create a XML file containing the above and then load it, there
's no error. Although there could be other reasons, this little experiment
indicates that something is not working properly in the Oracle XML parser.





Lars

----------------------------------------------------------------------------
------------



In the experiment above I'm just appending results as siblings so the end
result should be:



<root>

<results>

<sections>
<section source="doc1"/>
<section source="doc1"/>
</sections>

</results>

<results>

<sections>
<section source="doc2"/>
<section source="doc2"/>
</sections>

</results>

<results>

<sections>
<section source="doc2"/>
<section source="doc2"/>
</sections>

</results>

<results>

<sections>
<section source="doc2"/>
<section source="doc2"/>
</sections>

</results>
</root>


I think you should look at an earlier suggestion in this thread and
try using XSLT. You can use the document() function in the XSL sheet
to create a union of the node sets from both your documents. You can
then use a template match to grab the section nodes and copy them to
your output document.

I think the O'Reilly book 'Learning XSLT' (reviewed here
http://www.techbookreport.com/tbr0070.html), covers this sort of thing
really well. There's even some Java code in an appendix that might be
useful.

HTH
Pan
====================================
TechBookReport : http://www.techbookreport.com
 
Joined
Jan 16, 2016
Messages
1
Reaction score
0
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class xmlcopy {

public static void main(String[] args)
throws ParserConfigurationException, SAXException, IOException, TransformerException {
File input = new File("C:\\Users\\Admin\\Desktop\\catalo.xml");
File file = new File("C:\\Users\\Admin\\Desktop\\new.html");
if (file.createNewFile()) {
System.out.println("File is created!");
} else {
file.delete();
System.out.println("File already exists.");
file.createNewFile();
System.out.println("File is created!");
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder dbbuilder = factory.newDocumentBuilder();
Document doc = dbbuilder.parse(input);
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("author");
System.out.println("----------------------------");
int size = nList.getLength();
System.out.println(size);
Element element = (Element) nList.item(0);
/*
* Document doc2=factory.newDocumentBuilder().parse(new
* File("C:\\Users\\Admin\\Desktop\\new.xml")); Node
* dup=doc2.importNode(element,true);
* doc2.getDocumentElement().appendChild(dup);
*/
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc.importNode(element, true));
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
System.out.println("File saved!");
}

}
this works
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,832
Latest member
GlennSmall

Latest Threads

Top