SAX Parser是否将所有数据保存在内存中?

问题描述 投票:0回答:1

我正在研究一个需求,我需要拆分大XML并进一步处理。

这是XML Sample,它可以进入单行。

<?xml version="1.0"?><company><staff><firstname>yong</firstname><firstname>jin</firstname></staff></company>

这是我的代码:

import java.util.Arrays;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class ReadXML {

   public static void main(String argv[]) {

    try {

    SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser saxParser = factory.newSAXParser();

    DefaultHandler handler = new DefaultHandler() {

    boolean bfname = false;
    boolean blname = false;
    boolean bnname = false;
    boolean bsalary = false;

    public void startElement(String uri, String localName,String qName, 
                Attributes attributes) throws SAXException {

        System.out.println("Parameters :" + uri +":"+ localName +":"+ qName +":"+ attributes);
        System.out.println("Start Element :" + qName);

        if (qName.equalsIgnoreCase("FIRSTNAME")) {
            bfname = true;
        }

        if (qName.equalsIgnoreCase("LASTNAME")) {
            blname = true;
        }

        if (qName.equalsIgnoreCase("NICKNAME")) {
            bnname = true;
        }

        if (qName.equalsIgnoreCase("SALARY")) {
            bsalary = true;
        }

    }

    public void endElement(String uri, String localName,
        String qName) throws SAXException {

        System.out.println("End Element :" + qName);

    }

    public void characters(char[] ch, int start, int length) throws SAXException {

        System.out.println("Im here:"+Arrays.toString(ch));----Line 1
        if (bfname) {
            System.out.println("First Name : " + new String(ch, start, length));
            bfname = false;
        }

        if (blname) {
            System.out.println("Last Name : " + new String(ch, start, length));
            blname = false;
        }

        if (bnname) {
            System.out.println("Nick Name : " + new String(ch, start, length));
            bnname = false;
        }

        if (bsalary) {
            System.out.println("Salary : " + new String(ch, start, length));
            bsalary = false;
        }

    }

     };

       saxParser.parse("C:\\Lenny\\Work\\XML\\SaxParsing_01.xml", handler);



        /*InputSource input = new InputSource("C:\\Lenny\\Work\\XML\\SaxParsing_01.xml");
        System.out.println(input);
        XMLReader reader = saxParser.getXMLReader();
        reader.parse(input);*/


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

   }

}

我的第一个疑问是,SAXParser是否明智地读取字节?

其次,我希望我的输出像这样。

<firstname>yong</firstname>
<firstname>jin</firstname>

这件事我可以管理,但想知道......当我得到<firstname>标签并进入characters方法,为什么它打印所有整个XML?它不应该只在yong打印Line 1而不是打印整个XML吗?它打印全部,这就是为什么我在想,是不是SAXParser将整个数据保存在内存中?

有什么建议请..!

谢谢

java sax
1个回答
2
投票

SAX Parser是否将所有数据保存在内存中?

不,这就是重点。将XML文档的整个DOM数据加载到内存中,然后从中提取所需内容要比使用SAX繁琐的模型容易得多。

但SAX具有即时读取文档的好处,而无需将其完全加载到内存中。

我的第一个疑问是,SAXParser是否明智地读取字节?

不是字面的,没有。这将是非常低效的,特别是考虑到SAX的重点是操作大量文档。这是一个缓冲读取。这并不会消耗太多内存。

为什么要打印所有的整个XML?不应该只在第1行打印yong而不是打印整个XML吗?它的打印全部,这就是为什么我在想,SAXParser是否将整个数据保存在内存中?

如上所述,出于理智的表现原因,SAX使用缓冲区来读取。作为characters()方法的参数给出的char []大致是前面提到的缓冲区。

在您的示例中,您的文档很小,当然它完全适合用于读取文档的真实缓冲区。如果您使用较大的文档,您会注意到缓冲区包含数千个字符,但不在整个文档附近。

© www.soinside.com 2019 - 2024. All rights reserved.