XML解析学习总结--SAX解析

2 篇文章 0 订阅

2、SAX解析介绍

* 全称:Simple APIs for XML—即XML简单应用程序接口
* 解析原理:

通过parse(file,listener)函数用一个listener对xml文件进行查找,按顺序读取文档,遍历每个标签,当发现目标标签时,读取标签的属性、结点值等信息并返回。SAX接口也被称作事件驱动接口。

* 优缺点:
  • 优点:
    a. 采用事件驱动模式,无需将整个xml文档载入内存,对内存耗费比较小。
    b. 适用于只处理XML文件中的数据时。
    c. 可以继承ContentHandler创建多个执行不同查询的listener进行解析操作
  • 缺点:
    a. 编码比较麻烦;
    b. 不能随机的访问xml中的节点,查询一次就要对XML文档从头到尾遍历一次
    c. 不能修改文档
    d. 很难同时访问XML文件中的多处不同数据
*操作步骤

操作步骤:
1:创建解析工厂:SAXParserFactory factory = SAXParserFactory.newInstance();
2:由工厂创建解析器:SAXParser parser = factory.newSAXParser();
3:通过解析器的parse()方法,对指定xml文档以指定handler之类进行解析查询:parser.parse(xmlFile, new MySaxListener());

我们要继承DefaultHandler类,定义相应的查询操作类:
1:重写父类中的文档开始方法、文档结束方法,定义开始、结束遍历xml文档时的操作:

 void startDocument() 
         接收文档开始的通知。 
void endDocument() 
         接收文档结束的通知。 

2:重写父类的标签开始方法、标签结束方法,定义遍历到一个开始、结束标签时的操作:

void startElement(String uri, String localName, String qName, Attributes attributes) //参数qName是标签名、attributes是属性列表
         接收元素开始的通知。 
void endElement(String uri, String localName, String qName) 
         接收元素结束的通知。

3:重写characters(char[] ch, int start, int length)方法:

// 对事件发生时,元素的字符怎么处理  
   public void characters(char[] ch, int start, int length) throws SAXException {
       //参数ch是当上述4中事件随便一个发生时,对应的元素的值,值在ch中start开始,length长。从头到尾遍历整个xml文档时,每个标签的值依次被存入ch中。
}
*与DOM解析的区别

通过SAX解析xml文档是没有dom对象出现的,所以不会有node,不会有getNodeName()、getNodeValue()获取结点名、值。

* 总结:

SAX解析XML文档的结点名是通过事件函数的参数qName获取的,属性是通过参数attributes的getValue(“属性名”)获取的,
结点值是通过当前事件函数发生时,characters(char[] ch, int start, int length)方法中的内容获取的。

* 实例

SAXTest.java

package com.bonc.xmlTest;

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


public class SAXTest {
    /**
     * @param args
     */
    public static void main(String[] args) {
        //创建解析工厂SAXParserFactory
        SAXParserFactory factory = SAXParserFactory.newInstance();
        //由工厂factory创建SAXParser解析器
        try {
            SAXParser parser = factory.newSAXParser();
            //通过解析器的parse()方法,对指定xml文档以指定handler之类进行解析查询:parser.parse(xmlFile, new MySaxListener());
            SAXParserHandler handler = new SAXParserHandler();
            parser.parse("books.xml", handler);
            System.out.println("~!~!~!共有" + handler.getBookList().size()
                    + "本书");
            for (Book book : handler.getBookList()) {
                System.out.println(book.getId());
                System.out.println(book.getName());
                System.out.println(book.getAuthor());
                System.out.println(book.getYear());
                System.out.println(book.getPrice());
                System.out.println(book.getLanguage());
                System.out.println("----finish----");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}

SAXParserHandler.java

package com.bonc.xmlTest;

import java.util.ArrayList;

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

public class SAXParserHandler extends DefaultHandler {
    String value = null;
    Book book = null;
    private ArrayList<Book> bookList = new ArrayList<Book>();
    public ArrayList<Book> getBookList() {
        return bookList;
    }

    int bookIndex = 0;
    /**
     * 用来标识解析开始
     */
    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.startDocument();
        System.out.println("SAX解析开始");
    }
    
    /**
     * 用来标识解析结束
     */
    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
        System.out.println("SAX解析结束");
    }
    
    /**
     * 解析xml元素
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        //调用DefaultHandler类的startElement方法
        super.startElement(uri, localName, qName, attributes);
        if (qName.equals("book")) {
            bookIndex++;
            //创建一个book对象
            book = new Book();
            //开始解析book元素的属性
            System.out.println("======================开始遍历某一本书的内容=================");
            //不知道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("name") && !qName.equals("bookstore")) {
            System.out.print("节点名是:" + qName + "---");
        }
    }
    
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        //调用DefaultHandler类的endElement方法
        super.endElement(uri, localName, qName);
        //判断是否针对一本书已经遍历结束
        if (qName.equals("book")) {
            bookList.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);
        }
        else if (qName.equals("language")) {
            book.setLanguage(value);
        }
    }
    
    @Override
    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);
        }
    }
}

Book.java

package com.bonc.xmlTest;

public class Book {
	private String id;
	private String name;
	private String author;
	private String year;
	private String price;
	private String language;
	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;
	}
	public String getLanguage() {
		return language;
	}
	public void setLanguage(String language) {
		this.language = language;
	}
	@Override
	public String toString() {
		return "Book [id=" + id + ", name=" + name + ", author=" + author + ", year=" + year + ", price=" + price
				+ ", language=" + language + "]";
	}	
}

输出结果:

SAX解析开始
======================开始遍历某一本书的内容=================
book元素的第1个属性名是:id---属性值是:1
book元素的第2个属性名是:pages---属性值是:234
book元素的第3个属性名是:date---属性值是:20181203
节点值是:冰与火之歌
节点名是:author---节点值是:乔治马丁
节点名是:year---节点值是:2014
节点名是:price---节点值是:89
======================结束遍历某一本书的内容=================
======================开始遍历某一本书的内容=================
book元素的第1个属性名是:id---属性值是:2
节点值是:安徒生童话
节点名是:year---节点值是:2004
节点名是:price---节点值是:77
节点名是:language---节点值是:English
======================结束遍历某一本书的内容=================
SAX解析结束
~!~!~!共有2本书
1
冰与火之歌
乔治马丁
2014
89
null
----finish----
2
安徒生童话
null
2004
77
English
----finish----

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值