XML学习05-Java中SAX方式解析XML文件

来源:互联网 发布:国外视频软件 编辑:程序博客网 时间:2024/05/18 13:28

一、什么是SAX方式

-SAX: Simple API for XML。属于开源社区XML-DEV,几乎所有的XML解析器都支持它。
-相比于DOM方式,SAX方式更为迅速,占用内存资源更少。

二、Java中使用SAX方式解析XML的原理

-DOM方式与SAX方式的区别:DOM方式解析之前要将整个XML文档读入,在内存中产生一个DOM树;而SAX方式解析是逐行扫描文档,边扫描边进行解析,不必等到整个文档装载完才进行操作。
-Java中SAX解析XML的方式:SAX解析方式是基于事件驱动(一种基于回调(callback)机制的程序运行方法)的,利用SAX解析XML涉及解析器和事件处理器两个部分。

a.解析器:对XML文档逐行进行解析,只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的XML文件内容作为方法的参数传递给事件处理器。b.事件处理器:由程序员编写,决定对从解析器解析到的数据如何做处理。

-解析原理:
XML文档——解析器逐行解析——>解析到元素——-调用相应的时间处理方法——>处理解析到的数据——-继续解析下一行——>……

三、具体的Java代码实现

1.创建解析器,处理器,加载XML文档;2.内容处理的几个主要方法;3.取出特定元素的内容;4.将XML中的信息全部输出

待解析的XML代码:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><联系人列表>    <联系人>        <姓名>张三</姓名>        <EMAIL>zhang3@gmail.com</EMAIL>        <年龄>30</年龄>    </联系人>    <联系人>        <姓名>李四</姓名>        <EMAIL>li4@163.com</EMAIL>        <年龄>31</年龄>    </联系人></联系人列表>

1.创建解析器,处理器,加载XML文档

//创建sax解析器SAXParser sax = SAXParserFactory.newInstance().newSAXParser();//获取内容读取器XMLReader xml = sax.getXMLReader();//注册一个内容处理器xml.setContentHandler(new DefaultHandler(){});//重写DefaultHandler接口中的方法来处理解析到的内容//加载XML文档xml.parse("src/j2ee/dom/linkman.xml");

2.内容处理用到的几个主要方法(DefaultHandler 接口中)

i.startDocument() 方法说明:在解析整个文档开始时自动调用,重写此方法可以在解析文档开始时做特定处理。ii.endDocument() 方法说明:在解析整个文档结束时自动调用,重写此方法可以在解析整个文档结束时做处理。iii.startElement(String uri, String localName, String qName, Attributes attributes) 参数说明:URL,本地名称,当前解析到的元素名称,元素附加的属性方法说明:在解析到元素节点时自动调用,重写此方法可以在解析到元素节点时做相应处理。iv.endElement(String uri, String localName, String qName) 参数说明:URL,本地名称,当前结束解析的元素名称方法说明:在解析到元素节点结束标签时自动调用,重写此方法可以在解析元素节点结束时做相应处理。v.characters(char[] ch, int start, int length)参数说明:XML文档内容的字符数组,当前解析到的元素在字符数组的起始位置,当前解析到的元素所占长度方法说明:在解析完元素标签方法结束后自动调用,重写此方法可以对在此元素内读取到的相应内容做处理。

解析时方法调用的流程:由startDocument开始,在endDocument结束,中间三个按顺序反复调用

startDocument()---->sartElement()---->characters()---->endElement()---->sartElement()---->characters()---->endElement()---->......--->endDocument()

3.取出特定元素的内容(取出XML中第二个联系人的姓名,运行结果输出“李四”)

//创建sax解析器SAXParser sax = SAXParserFactory.newInstance().newSAXParser();//获取内容读取器XMLReader xml = sax.getXMLReader();//注册一个内容处理器xml.setContentHandler(new DefaultHandler(){    String curname = "";//记录当前的元素名    int count = 0;//记录当前取到的是第几个联系人    @Override    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {        if(qName.equals("姓名")){            curname = "姓名";//只关注“姓名”元素            count++;        }    }    @Override    public void endElement(String uri, String localName, String qName) throws SAXException {        curname="";//一个元素解析结束后应清空记录的当前元素名    }    @Override    public void characters(char[] ch, int start, int length) throws SAXException {        if("姓名".equals(curname)&&count==2){  //拿到了第二个联系人的姓名            System.out.println(new String(ch,start,length));        }    }});//加载XML文档xml.parse("src/j2ee/dom/linkman.xml");

4.将XML中的信息全部输出(定义一个linkman类封装信息,此处忽略linkman类的代码之关注主要代码)

List<Linkman> men = new ArrayList<Linkman>();//定义一个容器来存放解析到的联系人对象//创建sax解析器SAXParser sax = SAXParserFactory.newInstance().newSAXParser();//获取内容读取器XMLReader xml = sax.getXMLReader();//注册一个内容处理器xml.setContentHandler(new DefaultHandler(){    Linkman man;//联系人对象    String curname = "";//记录当前解析的元素名    @Override    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {        if(qName.equals("联系人")){            man = new Linkman();//当解析到联系人元素时new一个新的联系人对象        }        curname = qName;    }    @Override    public void endElement(String uri, String localName, String qName) throws SAXException {        if(qName.equals("联系人")){ //当一个联系人元素解析完成时,将这个联系人对象添加到容器中            men.add(man);        }        curname="";    }    @Override    public void characters(char[] ch, int start, int length) throws SAXException {        if("姓名".equals(curname)){             man.setName(new String(ch,start,length));//若当前解析的是姓名元素,则将姓名的内容添加给联系人对象        }        if("EMAIL".equals(curname)){            man.setEmail(new String(ch,start,length));//若当前解析的是EMAIL元素,则将Email内容添加给联系人对象        }        if("年龄".equals(curname)){            man.setAge(Integer.parseInt(new String(ch,start,length)));//若当前解析的是年龄元素,则将年龄内容添加给联系人对象        }    }});//加载XML文档xml.parse("src/j2ee/dom/book.xml");for (Linkman tmp: men ) {    System.out.println(tmp.toString());}

输出结果如下:(成功将XML中全部信息解析)

张三--zhang3@gmail.com--30李四--li4@163.com--31