xml文件--SAX方式解析xml文件
SAX介绍
SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。
与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。
当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并**相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。
局限性:
1. SAX分析器在对XML文档进行分析时,触发了一系列的事件,由于事件触发本身是有时序性的,因此,SAX提供的是一种顺序访问机制,对于已经分析过的部分,不能再倒回去重新处理。
即,一旦经过了某个元素,我们没有办法返回去再去访问它。
2. SAX分析器只做了一些简单的工作,大部分工作还要由应用程序自己去做。
也就是说,SAX分析器在实现时,只是顺序地检查XML文档中的字节流,判断当前字节是XML语法中的哪一部分、是否符合XML语法,然后再触发相应的事件,而事件处理函数本身则要由应用程序自己来实现。
同DOM分析器相比,SAX分析器缺乏灵活性。
优势:
然而,由于SAX分析器实现简单,对内存要求比较低,(SAX不必将整个XML文档加载到内存当中,因此它占据内存要比DOM小), 因此实现效率比较高。
对于大型的XML文档来说,通常会用SAX而不是DOM。
并且对于那些只需要访问XML文档中的数据而不对文档进行更改的应用程序来说,SAX分析器更为合适。
SAX原理图
xml文件
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book id="1">
<name>冰与活之歌</name>
<author>乔治马丁</author>
<year>2014</year>
<price>89</price>
</book>
<book id="2">
<name>安徒生童话</name>
<year>2014</year>
<price>77</price>
<language>English</language>
</book>
<book></book>
</bookstore>
Java代码
SAXText.java
package anqi;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import handle.Book;
import handle.SAXParserHandler;
/*
*1.通过SAXParserFactory的静态newInstance()方法获取
*SAXParserFactory实例factory
*2.通过SAXParserFactory实例的newSAXParser()方法返回
*SAXParser实例parser
*3.创建一个类继承DefaultHandler,重写其中的一些方法
*进行业务处理并创建这个类的实例handler
* */
public class SAXTest {
public static void main(String[] args) {
//获取一个SAXParserFactory的实例
SAXParserFactory factory = SAXParserFactory.newInstance();
//通过Factory获取SAXParser实例
try{
SAXParser parser = factory.newSAXParser();
//创建SAXParserHandler对象
SAXParserHandler handler = new SAXParserHandler();
//public void parse(String uri, DefaultHandler dh)
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.getAuthor());
System.out.println(book.getYear());
System.out.println(book.getPrice());
System.out.println(book.getLanguage());
System.out.println("----finish----");
}
}catch(Exception e){}
}
}
SAXParserHandler.java
package handle;
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<>();
public ArrayList<Book> getBookList() {
return bookList;
}
int bookIndex=0;
/**
* 解析xml元素
*/
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
//开始解析book元素
if(qName.equals("book")){
//创建一个book对象
book = new Book();
bookIndex++;
System.out.println("-----------------开始遍历第"+bookIndex+"本书---------------");
//已知book元素下属性的名称,根据名称获取值
//String value = attributes.getValue("id");
//System.out.println("book的属性值是:"+value);
//不知道book元素下属性的名称的话,如何获取value值
for(int i=0;i<attributes.getLength();i++){
System.out.println("book元素的第"+(i+1)+"个属性名是"+attributes.getQName(i));
// public abstract String getValue (int index);
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 {
super.endElement(uri, localName, qName);
//判断是否针对一本书已经遍历结束
if(qName.equals("book")){
bookList.add(book);
book = null;
System.out.println("----------------结束遍历第"+bookIndex+"本书--------------'");
}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);
}
}
/**
* 用来标识解析开始
*/
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("SAX解析开始");
}
/**
* 用来标识解析结束
*/
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("SAX解析结束");
}
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
value = new String(ch,start,length);
if(!value.trim().equals("")){
System.out.println("节点值是"+value);
}
}
}
Book.java
package handle;
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;
}
}
显示结果
SAX解析开始
-----------------开始遍历第1本书---------------
book元素的第1个属性名是id
属性值是:1
节点名是:name---节点值是冰与活之歌
节点名是:author---节点值是乔治马丁
节点名是:year---节点值是2014
节点名是:price---节点值是89
----------------结束遍历第1本书--------------'
-----------------开始遍历第2本书---------------
book元素的第1个属性名是id
属性值是:2
节点名是:name---节点值是安徒生童话
节点名是:year---节点值是2014
节点名是:price---节点值是77
节点名是:language---节点值是English
----------------结束遍历第2本书--------------'
-----------------开始遍历第3本书---------------
----------------结束遍历第3本书--------------'
SAX解析结束
共有3本书
1
乔治马丁
2014
89
null
----finish----
2
null
2014
77
English
----finish----
null
null
null
null
null
----finish----
问题分析
出现如下情况是因为把回车等空格也读到了value中,所以以下代码很有必要
if(!value.trim().equals("")){
System.out.println("节点值是"+value);
}
SAX解析开始
节点值是
-----------------开始遍历第1本书---------------
book元素的第1个属性名是id
属性值是:1
节点值是
节点名是:name---节点值是冰与活之歌
节点值是
节点名是:author---节点值是乔治马丁
节点值是
节点名是:year---节点值是2014
节点值是
节点名是:price---节点值是89
节点值是
----------------结束遍历第1本书--------------'
节点值是
-----------------开始遍历第2本书---------------
book元素的第1个属性名是id
属性值是:2
节点值是
节点名是:name---节点值是安徒生童话
节点值是
节点名是:year---节点值是2014
节点值是
节点名是:price---节点值是77
节点值是
节点名是:language---节点值是English
节点值是
----------------结束遍历第2本书--------------'
节点值是
-----------------开始遍历第3本书---------------
----------------结束遍历第3本书--------------'
节点值是
SAX解析结束
上一篇: 用curl发post请求,但是提示302 FOUND
下一篇: JS 遍历树
推荐阅读
-
实例详解简单实体类和xml文件的相互转换方法
-
mybatis之旅第三篇-SqlMapConfig.xml全局配置文件解析
-
这段php生成xml文件的代码找不出错误,可是就是总是提示错误
-
php 生成xml文件汉字中文编码问题
-
python读取xml文件方法解析
-
Axis2 Web服务配置文件services.xml详解
-
请问在html中,如何调用xml文件里的内容?_html/css_WEB-ITnose
-
mybaits的xxMapper.xml文件中大于号和小于号处理
-
读取配置文件properties并解析xml的main方法
-
php的SimpleXML方法读写XML接口文件实例解析_PHP