简体   繁体   English

在 Java 中使用 SAX 解析器的堆栈溢出错误

[英]Stack Overflow Error Using SAX Parser in Java

so a friend and I are working on this project and we'd been trying to figure out how to pull out the values from individual text nodes within an XML file.所以我和一个朋友正在做这个项目,我们一直在试图弄清楚如何从 XML 文件中的各个文本节点中提取值。 He was able to come up with a bit of code that extracts the text nodes we are looking for, but there is one slight problem.他能够想出一些代码来提取我们正在寻找的文本节点,但是有一个小问题。 When I run the following code, it works fine and extracts what we need...当我运行以下代码时,它可以正常工作并提取我们需要的内容......

JAVA CODE 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; 
    }
}

However, since this is only a portion of the larger project we are working on, I want to be able to incorporate this into a driver class.但是,由于这只是我们正在进行的更大项目的一部分,我希望能够将其合并到驱动程序 class 中。 Thus I want to be able to turn the main method here into a constructor, and so when I change...因此我希望能够将这里的 main 方法变成构造函数,所以当我改变时......

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

to....至....

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

And when I try to run this from my driver, I get the following error....当我尝试从我的驱动程序运行它时,我收到以下错误....

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)

I have no clue why it is doing this.我不知道它为什么这样做。 Looking over the code, I think I may have an idea of where the error is coming from.查看代码,我想我可能知道错误来自哪里。 Within the constructor, it instantiates another constructor by the same name ---> Hence why it works in the main method.在构造函数中,它用相同的名称实例化另一个构造函数 ---> 因此它在 main 方法中起作用。 However, I'm not really sure how to address that issue?但是,我不确定如何解决这个问题?

You create a new instance of Test, each time you create an instance of Test.每次创建 Test 实例时,都会创建一个新的 Test 实例。 See the error?看到错误了吗?

Do this instead in your try-statement:在您的尝试语句中执行此操作:

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

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

parser.parse(new File("blabla_filename.xml"), this);

In your constructor you are calling your constructor...在您的构造函数中,您正在调用构造函数...

public Test() { try { Test saxNames = new Test(); public Test() { try { 测试 saxNames = new Test(); ... ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM