XML SAX解析 附Java程序实例
发布日期:2021-05-09 05:16:46 浏览次数:19 分类:博客文章

本文共 7821 字,大约阅读时间需要 26 分钟。

 

XML解析之 SAX解析

 

SAX介绍

  SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。

  与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。

  当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口

  

  局限性:

  1. SAX分析器在对XML文档进行分析时,触发了一系列的事件,由于事件触发本身是有时序性的,因此,SAX提供的是一种顺序访问机制,对于已经分析过的部分,不能再倒回去重新处理。

  即,一旦经过了某个元素,我们没有办法返回去再去访问它。

  2. SAX分析器只做了一些简单的工作,大部分工作还要由应用程序自己去做。

  也就是说,SAX分析器在实现时,只是顺序地检查XML文档中的字节流,判断当前字节是XML语法中的哪一部分、是否符合XML语法,然后再触发相应的事件,而事件处理函数本身则要由应用程序自己来实现。

  同DOM分析器相比,SAX分析器缺乏灵活性。

  优势:

  然而,由于SAX分析器实现简单,对内存要求比较低,(SAX不必将整个XML文档加载到内存当中,因此它占据内存要比DOM小), 因此实现效率比较高。

  对于大型的XML文档来说,通常会用SAX而不是DOM。

  并且对于那些只需要访问XML文档中的数据而不对文档进行更改的应用程序来说,SAX分析器更为合适。

 

SAX分析器

 

 

 

  XML解析器实际上就是一段代码,它读入一个XML文档并分析其结构。

 

  分类:

  带校验的解析器

  不校验的解析器(效率高)

  支持DOM的解析器(W3C的官方标准)

  支持SAX的解析器(事实上的工业标准)

 

  SAX是事件驱动的,文档的读入过程就是SAX的解析过程。

  在读入的过程中,遇到不同的项目,解析器会调用不同的处理方法。

 

SAX解析实例

  以一个xml文档为例:

 

Harry Potter
J K. Rowling
2005
29.99
Everyday Italian
Giada De Laurentiis
2005
30.00
Learning XML
Erik T. Ray
2003
39.95
XQuery Kick Start
James McGovern
Per Bothner
Kurt Cagle
James Linn
Vaidyanathan Nagarajan
2003
49.99

 

  用SAX解析这个文档的Java代码:

package com.example.xml.sax;import java.io.File;import java.util.Arrays;import java.util.Stack;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;/** * SAX解析XML * 查看事件调用 * */public class SaxTest1{    public static void main(String[] args) throws Exception    {        // step 1: 获得SAX解析器工厂实例        SAXParserFactory factory = SAXParserFactory.newInstance();        // step 2: 获得SAX解析器实例        SAXParser parser = factory.newSAXParser();        // step 3: 开始进行解析        // 传入待解析的文档的处理器        parser.parse(new File("books.xml"), new MyHandler());    }}class MyHandler extends DefaultHandler{    // 使用栈这个数据结构来保存    private Stack
stack = new Stack
(); @Override public void startDocument() throws SAXException { System.out.println("start document -> parse begin"); } @Override public void endDocument() throws SAXException { System.out.println("end document -> parse finished"); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("start element-----------"); System.out.println(" localName: " + localName); System.out.println(" qName: " + qName); } @Override public void characters(char[] ch, int start, int length) throws SAXException { System.out.println("characters-----------"); // System.out.println(" ch: " + Arrays.toString(ch) ); System.out.println(" ch: " + ch); System.out.println(" start: " + start); System.out.println(" length: " + length); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("end element-----------"); System.out.println(" localName: " + localName); System.out.println(" qName: " + qName); }}

  解析程序第二版:

package com.example.xml.sax;import java.io.File;import java.util.Stack;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;/** * SAX解析XML *  */public class SaxTest2{    public static void main(String[] args) throws Exception    {        // step 1: 获得SAX解析器工厂实例        SAXParserFactory factory = SAXParserFactory.newInstance();        // step 2: 获得SAX解析器实例        SAXParser parser = factory.newSAXParser();        // step 3: 开始进行解析        // 传入待解析的文档的处理器        parser.parse(new File("books.xml"), new MySAXHandler());    }}class MySAXHandler extends DefaultHandler{    // 使用栈这个数据结构来保存    private Stack
stack = new Stack
(); // 数据 private String title; private String author; private String year; private double price; @Override public void startDocument() throws SAXException { System.out.println("start document -> parse begin"); } @Override public void endDocument() throws SAXException { System.out.println("end document -> parse finished"); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // System.out.println("start element-----------"); // System.out.println(" localName: " + localName); // System.out.println(" qName: " + qName); // 将标签名压入栈 stack.push(qName); // 处理属性 for (int i = 0; i < attributes.getLength(); ++i) { String attrName = attributes.getQName(i); String attrValue = attributes.getValue(i); System.out.println("属性: " + attrName + "=" + attrValue); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { // System.out.println("characters-----------"); // System.out.println(" ch: " + Arrays.toString(ch) ); // System.out.println(" ch: " + ch); // System.out.println(" start: " + start); // System.out.println(" length: " + length); // 取出标签名 String tag = stack.peek(); if ("title".equals(tag)) { title = new String(ch, start, length); } else if ("author".equals(tag)) { author = new String(ch, start, length); } else if ("year".equals(tag)) { year = new String(ch, start, length); } else if ("price".equals(tag)) { price = Double.parseDouble(new String(ch, start, length)); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // System.out.println("end element-----------"); // // System.out.println(" localName: " + localName); // System.out.println(" qName: " + qName); stack.pop();// 表示该元素解析完毕,需要从栈中弹出标签 if ("book".equals(qName)) { System.out.println("Book info: -------"); System.out.println(" title: " + title); System.out.println(" author: " + author); System.out.println(" year: " + year); System.out.println(" price: " + price); System.out.println(); } }}
SaxTest2

  SaxTest2程序输出:

start document -> parse begin属性: category=children属性: lang=enBook info: -------    title: Harry Potter    author: J K. Rowling    year: 2005    price: 29.99属性: category=cooking属性: lang=enBook info: -------    title: Everyday Italian    author: Giada De Laurentiis    year: 2005    price: 30.0属性: category=web属性: lang=enBook info: -------    title: Learning XML    author: Erik T. Ray    year: 2003    price: 39.95属性: category=web属性: lang=enBook info: -------    title: XQuery Kick Start    author: Vaidyanathan Nagarajan    year: 2003    price: 49.99end document -> parse finished
Console output

 

参考资料

  圣思园张龙老师XML教学视频。

  Java API文档:

 

上一篇:Java XML解析工具 JDOM介绍及使用实例
下一篇:XML的DOM解析 Java实现 使用递归解析一个XML文档

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2025年04月04日 04时22分18秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章