java sax解析_SAX文档解析、Java用SAX解析XML

f088cae845f99e5181711330d91a9a0c.png

类型:下载工具大小:828KB语言:中文 评分:7.5

标签:

立即下载

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 Allen

5 男

6 20

7

8

9 namy

10 女

11 18

12

13

14 lufy

15 男

16 18

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 map=null;

18     //存储所有解析的元素的数据

19     private List> list=null;

20     //正在解析的元素的名字

21     String currentTag=null;

22     //正在解析的元素的元素值

23     String currentValue=null;

24     //解析的XML文档中要获取数据的元素标签

25     String nodeName=null;

26

27

28     public Myhandler(String nodeName) {

29         // TODO Auto-generated constructor stub

30         this.nodeName=nodeName;

31     }

32

33     public List> getList() {

34         return list;

35     }

36

37     //开始解析文档,即开始解析根元素时调用该方法

38     @Override

39     public void startDocument() throws SAXException {

40         // TODO Auto-generated method stub

41         System.out.println("--startDocument()--");

42         //初始化Map

43         list=new ArrayList>();

44     }

45

46     //开始解析每个元素时都会调用该方法

47     @Override

48     public void startElement(String uri, String localName, String qName,

49             Attributes attributes) throws SAXException {

50         // TODO Auto-generated method stub

51         //判断正在解析的元素是不是要获取数据的元素标签

52         System.out.println("--startElement()--"+qName);

53         if(qName.equals(nodeName)){

54             map=new HashMap();

55         }

56

57         //判断正在解析的元素是否有属性值,如果有则将其全部取出并保存到map对象中,如:

58         if(attributes!=null&&map!=null){

59             for(int i=0;i

60                 map.put(attributes.getQName(i), attributes.getValue(i));

61             }

62         }

63         currentTag=qName;  //正在解析的元素

64     }

65

66     //解析到每个元素的内容时会调用此方法

67     @Override

68     public void characters(char[] ch, int start, int length)

69             throws SAXException {

70         // TODO Auto-generated method stub

71         System.out.println("--characters()--");

72         if(currentTag!=null&&map!=null){

73             currentValue=new String(ch,start,length);

74             //如果内容不为空和空格,也不是换行符则将该元素名和值和存入map中

75             if(currentValue!=null&&!currentValue.trim().equals("")&&!currentValue.trim().equals("\n")){

76                 map.put(currentTag, currentValue);

77                 System.out.println("-----"+currentTag+" "+currentValue);

78             }

79             //当前的元素已解析过,将其置空用于下一个元素的解析

80             currentTag=null;

81             currentValue=null;

82         }

83     }

84

85     //每个元素结束的时候都会调用该方法

86     @Override

87     public void endElement(String uri, String localName, String qName)

88             throws SAXException {

89         // TODO Auto-generated method stub

90         System.out.println("--endElement()--"+qName);

91         //判断是否为一个节点结束的元素标签

92         if(qName.equals(nodeName)){

93             list.add(map);

94             map=null;

95         }

96     }

97

98     //结束解析文档,即解析根元素结束标签时调用该方法

99     @Override

100     public void endDocument() throws SAXException {

101         // TODO Auto-generated method stub

102         System.out.println("--endDocument()--");

103         super.endDocument();

104     }

105 }

用于解析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> ReadXML(String uri,String NodeName){

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> list=(ArrayList>) SaxService.ReadXML("M:\\XML\\Demo\\myClass.xml","class");

22         /*for(int i=0;i

23             HashMap temp=(HashMap) list.get(i);

24                 Iterator iterator=temp.keySet().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()方法只会在文档解析结束的时候被调用,每次解析只会调用一次。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值