使用SAX

使用DOM解析XML的优点是用起来省事,但它的主要缺点是内存占用太大。

另一种解析XML的方式是SAX。SAX是Simple API for XML的缩写,它是一种基于流的解析方式,边读取XML边解析,并以事件回调的方式让调用者获取数据。因为是一边读一边解析,所以无论XML有多大,占用的内存都很小。

SAX解析会触发一系列事件:

  • startDocument:开始读取XML文档;
  • startElement:读取到了一个元素,例如<book>
  • characters:读取到了字符;
  • endElement:读取到了一个结束的元素,例如</book>
  • endDocument:读取XML文档结束。

如果我们用SAX API解析XML,Java代码如下:

  1. InputStream input = Main.class.getResourceAsStream("/book.xml");
  2. SAXParserFactory spf = SAXParserFactory.newInstance();
  3. SAXParser saxParser = spf.newSAXParser();
  4. saxParser.parse(input, new MyHandler());

关键代码SAXParser.parse()除了需要传入一个InputStream外,还需要传入一个回调对象,这个对象要继承自DefaultHandler

  1. class MyHandler extends DefaultHandler {
  2. public void startDocument() throws SAXException {
  3. print("start document");
  4. }
  5. public void endDocument() throws SAXException {
  6. print("end document");
  7. }
  8. public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
  9. print("start element:", localName, qName);
  10. }
  11. public void endElement(String uri, String localName, String qName) throws SAXException {
  12. print("end element:", localName, qName);
  13. }
  14. public void characters(char[] ch, int start, int length) throws SAXException {
  15. print("characters:", new String(ch, start, length));
  16. }
  17. public void error(SAXParseException e) throws SAXException {
  18. print("error:", e);
  19. }
  20. void print(Object... objs) {
  21. for (Object obj : objs) {
  22. System.out.print(obj);
  23. System.out.print(" ");
  24. }
  25. System.out.println();
  26. }
  27. }

运行SAX解析代码,可以打印出下面的结果:

  1. start document
  2. start element: book
  3. characters:
  4. start element: name
  5. characters: Java核心技术
  6. end element: name
  7. characters:
  8. start element: author
  9. ...

如果要读取<name>节点的文本,我们就必须在解析过程中根据startElement()endElement()定位当前正在读取的节点,可以使用栈结构保存,每遇到一个startElement()入栈,每遇到一个endElement()出栈,这样,读到characters()时我们才知道当前读取的文本是哪个节点的。可见,使用SAX API仍然比较麻烦。

练习

下载练习:使用SAX解析XML (推荐使用IDE练习插件快速下载)

小结

SAX是一种流式解析XML的API;

SAX通过事件触发,读取速度快,消耗内存少;

调用方必须通过回调方法获得解析过程中的数据。

读后有收获可以支付宝请作者喝咖啡,读后有疑问请加微信群讨论

使用SAX - 图1使用SAX - 图2