I am using the following code for parsing of small xml files and it is working successfully. But when I parse huge data files I am getting a stack overflow error. So, I decided to convert this method into an iterative style. Initially when writing this method, I created the logic and wrote it successfully though when converting to an iterative style I’ve become completely lost and I’m not getting the required output. This is my recursive code:
private void xmlParsing(Node node,int indent) throws IOException {
if (node.hasChildNodes()) {
Node firstChild=node.getFirstChild();
xmlParsing(firstChild,indent+1);
} else {
System.out.println(node.getNodeName()+":"+node.getNodeValue()+":"+indent);
}
Node nextNode=node.getNextSibling();
if (nextNode!=null) {
xmlParsing(nextNode,indent);
}
}
Can someone please help me to convert this to iterative function that will perform this logic under single function? I hope I have made a clear request.
My full code:
package sample;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class NewTestClass {
private Document doc = null;
public NewTestClass() {
BufferedWriter br=null;
try {
doc = parserXML(new File("debug.xml"));
br=new BufferedWriter(new FileWriter("xmldata.txt"));
xmlParsing(doc, 0,br);
} catch(Exception error) {
error.printStackTrace();
} finally {
try {
br.flush();
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void xmlParsing(Node node,int indent,BufferedWriter br) throws IOException {
if (node.hasChildNodes()) {
Node firstChild=node.getFirstChild();
xmlParsing(firstChild,indent+1,br);
} else {
br.write(node.getNodeName()+":"+node.getNodeValue()+":"+indent);
br.newLine();
}
Node nextNode=node.getNextSibling();
if (nextNode!=null) {
xmlParsing(nextNode,indent,br);
}
}
public Document parserXML(File file) throws SAXException, IOException, ParserConfigurationException
{
return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
}
public static void main(String[] args)
{
new NewTestClass();
}
}
My initial error:
Exception in thread "main" java.lang.StackOverflowError
at com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.getNodeValueString(Unknown Source)
at com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.getNodeValueString(Unknown Source)
at com.sun.org.apache.xerces.internal.dom.DeferredTextImpl.synchronizeData(Unknown Source)
at com.sun.org.apache.xerces.internal.dom.CharacterDataImpl.getNodeValue(Unknown Source)
Your problem is the fact that you recurse also for siblings, not only for children. Child recursion is perfectly OK, but in your case, recursion goes as deep as the number of (flattened) nodes (not only elements) in your document.
Do this instead: