xml解析之1--SAX解析(转)

    

一、        前言

 

 

 

 

Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单APISimple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object Module)称为DOMSun公司提供了Java API for XML ParsingJAXP)接口来使用SAXDOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。

JAXP接口包含了三个包:

(1)       org.w3c.dom  W3C推荐的用于XML标准规划文档对象模型的接口。

(2)       org.xml.sax   用于对XML进行语法分析的事件驱动的XML简单APISAX

(3)       javax.xml.parsers解析器工厂工具,程序员获得并配置特殊的特殊语法分析器。

二、        前提

 

 

 

 

DOM编程不要其它的依赖包,因为JDK里自带的JDK里含有的上面提到的org.w3c.domorg.xml.sax javax.xml.parsers包就可以满意条件了。

三、        使用SAX解析XML文档

 

 

 

 

SAX是基于事件的简单API,同样的我们也是用一个最简单的例子来看看SAX是如何解析XML

先来看看我们要解析的XML代码吧

<?xml version="1.0" encoding="gb2312"?>

<books>
  <book email="zhoujunhui">
        <name addr="address">rjzjh</name>
       <price>jjjjjj</price>
 </book>
</books>

 

 

 

 

 

 

简单的不能再简单了。但是该有的都有了,根元素、属性、子节点。好了,能反应问题就行了,下面来看看解析这个XML文件的Java代码吧!

 public class SaxParse {

     public SaxParse(){       

     SAXParserFactory saxfac=SAXParserFactory.newInstance();

          try {

                  SAXParser saxparser=saxfac.newSAXParser();

                 InputStream is=new FileInputStream("bin/library.xml");

                  saxparser.parse(is,new MySAXHandler());

           } catch (ParserConfigurationException e) {

                 e.printStackTrace();

           } catch (SAXException e) {

                  e.printStackTrace();

           } catch (FileNotFoundException e) {

                  e.printStackTrace();

           } catch (IOException e) {

                  e.printStackTrace();

           }

    }

    public static void main(String[] args) {

           new SaxParse();

   }

  }

 这段代码比较短,因为

SAX 是事件驱动的,它的大部分实现在在另一个 Java 文件中,先别管另一个文件,我们来一个个地分析吧!

SAX是事件驱动的,它的大部分实现在在另一个Java文件中,先别管另一个文件,我们来一个个地分析吧!

 

 

1)得到SAX解析器的工厂实例

3         SAXParserFactory saxfac=SAXParserFactory.newInstance();

这是一个javax.xml.parsers.SAXParserFactory类的实例

2)从SAX工厂实例中获得SAX解析器

5          SAXParser saxparser=saxfac.newSAXParser();

使用javax.xml.parsers.SAXParserFactory工厂的newSAXParser()方法

3)把要解析的XML文档转化为输入流,以便DOM解析器解析它

6                InputStream is=new FileInputStream("bin/library.xml");

InputStream是一个接口。

4)解析XML文档

7                 saxparser.parse(is,new MySAXHandler());

后面就不用看了,都是些没用的代码(相对而言),够简单的吧!

注意了,我们新建了一个实例new MySAXHandler()这个实例里面又有什么东西呢?

这个实例就是SAX的精华所在。我们使用SAX解析器时,必须实现内容处理器ContentHandler接口中的一些回调方法,然而我们不须要全部地实现这些方法,还好,我们有org.xml.sax.helpers.DefaultHandler类,看它的类申明:

public class DefaultHandler

implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler

实现了这么多接口啊,其它的先不管了,至少它实现了ContentHandler这一接口。

好了,看看这个类有些什么吧?下面是它的Java代码!


public class MySAXHandler extends DefaultHandler {

       boolean hasAttribute=false;

       Attributes attributes=null;

       /* (非 Javadoc)

        * @see org.xml.sax.helpers.DefaultHandler#startDocument()

        */

       public void startDocument() throws SAXException {

               System.out.println("文档开始打印了");

       }

       /* (非 Javadoc)

        * @see org.xml.sax.helpers.DefaultHandler#endDocument()

        */

       public void endDocument() throws SAXException {

              System.out.println("文档打印结束了");

       }

       /* (非 Javadoc)

        * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)

        */

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

                     Attributes attributes) throws SAXException {

              if(qName.equals("books")){

                     return;

              }

              if(qName.equals("book")){

                     System.out.println(attributes.getQName(0)+attributes.getValue(0));

              }

              if(attributes.getLength()>0){

                     this.attributes=attributes;

                     this.hasAttribute=true;

              }

       }

       /* (非 Javadoc)

        * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)

        */

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

                     throws SAXException {

              if(hasAttribute&&(attributes!=null)){

                     for(int i=0;i<attributes.getLength();i++){

                            System.out.println(attributes.getQName(0)+attributes.getValue(0));

                     }

              }

       }

       /* (非 Javadoc)

        * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)

        */

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

                     throws SAXException {

              System.out.println(new String(ch,start,length));

       }

}

 

 

不要看它一大堆,我一一分解给大家看。我们说SAX是基于事件的API,我们这个类实到了ContentHandler接口中的如下方法:

1startDocument()  用于处理文档解析开始事件

     public void startDocument() throws SAXException {

               System.out.println("文档开始打印了");

        }

2endDocument()  用于处理文档解析结束事件

      public void endDocument() throws SAXException {

              System.out.println("文档打印结束了");

        }

3startElement  用于处理元素开始事件

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

                     Attributes attributes) throws SAXException {

              if(qName.equals("books")){

                     return;

              }

              if(qName.equals("book")){

                     System.out.println(attributes.getQName(0)+attributes.getValue(0));

              }

              if(attributes.getLength()>0){

                     this.attributes=attributes;

                     this.hasAttribute=true;

              }

       }

第二个参数String qName表示这个元素的名字,如:

根节点  <books></books>  它的qName为“books

最底层节点 <price>jjjjjj</price> 它的qName为“price

知道这一点上面程序就好解释了,当遇到根元素“books”时就什么也不做跳过,当遇到“book”元素时就打出它的属性(它只有一个属性<book email="zhoujunhui"></book>)。

当是其它节点时(这下只剩下最底层的两个节点“name”和“price”了),就把它的属性取出来存到this.attributes域中,以后中元素结束事件好处理。

4endElement  用于处理元素结束事件

    

 

代码的作用是如果这个元素的属性不为空(hasAttribute&&(attributes!=null)),就把它们打印出来。

 

5characters(char[] ch, int start, int length) 处理元素字符的内容

       

   

 

我们只用了这么几个事件,其它还有其的的一些事件,我们只要看一下ContentHandler这个接口就行了,如:

 

6startPrefixMapping(String prefix,String URI)  处理前缀映射开始事件,参数表示前缀名称和所指向的URI

7endPrefixMapping(String prefix,String URI)  处理前缀映射结束事件,参数表示前缀名称和所指向的URI

8ignorableWhitespace(Char[] ch,int start,int length)  处理元素中可忽略的空格

9processingInstruction(String target,String data)  处理解析中产生的处理指令事件。

至此SAX解析XML文档的大概介绍完了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值