SAX文档解析、Java用SAX解析XML
- 时间:2015年04月02日 15:27:28 来源:魔法猪系统重装大师官网 人气:15828
SAX最初是由DavidMegginson采用Java语言开发的,之后SAX很快在Java开发者中流行起来。SAN项目现在负责管理其原始API的开发工作,这是一种公开的、开放源代码软件。不同于其他大多数XML标准的是,SAX没有语言开发商必须遵守的标准SAX参考版本。因此,SAX的不同实现可能采用区别很大的接口。不过,所有的这些实现至少有一个特性是完全一样的,这就是事件驱动。
文档解析
在SAX解析器装载XML文件时,它遍历文件文档并在其主机应用程序中产生事件(经由回调函数、指派函数或者任何可调用平台完成这一功能)表示这一过程。这样,编写SAX应用程序就如同采用最现代的工具箱编写GUI程序。
大多数SAX实现都会产生以下若干类型的事件:
在文档的开始和结束时触发文档处理事件。
在文档内每一XML元素接受解析的前后触发元素事件。任何元数据通常都由单独的事件交付。
在处理文档的DTD或Schema时产生DTD或Schema事件。
错误事件用来通知主机应用程序解析错误。
显而易见,在处理文档时你最关心的就是元素事件了。通常,SAX解析器会向你的主机应用程序提供包含元素信息的事件参数;在最低程度下也会提供元素的名字。具体取决于你的特定实现,可以定义不同类型的元素事件代表不同类型元素的处理。例如,注释元素(它可能包含主机应用程序的处理指令)就经常在接受处理时产生特殊的事件。
要解析的XML文件:myClass.xml
1 <?xml version="1.0" encoding="utf-8"?>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
用SAX解析XML的Handler类:Myhandler.java
1 /**
2 * 用SAX解析XML的Handler
3 */
4 package com.xml.util;
5
6 import java.util.ArrayList;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10
11 import org.xml.sax.Attributes;
12 import org.xml.sax.SAXException;
13 import org.xml.sax.helpers.DefaultHandler;
14
15 public class Myhandler extends DefaultHandler {
16 //存储正在解析的元素的数据
17 private Map
18 //存储所有解析的元素的数据
19 private List
用于解析XML的业务类:SaxService.java
1 /**
2 * 封装解析业务类
3 */
4 package com.xml.service;
5
6 import java.io.InputStream;
7 import java.util.List;
8 import java.util.Map;
9
10 import javax.xml.parsers.SAXParser;
11 import javax.xml.parsers.SAXParserFactory;
12
13 import com.xml.util.Myhandler;
14
15 public class SaxService {
16
17 public static List
18 try {
19 //创建一个解析XML的工厂对象
20 SAXParserFactory parserFactory=SAXParserFactory.newInstance();
21 //创建一个解析XML的对象
22 SAXParser parser=parserFactory.newSAXParser();
23 //创建一个解析助手类
24 Myhandler myhandler=new Myhandler("stu");
25 parser.parse(uri, myhandler);
26 return myhandler.getList();
27 } catch (Exception e) {
28 e.printStackTrace();
29 }finally{
30
31 }
32 return null;
33
34 }
35 }
主程序入口:XmlSaxTest
1 /**
2 * 程序入口
3 */
4 package com.xml.sax;
5
6 import java.util.ArrayList;
7 import java.util.HashMap;
8 import java.util.Iterator;
9 import java.util.List;
10 import java.util.Map;
11
12 import com.xml.service.SaxService;
13
14 public class XmlSaxTest {
15
16 /**
17 * @param args
18 */
19 public static void main(String[] args) {
20 // TODO Auto-generated method stub
21 ArrayList
22 /*for(int i=0;i
24 Iterator
25 while(iterator.hasNext()){
26 String key=iterator.next().toString();
27 String value=temp.get(key);
28 System.out.print(key+" "+value+"--");
29 }
30 }*/
31 System.out.println(list.toString());
32 }
33
34 }
执行结果:
1 --startDocument()--
2 --startElement()--class
3 --characters()--
4 --startElement()--stu
5 --characters()--
6 --startElement()--name
7 --characters()--
8 -----name Allen
9 --endElement()--name
10 --characters()--
11 --startElement()--sex
12 --characters()--
13 -----sex 男
14 --endElement()--sex
15 --characters()--
16 --startElement()--age
17 --characters()--
18 -----age 20
19 --endElement()--age
20 --characters()--
21 --endElement()--stu
22 --characters()--
23 --startElement()--stu
24 --characters()--
25 --startElement()--name
26 --characters()--
27 -----name namy
28 --endElement()--name
29 --characters()--
30 --startElement()--sex
31 --characters()--
32 -----sex 女
33 --endElement()--sex
34 --characters()--
35 --startElement()--age
36 --characters()--
37 -----age 18
38 --endElement()--age
39 --characters()--
40 --endElement()--stu
41 --characters()--
42 --startElement()--stu
43 --characters()--
44 --startElement()--name
45 --characters()--
46 -----name lufy
47 --endElement()--name
48 --characters()--
49 --startElement()--sex
50 --characters()--
51 -----sex 男
52 --endElement()--sex
53 --characters()--
54 --startElement()--age
55 --characters()--
56 -----age 18
57 --endElement()--age
58 --characters()--
59 --endElement()--stu
60 --characters()--
61 --endElement()--class
62 --endDocument()--
63 [{id=001, sex=男, age=20, name=Allen}, {id=002, sex=女, age=18, name=namy}, {id=003, sex=男, age=18, name=lufy}]
分析:用SAX解析XML采用的是从上而下的基于事件驱动的解析方式,在解析过程中会视情况自动调用startDocument()、startElement()、characters()、endElement()、endDocument()等相关的方法。
由编译执行的结果来看:
startDocument()方法只会在文档开始解析的时候被调用,每次解析只会调用一次。
startElement()方法每次在开始解析一个元素,即遇到元素标签开始的时候都会调用。
characters()方法也是在每次解析到元素标签携带的内容时都会调用,即使该元素标签的内容为空或换行。而且如果元素内嵌套元素,在父元素结束标签前, characters()方法会再次被调用,此处需要注意。
endElement()方法每次在结束解析一个元素,即遇到元素标签结束的时候都会调用。
endDocument() startDocument()方法只会在文档解析结束的时候被调用,每次解析只会调用一次。