随笔都是学习笔记
随笔仅供参考,为避免笔记中可能出现的错误误导他人,请勿转载。

简介:

事件驱动,边读边解析

NO.

SAXParser

作用

SAXParserFactory

作用

1

public abstract class SAXParser extends Object
继承关系
public abstract class SAXParserFactory extends Object
继承关系

2

 
public void parse(File f,DefaultHandler dh) throws SAXException,IOException

解析使用指定的指定XML文件的内容DefaultHandler 

f - 包含要解析的XML的文件

dh - 要使用的SAX DefaultHandler。

当传入事件处理器,相当于在方法里面绑定了一个事件(自动执行事件)

public static SAXParserFactory newInstance()
创建 SAXParserFactory实例

3

   
public abstract SAXParser newSAXParser()throws ParserConfigurationException,SAXException
创建SAXParse实例

 NO

DefaultHandler (事件处理器)

参数

 作用

1

public class DefaultHandler
extends Object
implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler
  继承这个类然后重写下面三个方法

2

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

ch - 字符。

start - 字符数组中的起始位置。

length - 从字符数组中使用的字符数。

 接收元素内的字符数据通知。

默认情况下,什么也不做。 应用程序编写者可以覆盖此方法以对每个字符数据块采取特定操作(例如将数据添加到节点或缓冲区,或将其打印到文件中)。

3

public void startElement(String uri,String localName,String qName,Attributes attributes)throws SAXException

 uri - 命名空间URI,如果该元素没有命名空间URI或未执行命名空间处理,则为空字符串。

localName - 本地名称(无前缀),或空字符串,如果未执行命名空间处理。

qName - 限定名称(带前缀),如果限定名称不可用,则为空字符串。

attributes - 附加到元素的属性。 如果没有属性,它将是一个空的Attributes对象。

 接收元素开始的通知。

默认情况下,什么也不做。 应用程序编写者可以在子类中覆盖此方法,以在每个元素的开始处采取特定的操作(例如分配新的树节点或将输出写入文件)。

4

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

uri - 名称空间URI,或空字符串,如果该元素没有命名空间URI或未命名空间处理。


localName - 本地名称(无前缀),或空字符串,如果未执行命名空间处理。


qName - 限定名称(带前缀),如果限定名称不可用,则为空字符串。

 

接收元素结尾的通知。
默认情况下,什么也不做。 应用程序编写者可以在子类中覆盖此方法,以在每个元素的末尾执行特定操作(例如,完成树节点或将输出写入文件)。

 代码实现:

package SAX.cn;

import java.io.File;

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;

public class TestSax {
    public static void main(String[] args) throws Exception {
        /**
         * 1、创建一个解析器工厂
         * 2、创建解析器
         * 3、执行parse()方法
         */
        // 创建解析器工厂
        SAXParserFactory spf = SAXParserFactory.newInstance();
        // 创建解析器
        SAXParser sax = spf.newSAXParser();
        // 执行parse()方法
        sax.parse("src" + File.separator + "SAX" + File.separator + "cn" + File.separator + "saxDemo.xml",new MyDef());
        // 执行parse()方法后会自动执行事件处理器中的方法
        
    }
}
class MyDef extends DefaultHandler{
    
    /**
     * 开始标签
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        System.out.print("<" + qName + ">");
    }
    
    /**
     * 文本内容
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        System.out.print(new String(ch,start,length));
    }
    
    /**
     * 结束标签
     */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        System.out.print("</" + qName + ">");
    }
}

输出结果:

 

 

import java.io.File;

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;

public class TestSax {
    public static void main(String[] args) throws Exception {
        /**
         * 1、创建一个解析器工厂 2、创建解析器 3、执行parse()方法
         */
        // 创建解析器工厂
        SAXParserFactory spf = SAXParserFactory.newInstance();
        // 创建解析器
        SAXParser sax = spf.newSAXParser();
        // 执行parse()方法
        sax.parse("src" + File.separator + "SAX" + File.separator + "cn" + File.separator + "saxDemo.xml", new MyDef2());
        // 执行parse()方法后会自动执行事件处理器中的方法

    }
}

// 获取所有name标签的值
class MyDef2 extends DefaultHandler {
    
    boolean flag = false;    // 相当于是仓库钥匙,startElement()是进门和endElement()就是出门,flag=true就是用钥匙开门,flag=false就是关门,characters()就是在进出仓库拿内容
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // 判断qName是否是name标签
        if ("name".equals(qName)) {    
            flag = true;    // 找到name标签则flag为true
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if(flag == true) {    // flag为true表示已经找到name标签
            System.out.println("name:" + new String(ch,start,length));
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if(flag == true) {    // 已经找到name的开始标签并打印了内容,那么此次那么标签应该结束
            flag = false;
        }
    }
    }
}

上面的代码实现了获取name标签的值(使用"name".equals(qName)来控制):

package SAX.cn;

import java.io.File;
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;

public class TestSax {
    public static void main(String[] args) throws Exception {
        /**
         * 1、创建一个解析器工厂 2、创建解析器 3、执行parse()方法
         */
        // 创建解析器工厂
        SAXParserFactory spf = SAXParserFactory.newInstance();
        // 创建解析器
        SAXParser sax = spf.newSAXParser();
        // 执行parse()方法
        sax.parse("src" + File.separator + "SAX" + File.separator + "cn" + File.separator + "saxDemo.xml", new MyDef2());
        // 执行parse()方法后会自动执行事件处理器中的方法

    }
}

// 获取所有name标签的值
class MyDef2 extends DefaultHandler {
    
    boolean flag = false;    // 相当于是仓库钥匙,startElement()是进门和endElement()就是出门,flag=true就是用钥匙开门,flag=false就是关门,characters()就是在进出仓库拿内容
    int index = 1;
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // 判断qName是否是name标签
        if ("name".equals(qName) && index==1) {    
            flag = true;    // 找到name标签则flag为true
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if(flag == true) {    // flag为true表示已经找到name标签
            System.out.println("name:" + new String(ch,start,length));
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if(flag == true) {    // 已经找到name的开始标签并打印了内容,那么此次那么标签应该结束
            flag = false;
            index++;
        }
    }

}

上面的代码实现了获取第一个name标签的值(使用index来控制):

 

posted on 2022-03-26 16:35  时间完全不够用啊  阅读(1013)  评论(0编辑  收藏  举报