Ошибка переполнения стека при использовании SAX Parser в Java - PullRequest
2 голосов
/ 30 июня 2011

поэтому мы с другом работаем над этим проектом, и мы пытались выяснить, как извлечь значения из отдельных текстовых узлов в файле XML.Он смог придумать немного кода, который извлекает искомые текстовые узлы, но есть одна небольшая проблема.Когда я запускаю следующий код, он работает нормально и извлекает то, что нам нужно ...

КОД JAVA

import java.io.File;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class Test extends DefaultHandler 
{
    StringBuffer buffer;
    String heading;
    boolean inHeading;

    public static void main(String[] args)
    {
        try
        {
            Test saxNames = new Test();
            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();

            parser.parse(new File("C:/Documents and Settings/user/workspace/Intern Project/Proposals/Converted Proposals/Extracted Items/ProposalOne.docx - Extracted Items/word/document.xml"), saxNames);

        }
        catch(Exception e)
        {
            e.printStackTrace(System.err);
        }
    }

    public void startElement(String uri, String localName, String qName, Attributes attrs)
    {
        if ("w:pStyle".equals(qName))
        {
            String val = attrs.getValue("w:val");

            if (val.contains("Heading"))
            {
                if (isHeading(val))
                {
                    System.out.println(val);
                    inHeading = true;
                }
            }
        }



        if("w:t".equals(qName))
        {
            String val = attrs.getValue("w:t");
            if (inHeading == true)
            {
                buffer = new StringBuffer();
            }
        } 
    }

    public void characters(char buff[], int offset, int length) throws SAXException
    {
        String s = new String(buff, offset, length);

        if(buffer != null)
        {
            buffer.append(s);
            heading = heading += s;
        }   
    }

    public void endElement(String uri, String localName, String qName)
    {
        buffer = null; 

        if ("w:p".equals(qName) && inHeading == true)
        {       
            System.out.println(heading);        

            heading = "";
            inHeading = false;      
        }   
    }

    private static boolean isHeading(String heading)
    {
        String headingNumber = heading.substring(7,8);
        String headingName = heading.substring(0,7);

        if (headingName.equals("Heading"))
        {
            if (headingNumber.equals("1") 
                    || headingNumber.equals("2")
                    || headingNumber.equals("3")
                    || headingNumber.equals("4")
                    || headingNumber.equals("5")
                    || headingNumber.equals("6"))
            {
                return true;
            }
        }

        return false; 
    }
}

Однако, поскольку это только частьВ более крупном проекте, над которым мы работаем, я хочу включить это в класс водителя.Таким образом, я хочу иметь возможность превратить основной метод здесь в конструктор, и поэтому, когда я изменяю ...

public static void main(String[] args)
        {
            try
            {
                Test saxNames = new Test();
                SAXParser parser = SAXParserFactory.newInstance().newSAXParser();

                parser.parse(new File("C:/Documents and Settings/user/workspace/Intern Project/Proposals/Converted Proposals/Extracted Items/ProposalOne.docx - Extracted Items/word/document.xml"), saxNames);

            }
            catch(Exception e)
            {
                e.printStackTrace(System.err);
            }
        }

на ....

public Test()
        {
            try
            {
                Test saxNames = new Test();
                SAXParser parser = SAXParserFactory.newInstance().newSAXParser();

                parser.parse(new File("C:/Documents and Settings/user/workspace/Intern Project/Proposals/Converted Proposals/Extracted Items/ProposalOne.docx - Extracted Items/word/document.xml"), saxNames);

            }
            catch(Exception e)
            {
                e.printStackTrace(System.err);
            }
        }

И когда я пытаюсь запустить это из моего драйвера, я получаю следующую ошибку ....

Exception in thread "main" java.lang.StackOverflowError
    at Test.<init>(Test.java:17)
    at Test.<init>(Test.java:17)
    at Test.<init>(Test.java:17)
    at Test.<init>(Test.java:17)
    at Test.<init>(Test.java:17)
        .
        .
        .
    at Test.<init>(Test.java:17)

Понятия не имею, почему он это делает.Просматривая код, я думаю, что у меня есть представление о том, откуда возникла ошибка.Внутри конструктора он создает экземпляр другого конструктора с тем же именем ---> Следовательно, почему он работает в методе main.Однако я не совсем уверен, как решить эту проблему?

Ответы [ 2 ]

5 голосов
/ 30 июня 2011

Вы создаете новый экземпляр Test, каждый раз, когда вы создаете экземпляр Test. Видите ошибку?

Сделайте это вместо этого в своем предложении try:

// DON'T DO THIS: Test saxNames = new Test();

SAXParser parser = SAXParserFactory.newInstance().newSAXParser();

parser.parse(new File("blabla_filename.xml"), this);
3 голосов
/ 30 июня 2011

В вашем конструкторе вы вызываете ваш конструктор ...

public Test () { пытаться { Test saxNames = new Test (); ...

...