XML解析(二):SAX解析

概述

      SAX(Simple API for XML)是java官方提供的另一种解析XML的方式。与DOM解析方式不同,SAX是采用事件驱动的方式解析文档,解析前不需要读入整个文档,而读文档的过程就是解析的过程。事件驱动,就是一种基于回调(callback)机制的运行方法。
优点:采用事件驱动模式,对内存耗费较小,适用于只需要处理xml中的数据的场景
缺点:不易编码,很难同时访问同一个xml中的多处不同数据

SAX是使用SAXParserHandler对象来解析XML文件,SAXParserHandler继承了DefaultHandler

解析流程

这里写图片描述

示例

解析《XML解析(一):DOM解析》文中的book.xml,并且将解析所得信息保存在Book类中。

创建Book类

package wds.entity;

public class Book {

    private String id;
    private String name;
    private String author;
    private String year;
    private String price;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getYear() {
        return year;
    }
    public void setYear(String year) {
        this.year = year;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Book [id=" + id + ", name=" + name + ", author=" + author
                + ", year=" + year + ", price=" + price + "]";
    }
}

创建SAXParserHandler类

import java.util.ArrayList;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import wds.entity.Book;

public class SAXParserHandler extends DefaultHandler {

    Book book = null;
    String value = null; // 节点内容 为了不同方法共享 设置为全局变量
    ArrayList<Book> list = new ArrayList<Book>();

    public ArrayList<Book> getList() {
        return list;
    }

    // 用来标志解析开始
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.startDocument();
        System.out.println("=========解析开始=========");
    }

    // 用来标志解析结束
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
        System.out.println("=========解析结束=========");
    }

    // 用来遍历xml文件的开始标签
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        // TODO Auto-generated method stub
        super.startElement(uri, localName, qName, attributes);
        // 开始解析book标签的属性 要想获取book的顺序 设置一个全局变量 index
        if (qName.equals("book")) {
            book = new Book();
            System.out.println("=============开始遍历某本书=============");
            // //已知book元素下属性的名称 根据名称获取值
            // System.out.println(attributes.getValue("id"));

            // 不知道book元素下属性的名称和个数 获取属性值
            int num = attributes.getLength();
            for (int i = 0; i < num; i++) {
                System.out.print("book元素的第" + (i + 1) + "个属性名为  "
                        + attributes.getQName(i));
                System.out.println(" ----属性值: " + attributes.getValue(i));
                if (attributes.getQName(i).equals("id")) {
                    book.setId(attributes.getValue(i));
                }
            }
        } else if (!qName.equals("book") && !qName.equals("bookstore")) {
            System.out.print("节点名是:  " + qName);
        }
    }

    // 用来遍历xml文件的结束标签
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        // TODO Auto-generated method stub
        super.endElement(uri, localName, qName);
        // 判断是否针对某本书结束遍历
        if (qName.equals("book")) {
            list.add(book);
            book = null;
            System.out.println("=============结束遍历某本书=============");
        } else if (qName.equals("name")) {
            book.setName(value);
        } else if (qName.equals("author")) {
            book.setAuthor(value);
        } else if (qName.equals("year")) {
            book.setYear(value);
        } else if (qName.equals("price")) {
            book.setPrice(value);
        }
    }

    // 获取节点中的内容
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        // TODO Auto-generated method stub
        super.characters(ch, start, length);
        value = new String(ch, start, length);
        if (!value.trim().equals("")) {
            System.out.println("  节点值:" + value);
        }
    }

}

创建SAXXMLTest

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import wds.entity.Book;
import wds.handler.SAXParserHandler;

public class SAXXMLTest {

    /**
     * @param args
     * 使用SAX方式解析XML文件  步骤
     * 1.通过SAXParserFactory的静态newInstance()方法获取SAXParserFactory实例factory
     * 2.通过SAXParserFactory实例的newSAXParser()方法返回SAXParser实例parser
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //创建SAXParserFactory对象
        SAXParserFactory  factory=SAXParserFactory.newInstance();
        try {
            //创建SAXParser
            SAXParser  parser= factory.newSAXParser();
            //创建SAXParserHandler对象
            SAXParserHandler handler = new SAXParserHandler();
            //解析xml文件 handler处理
            parser.parse("book.xml", handler);
            System.out.println("···········共有"+handler.getList().size()+"本书···········");
            for(Book book:handler.getList()){
                System.out.println(book.toString());
                System.out.println("**************************");
            }
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值