引用:http://www.cnblogs.com/boyupeng/archive/2011/04/06/2028529.html
这几天看了mars老师的文章,其中有一个利用sax解析从网络中下载的xml文件,很受用。先来看看工程的架构:
其中FileUtils.java用来放一些常用的公共方法,这里放置对文件的读写
HttpDownload.java用来从网上下载xml文件
MyContentHandler.java为xml内容处理器类
XMLActivity.java这个大家懂得,呵呵
第一步,FileUtils.java,还是老样子,具体的解释放在代码注释中:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.os.Environment;
public class FileUtils
{
private String SDPATH;
public String getSDPATH()
{
return SDPATH;
}
public FileUtils()
{
//得到当前外部存储设备的目录/SDCARD
SDPATH = Environment.getExternalStorageDirectory() + "/";
}
/**
* 在SD卡上创建文件
*
* @throws IOException
*/
public File creatSDFile(String fileName) throws IOException
{
File file = new File(SDPATH + fileName);
file.createNewFile();
return file;
}
/**
* 在SD卡上创建目录
*
* @param dirName
*/
public File creatSDDir(String dirName)
{
File dir = new File(SDPATH + dirName);
dir.mkdir();
return dir;
}
/**
* 判断SD卡上的文件夹是否存在
*/
public boolean isFileExist(String fileName)
{
File file = new File(SDPATH + fileName);
return file.exists();
}
/**
* 将一个InputStream里面的数据写入到SD卡中
*/
public File write2SDFromInput(String path, String fileName,
InputStream input)
{
File file = null;
OutputStream output = null;
try
{
creatSDDir(path);
file = creatSDFile(path + fileName);
output = new FileOutputStream(file);
byte buffer[] = new byte[4 * 1024];
while ((input.read(buffer)) != -1)
{
output.write(buffer);
}
output.flush();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
output.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
return file;
}
}
第二步,HttpDownload.java
package my.utils;
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;
public class HttpDownloader
{
private URL url = null;
/**
* 根据URL下载文件,前提是这个文件当中的内容是文本,函数的返回值就是文件当中的内容
* 1.创建一个URL对象
* 2.通过URL对象,创建一个HttpURLConnection对象
* 3.得到InputStram
* 4.从InputStream当中读取数据
* @param urlStr
* @return
*/
public String download(String urlStr)
{
StringBuffer sb = new StringBuffer();
String line = null;
BufferedReader buffer = null;
try
{
// 创建一个URL对象
url = new URL(urlStr);
// 创建一个Http连接
HttpURLConnection urlConn = (HttpURLConnection) url
.openConnection();
// 使用IO流读取数据
buffer = new BufferedReader(new InputStreamReader(urlConn
.getInputStream()));
while ((line = buffer.readLine()) != null)
{
sb.append(line);
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
buffer.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
return sb.toString();
}
/**
* 该函数返回整形 -1:代表下载文件出错 0:代表下载文件成功 1:代表文件已经存在
*/
public int downFile(String urlStr, String path, String fileName)
{
InputStream inputStream = null;
try
{
FileUtils fileUtils = new FileUtils();
if (fileUtils.isFileExist(path + fileName))
{
return 1;
}
else
{
inputStream = getInputStreamFromUrl(urlStr);
File resultFile = fileUtils.write2SDFromInput(path, fileName,
inputStream);
if (resultFile == null)
{
return -1;
}
}
}
catch (Exception e)
{
e.printStackTrace();
return -1;
}
finally
{
try
{
inputStream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
return 0;
}
/**
* 根据URL得到输入流
*
* @param urlStr
* @return
* @throws MalformedURLException
* @throws IOException
*/
public InputStream getInputStreamFromUrl(String urlStr)
throws MalformedURLException, IOException
{
url = new URL(urlStr);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConn.getInputStream();
return inputStream;
}
}
第三步,MyContentHandler.java
package my.xml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
public class MyContentHandler extends DefaultHandler
{
String hisname, address, money, sex, status;
String tagName;
/**
* 开始解析xml
* @throws SAXException
*/
public void startDocument() throws SAXException
{
System.out.println("````````begin````````");
}
/**
* 结束解析xml
* @throws SAXException
*/
public void endDocument() throws SAXException
{
System.out.println("````````end````````");
}
/**
* 开始解析元素属性
*
* @param namespaceURI 命名空间,防止命名重复
* @param localName 不带前缀的名字
* @param qName 带前缀的名字
* @param attr 代表标签里所有的属性
* @throws SAXException
*/
public void startElement(String namespaceURI, String localName,
String qName, Attributes attr) throws SAXException
{
tagName = localName;//把当前正在解析的无前缀的名字传给tagName
if (localName.equals("worker"))
{
//获取标签的全部属性
for (int i = 0; i < attr.getLength(); i++)
{
Log.e("@@@", (attr.getLocalName(i) + "=" + attr.getValue(i)));//得到第i个属性的名字和值
}
}
}
/**
* 结束元素解析
*
* @param namespaceURI
* @param localName
* @param qName
* @throws SAXException
*/
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException
{
//在workr标签解析完之后,会打印出所有得到的数据
tagName = "";
if (localName.equals("worker"))
{
this.printout();
}
}
/**
* 具体解析标签里的内容
*
* @param ch 所有读取到的内容,都会放到char[]类型的数组里
* @param start 读取的内容是从char[]数组的哪一位开始
* @param length 从start开始,一共有多长的内容
* @throws SAXException
*/
public void characters(char[] ch, int start, int length)
throws SAXException
{
if (tagName.equals("name"))
hisname = new String(ch, start, length);
else if (tagName.equals("sex"))
sex = new String(ch, start, length);
else if (tagName.equals("status"))
status = new String(ch, start, length);
else if (tagName.equals("address"))
address = new String(ch, start, length);
else if (tagName.equals("money"))
money = new String(ch, start, length);
}
private void printout()
{
System.out.print("name: ");
System.out.println(hisname);
System.out.print("sex: ");
System.out.println(sex);
System.out.print("status: ");
System.out.println(status);
System.out.print("address: ");
System.out.println(address);
System.out.print("money: ");
System.out.println(money);
System.out.println();
}
}
第四步,在完成了上面三个类的编写,XMLActivity.java就只要实现简单的调用就可以了:
package my.xml;
import java.io.StringReader;
import javax.xml.parsers.SAXParserFactory;
import my.utils.HttpDownloader;
import my.xml.R;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class XMLActitity extends Activity
{
/** Called when the activity is first created. */
private Button parseButton;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
parseButton = (Button) findViewById(R.id.parseButton);
parseButton.setOnClickListener(new ParseButtonListener());
}
class ParseButtonListener implements OnClickListener
{
@Override
public void onClick(View v)
{
HttpDownloader hd = new HttpDownloader();//new一个HttpDownloader对象
String resultStr = hd
.download("http://192.168.1.112/test.xml");//把下载的字符串放在resultStr
try
{
/**
* 创建一个SAXParserFactory,再用这个工厂来创建一个XMLReader,以此来读取XML
* 这个方法就是这样写的,没有什么为什么,只是规定的格式罢了。
*/
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader reader = factory.newSAXParser().getXMLReader();
//为XMLReader设置内容处理器,MyContentHandler()为具体处理的类
reader.setContentHandler(new MyContentHandler());
//开始解析文件
reader.parse(new InputSource(new StringReader(resultStr)));
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
在MyContentHandler 继承DefaultHandler中,主要是使用了适配器设计模式,不必实现接口中的所有方法。ok!