解析网络 xml 流程

简介: 引用:http://www.cnblogs.com/boyupeng/archive/2011/04/06/2028529.html 这几天看了mars老师的文章,其中有一个利用sax解析从网络中下载的xml文件,很受用。

引用:http://www.cnblogs.com/boyupeng/archive/2011/04/06/2028529.html

这几天看了mars老师的文章,其中有一个利用sax解析从网络中下载的xml文件,很受用。先来看看工程的架构:

1

其中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!

相关文章
|
18天前
|
XML JavaScript 前端开发
xml文件使用及解析
xml文件使用及解析
|
1月前
|
算法 数据处理 开发者
FFmpeg库的使用与深度解析:解码音频流流程
FFmpeg库的使用与深度解析:解码音频流流程
36 0
|
1月前
|
机器学习/深度学习 算法 PyTorch
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
232 1
|
4天前
|
XML Java 数据库连接
Javaweb之Mybatis的XML配置文件的详细解析
Javaweb之Mybatis的XML配置文件的详细解析
13 0
|
7天前
|
XML C# 数据格式
C# 解析XML文件
C# 解析XML文件
17 1
|
15天前
|
存储 安全 测试技术
网络奇谭:虚拟机中的共享、桥接与Host-Only模式解析
网络奇谭:虚拟机中的共享、桥接与Host-Only模式解析
19 0
|
23天前
|
C++
C++ While 和 For 循环:流程控制全解析
本文介绍了C++中的`switch`语句和循环结构。`switch`语句根据表达式的值执行匹配的代码块,可以使用`break`终止执行并跳出`switch`。`default`关键字用于处理没有匹配`case`的情况。接着,文章讲述了三种类型的循环:`while`循环在条件满足时执行代码,`do/while`至少执行一次代码再检查条件,`for`循环适用于已知循环次数的情况。`for`循环包含初始化、条件和递增三个部分。此外,还提到了嵌套循环和C++11引入的`foreach`循环,用于遍历数组元素。最后,鼓励读者关注微信公众号`Let us Coding`获取更多内容。
21 0
|
1月前
|
SQL 安全 网络安全
构筑数字堡垒:网络安全漏洞解析与防御策略
在数字化时代,网络安全已成为维护信息完整性、保障用户隐私和确保商业连续性的关键。本文将深入探讨网络安全领域的核心议题—安全漏洞及其防御机制。通过分析常见网络攻击手段,如SQL注入、跨站脚本攻击(XSS)及拒绝服务(DoS)攻击,揭示其背后的原理与潜在危害。同时,文章将重点介绍加密技术的种类和应用场景,以及如何通过强化安全意识,构建多层次的防御体系来有效预防和应对网络安全威胁。本研究旨在为读者提供一份系统性的网络安全防护指南,帮助个人和组织在不断演变的威胁面前保持警惕,并采取适当的安全措施。
21 2
|
1天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
9天前
yolo-world 源码解析(六)(2)
yolo-world 源码解析(六)
19 0

推荐镜像

更多