2011-12-29 2 views
2

Я использую следующий код для синтаксического анализа небольших xml-файлов, и он работает успешно. Но когда я разбираю огромные файлы данных, я получаю ошибку переполнения стека. Итак, я решил преобразовать этот метод в итеративный стиль. Изначально при написании этого метода я создал логику и написал ее успешно, хотя при преобразовании в итеративный стиль я полностью потерялся, и я не получаю требуемый вывод. Это мой рекурсивный код:Как преобразовать рекурсивную функцию в итеративную функцию в java?

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); 
    } 
} 

Может кто-то пожалуйста, помогите мне, чтобы преобразовать это в итерационной функции, которая будет выполнять эту логику под одной функции? Надеюсь, я сделал четкую просьбу.

Мой полный код:

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(); 
    } 
} 

Моя первая ошибка:

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) 
+3

Вам нужна коллекция для хранения все вложенного состояния. –

+2

@PeterLawrey: Не обязательно. Я уверен, что «StackOverflowError» возникает из-за рекурсии для братьев и сестер, которые легко могут быть преобразованы в итерацию ... –

ответ

3

Ваша проблема заключается в том, что вы рекурсию также для братьев и сестер, а не только для детей. Рекурсия ребёнка в порядке, но в вашем случае рекурсия идет так же глубоко, как количество (сплющенных) узлов (а не только элементов) в вашем документе.

ли это вместо:

private void xmlParsing(Node node, int indent) throws IOException { 

    // iterate for siblings 
    while (node != null) { 

     // recurse for children 
     if (node.hasChildNodes()) { 
      Node firstChild = node.getFirstChild(); 
      xmlParsing(firstChild, indent + 1); 
     } else { 
      // do the leaf node action 
     } 

     node = node.getNextSibling(); 
    } 
} 
1

Я думаю, что у вас есть огромный уровень вложенности тегов. можете ли вы разместить образец XML-файла?

Если я правильно понимаю, вы пытаетесь преобразовать xml в текстовый файл с определенным форматом. Если это требование, я бы предложил вам использовать XSL с XML для перевода. Это очень легко и гибко.

Вы можете найти пример в http://speakingjava.blogspot.com/2011/07/how-to-use-xml-and-xsl-in-java.html

+0

В этом случае переход на XSL может быть чрезмерным, поскольку в простом представлении есть простое заблуждение алгоритм: рекурсия для братьев и сестер (вместо итерации над братьями и сестрами) –

+0

@ Прагалатан, Лукас прав. Мне нужно работать над простыми вещами..XSL - это новое знание .. и я не думаю, что это необходимо для меня. спасибо за ваше предложение .. – user1119970

+0

Спасибо Lukas и приветствуем user1119970 :) –

Смежные вопросы