sax解析分为以下几步:
1 获取一个saxparserfactory
2 获取一个解析器
3 创建handler对象,这个myHandler是继承了DefaultHandler的一个类,这个实现类里写具体的解析逻辑
4 开始解析xml。
结构层次图:
具体如下面的代码:
mySAXparser:
package com.imooc.test;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
public class mySAXparser {
public static void main(String[] args) {
//1 获取一个saxparserfactory
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
//2 获取一个解析器
SAXParser parser = factory.newSAXParser();
/*
* 3 创建handler对象,这个myHandler是继承了DefaultHandler的一个类
* 这个实现类里写具体的解析逻辑
*/
myHandler handler = new myHandler();
//4 开始解析xml,
parser.parse("books.xml",handler);
} 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();
}
}
}
myHandler:
package sax;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class myHandler extends DefaultHandler {
int i =0;
int j = 0;
String value = null;
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
super.startDocument();
System.out.println("startDocument开始解析..............");
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
System.out.println("endDocument结束解析............");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
/*
* qName:The qualified name (with prefix),
* or the empty string if qualified names are not available.
* qName:实际上就是标签名的名字,如<sex>1</sex> 那么qName就代指的这个标签名,sex
*
*/
if(qName.equals("book")){
i++;
String value = attributes.getValue("size");
int len = attributes.getLength();
System.out.println("len:"+len);
for(int k=0;k<len;k++){
int m = k+1;
System.out.println("属性"+m+":"+attributes.getQName(k));
}
System.out.println("book.size:"+value);
System.out.println("第"+i+"处,解析到book元素的标签。。。");
}
if(qName.equals("bookstore")){
j++;
System.out.println("第"+j+"处,解析到bookstore元素的标签。。。");
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
System.out.println("第"+i+",endElement结束");
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
//new String(ch, start, length)用来生成一个元素中标签之间的具体的文本
value = new String(ch, start, length);//加入正好解析到<name>冰与火之歌</name>时,那么value="冰与火之歌"
System.out.println("================节点值是:" + value);
if (!value.trim().equals("")) {
System.out.println(i+"节点值是:" + value);
}
}
}
books.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>2004</year>
<price>77</price>
<language>English</language>
</book>
</bookstore>
解析结果下:
startDocument开始解析..............
第1处,解析到bookstore元素的标签。。。
================节点值是:
len:2
属性1:id
属性2:size
book.size:23
第1处,解析到book元素的标签。。。
================节点值是:
================节点值是:冰与火之歌
1节点值是:冰与火之歌
第1,endElement结束
================节点值是:
================节点值是:乔治马丁
1节点值是:乔治马丁
第1,endElement结束
================节点值是:
================节点值是:2014
1节点值是:2014
第1,endElement结束
================节点值是:
================节点值是:89
1节点值是:89
第1,endElement结束
================节点值是:
第1,endElement结束
================节点值是:
len:1
属性1:id
book.size:null
第2处,解析到book元素的标签。。。
================节点值是:
================节点值是:安徒生童话
2节点值是:安徒生童话
第2,endElement结束
================节点值是:
================节点值是:2004
2节点值是:2004
第2,endElement结束
================节点值是:
================节点值是:77
2节点值是:77
第2,endElement结束
================节点值是:
================节点值是:English
2节点值是:English
第2,endElement结束
================节点值是:
第2,endElement结束
================节点值是:
第2,endElement结束
endDocument结束解析............
sax解析的myHandler这个类继承了DefaultHandler,具体的解析逻辑就是写在这个myHandler
中,覆盖的方法的执行顺序是:
1. startDocument()
2.
startElement(String uri, String localName, String qName,
Attributes attributes)
3. endElement(String uri, String localName, String qName)
4. characters(char[] ch, int start, int length)
...
n. endDocument()
其中的...省略号部分一直重复的执行2,3,4两个步骤,主要是根据xml的具体情形,遇到一个具体元素就会执行2,3,4三个步骤一次。如上面的
xml中的
<name>冰与火之歌</name>
<author>乔治马丁</author>
<year>2014</year>
<price>89</price>
,这样就会重复执行2,3,4步骤四次。