1.什么是SAX
SAX,全称Simple API for XML,既是指一种接口,也是指一个软件包。
作为接口,SAX是事件驱动型XML解析的一个标准接口。
2.SAX基本原理
3.SAX常用接口
ContentHander
4.SAX解析步骤
1)用HttpDownloader下载一个xml文件
2)用SAXParserFactory.newInstance()方法创建一个SAXParserFactory对象
3)用生成的SAXParserFactory对象的.newSAXParser().getXMLReader()方法创建一个XMLReader对象
4)编写内容处理器类,该类继承DefaultHander类并重写characters()、startDocument()、endDocument()、startElement()和endElement()方法
(注:DefaultHander类实现了Handler接口并重写了所有的抽象方法,但都为空。具体实现由我们在继承DefaultHander类时再次重写。)
5)调用XMLReader对象的.setContentHandler(new MyContentHandler)方法设置内容处理器
(注:XMLReader的作用是逐行读取xml文件,遇到重要标签会触发一些事件,事件处理函数的作用就是逐行的解析xml文件,代码由我们来编写)
6)调用XMLReader对象的.parse(new InputSource(new StringReader(resultStr)))方法来解析xml文件
(注:resultStr为保存有xml所有内容的字符串)
例子:
Mp3ListActivity.java:
package com.mycompany.mp3player;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.Menu;
import android.view.MenuItem;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.SAXParserFactory;
/**
* Created by Administrator on 2016/8/21.
*/
public class Mp3ListActivity extends android.app.ListActivity {
private static final int UPDATE = 1;
private static final int ABOUT = 2;
/*
在点击MENU按钮之后,会调用该方法,我们可以在这个方法当中加入自己的按钮控件
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, UPDATE, 1, R.string.mp3list_update);
menu.add(0, ABOUT, 2, R.string.mp3list_about);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == UPDATE){
// 用户点击了更新按钮
Thread thread = new MyThread();
thread.start();
}
else if(item.getItemId() == ABOUT){
// 用户点击了关于按钮
}
return super.onOptionsItemSelected(item);
}
private String downloadXML(String urlStr){
HttpDownloader httpDownloader = new HttpDownloader();
String result = httpDownloader.download(urlStr);
return result;
}
// 该函数的作用是对xml文件内容进行解析
private List<Mp3Info> parser(String xmlStr){
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
List<Mp3Info> infos = new ArrayList<Mp3Info>(); // 生成存放Mp3Info类型数据的集合对象
try{
XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();
Mp3ListContentHandler mp3ListContentHandler = new Mp3ListContentHandler(infos); // 生成内容处理器对象
xmlReader.setContentHandler(mp3ListContentHandler); // 为XMLReader对象设置内容处理器
xmlReader.parse(new InputSource(new StringReader(xmlStr))); // 真正开始解析(上一行并没有开始解析),xmlStr为保存着xml文件所有内容的字符串
// 利用迭代器读取集合中的所有歌曲
for(Iterator iterator = infos.iterator(); iterator.hasNext();){
Mp3Info mp3Info = (Mp3Info)iterator.next();
System.out.println(mp3Info); // 此时调用了Mp3Info类的toString方法
}
}catch (Exception e){
e.printStackTrace();
}
return infos;
}
class MyThread extends Thread{
@Override
public void run() {
String xml = downloadXML("http://192.168.137.1:8080/MP3/resources.xml");
parser(xml);
}
}
}
HttpDownloader.java:
package com.mycompany.mp3player;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Created by Administrator on 2016/8/14.
*/
public class HttpDownloader {
private URL url = null;
public String download(String urlStr){
StringBuffer stringBuffer = new StringBuffer();
String line;
BufferedReader bufferedReader = null;
try{
// 创建一个URL对象
url = new URL(urlStr);
// 创建一个Http连接
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
// 使用IO流读取数据
bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
while ((line = bufferedReader.readLine()) != null){
stringBuffer.append(line);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
bufferedReader.close();;
} catch (Exception e){
e.printStackTrace();
}
}
return stringBuffer.toString();
}
}
package com.mycompany.mp3player;
/**
* Created by Administrator on 2016/8/22.
* 该类类似结构体,存放Mp3歌曲信息
*/
public class Mp3Info {
private String ID;
private String mp3Name;
private String mp3Size;
private String lrcName;
private String lrcSize;
public Mp3Info() {
}
public Mp3Info(String ID, String mp3Name, String mp3Size, String lrcName, String lrcSize) {
this.ID = ID;
this.mp3Name = mp3Name;
this.mp3Size = mp3Size;
this.lrcName = lrcName;
this.lrcSize = lrcSize;
}
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID = ID;
}
public String getMp3Name() {
return mp3Name;
}
public void setMp3Name(String mp3Name) {
this.mp3Name = mp3Name;
}
public String getMp3Size() {
return mp3Size;
}
public void setMp3Size(String mp3Size) {
this.mp3Size = mp3Size;
}
public String getLrcName() {
return lrcName;
}
public void setLrcName(String lrcName) {
this.lrcName = lrcName;
}
public String getLrcSize() {
return lrcSize;
}
public void setLrcSize(String lrcSize) {
this.lrcSize = lrcSize;
}
@Override
public String toString() {
return "Mp3Info{" +
"ID='" + ID + '\'' +
", mp3Name='" + mp3Name + '\'' +
", mp3Size='" + mp3Size + '\'' +
", lrcName='" + lrcName + '\'' +
", lrcSize='" + lrcSize + '\'' +
'}';
}
}
Mp3ListContentHandler.java:
package com.mycompany.mp3player;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.List;
/**
* Created by Administrator on 2016/8/22.
* 该类为内容处理器类,主要作用是对xml文件内容进行具体的解析
* 该内容处理器接受一个Mp3Info集合类型的参数
*/
public class Mp3ListContentHandler extends DefaultHandler{
private List<Mp3Info> infos = null; // 该变量为集合,存放Mp3Info类型的数据
private Mp3Info mp3Info = null; // 该变量存储一首歌曲的信息
private String tagName = null; // 该变量存储xml文件内的标签名
public Mp3ListContentHandler(List<Mp3Info> infos) {
this.infos = infos;
}
public List<Mp3Info> getInfos() {
return infos;
}
public void setInfos(List<Mp3Info> infos) {
this.infos = infos;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String temp = new String(ch, start, length);
if(tagName.equals("id")){
mp3Info.setID(temp);
}
else if(tagName.equals("mp3.name")){
mp3Info.setMp3Name(temp);
}
else if(tagName.equals("mp3.size")){
mp3Info.setMp3Size(temp);
}
else if(tagName.equals("lrc.name")){
mp3Info.setLrcName(temp);
}
else if(tagName.equals("lrc.size")){
mp3Info.setLrcSize(temp);
}
}
@Override
// 开始读取标签
// uri为命名空间uri,localName为不带前缀的标签名,qName为带前缀的标签名,attributes为属性集
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
this.tagName = localName;
if(tagName.equals("resource")){
mp3Info = new Mp3Info();
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equals("resource")){
// 将读取结束的该首歌曲存入List当中
infos.add(mp3Info);
}
tagName = "";
}
@Override
public void startDocument() throws SAXException {
}
@Override
public void endDocument() throws SAXException {
}
}
resources.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<resources>
<resource>
<id>0001</id>
<mp3.name>毛阿敏 - 爱上张无忌.mp3</mp3.name>
<mp3.size>10461734</mp3.size>
<lrc.name>毛阿敏 - 爱上张无忌.lrc</lrc.name>
<lrc.size>941</lrc.size>
</resource>
<resource>
<id>0002</id>
<mp3.name>李志 - 天空之城.mp3</mp3.name>
<mp3.size>9063843</mp3.size>
<lrc.name>李志 - 天空之城.lrc</lrc.name>
<lrc.size>1315</lrc.size>
</resource>
</resources>
lingweXML是指可扩展标记语言(eXtensible MarkupLanguage),它是一种标记语言。它被设计的宗旨是描述数据(XML),而非显示数据(HTML)。
XML是各种应用程序之间进行数据传输的最常用的工具