`
Bauble
  • 浏览: 66949 次
  • 性别: Icon_minigender_1
  • 来自: Mercury
社区版块
存档分类
最新评论

Android19_XML文件解析

阅读更多

一、SAX的概念

在Android平台解析XML主要使用SAX标准。

 

SAX全称Simple API for XML,既是指一种接口,也是指一个软件包。作为接口,SAX是事件驱动型/XML解析的一个标准接口。

 

逐行扫描文档,而dom是要先把所有文档先载入进来。缺点:操作不方便,添加删除内容麻烦。

 

二、SAX基本原理

SAX的工作原理简单的说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知时间处理函数,由时间处理函数做相应动作,然后继续同样的扫描,直至文档结束。

 

SAX实现都会产生以下类型的事件:

1) 在文档的开始和结束时触发文档处理事件。

2) 在文档内每一个XML元素接受解析的前后触发元素事件。

3) 任何元数据通常都由单独的事件交付。

4) 在处理文档的DTD或Schema是产生DTD或Schema事件。

5) 产生错误时间用来通知主机应用程序解析错误。

 

SAX解析模型 


SAX解析文档过程

<doc>
     <para>Hello,XML!</para>
</doc>

  在解析文档的过程中会产生如下一系列事件:

1)创建事件处理程序。

2)创建SAX解析器。

3)将事件处理程序分配给解析器。

4)对文档进行解析,将每个事件发送给处理程序。

 

三、SAX常用接口

ContentHandler接口是Java类包中的一个特殊的SAX接口,位于org.xml.sax包中。该接口封装了一些对事件处理的方法,当XML解析器开始解析XML输入文档的时候,他会遇到某些特殊的事件,比如文档的开始和结束、元素的开始和结束、以及元素中的字符数据等事件。当遇到这些事件是,XML解析器会调用ContentHandler接口中相应的方法来相应该事件。

ContentHandler接口的方法有以下几种:

void startDocument()

void endDocument()

void startElement(String uri,String localName,String qName,Attributes atts)

void endElement(String uri,String localName,String qName)

void characters(char[] ch,int start,ing length)

 

四、SAX解析

例子程序很简单,在Tomcat上放入一个xml文件,调用程序下载下来,并解析。

 

目录结构如下:

          

test.xml

<?xml version="1.0" encoding="UTF-8"?>
<teachers>
	<teacher id="1">
		<name>bauble</name>
		<sex>男</sex>
		<subject>数学</subject>
	</teacher>
	<teacher id="2">
		<name>allorry</name>
		<sex>男</sex>
		<subject>英语</subject>
	</teacher>
	<teacher id="3">
		<name>lily</name>
		<sex>女</sex>
		<subject>语文</subject>
	</teacher>
</teachers>

  XMLActivity.java

package com.android.activity;

import java.io.StringReader;

import javax.xml.parsers.SAXParserFactory;

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;

import com.android.utils.HttpDownloader;

public class XMLActivity extends Activity {
	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{

		public void onClick(View v) {
			HttpDownloader hd = new HttpDownloader();
			String resultStr = hd.download("http://1.56.227.150:8080/download/test.xml");
			System.out.println(resultStr);
			try{
				//创建一个SAXParserFactory解析器工厂
				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.java

package com.android.activity;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class MyContentHandler extends DefaultHandler {
	String name,sex, subject;
	String tagName;

	public void startDocument() throws SAXException {
		System.out.println("-----------begin-----------");
	}

	public void endDocument() throws SAXException {
		System.out.println("-------------end-----------");
	}

	/**
	 * namespaceURI当前正在解析的标签的命名空间,localName没有前缀的值,qName有前缀的值,如c:out
	 * attributes表示属性,可有多个
	 */
	public void startElement(String namespaceURI, String localName,
			String qName, Attributes attr) throws SAXException {
		tagName = localName;
		if (localName.equals("teacher")) {
			//获取标签的全部属性
			for (int i = 0; i < attr.getLength(); i++) {
				System.out.println(attr.getLocalName(i) + "=" + attr.getValue(i));
			}
		}
	}

	public void endElement(String namespaceURI, String localName, String qName)
			throws SAXException {
		//在teacher标签解析完之后,会打印出所有得到的数据
		tagName = "";
		if (localName.equals("teacher")) {
			this.print();
		}
	}
	
	/**
	 * 该方法用于得到标签中的内容
	 * ch:标签中的内容存储到一个char型数组中,start:读取到的数组是从ch中的哪一位开始,length:有多长
	 */
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if (tagName.equals("name")){
			name = new String(ch, start, length);
		}else if (tagName.equals("sex")){
			sex = new String(ch, start, length);
		}else if (tagName.equals("subject")){
			subject = new String(ch, start, length);
		}
	}

	private void print() {
		System.out.print("name: ");
		System.out.println(name);
		System.out.print("sex: ");
		System.out.println(sex);
		System.out.print("subject: ");
		System.out.println(subject);
		System.out.println();
	}

}

  FileUtils.java

package com.android.utils;

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 writeToSDFromInput(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;
	}

}

  HttpDownloader.java

package com.android.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpDownloader {
	
	private URL url = null;
	
	/**
	 * 根据URL下载文件,前提是这个文件当中的内容是文本,函数的返回值就是文件当中的内容
	 * 1.创建一个URL对象
	 * 2.通过URL对象,创建一个HttpURLConnection对象
	 * 3.得到InputStram
	 * 4.从InputStream当中读取数据
	 * @param url
	 * @return
	 */
	public String download(String fileURL){
		
		StringBuffer stringBuffer = new StringBuffer();
		String line = null;
		BufferedReader buffer = null;
		try{
			//创建一个URL对象
			url = new URL(fileURL);
			//创建一个HTTP连接
			HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
			//使用IO流读取数据
			buffer = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
			while((line = buffer.readLine()) != null){
				stringBuffer.append(line);
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try{
				buffer.close();
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		
		return stringBuffer.toString();
	}
	
	/**
	 * 可以下载任意文件,返回-1代表下载出错,返回0代表下载成功,返回1代表文件已存在
	 * 参数为源URL地址、目标路径、文件名
	 */
	public int downloadFile(String fileURL,String path,String fileName){
		InputStream inputStream = null;
		try {
			FileUtils fileUtils = new FileUtils();
			
			if (fileUtils.isFileExist(path + fileName)) {
				return 1;
			} else {
				url = new URL(fileURL);
				HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
				inputStream = urlConnection.getInputStream();
				File resultFile = fileUtils.writeToSDFromInput(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;
	}
}

  运行结果:


程序界面:


 

 

 

 

 

 

 

 

 

 

 

 

  • 大小: 42.1 KB
  • 大小: 13 KB
  • 大小: 23.2 KB
  • 大小: 23.3 KB
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    黑马安卓基础day2

    黑马安卓基础 总共8天教程。...21_采用pull解析 解析xml文件.avi 20_知识点补充.avi 22_通过断点调试分析pull解析的原理.avi 23_生成xml文件.avi 24_如何创建数据库oncreate和onupdate方法.avi 25_数据库的增删改查.avi

    8天快速掌握Android系列视频之04_开发与 运行(卸载)第一个ANDROID应用

    息,12_文件的保存与读取,13_文件的操作模式,14_把文件存放在SDCard,15_采用Pull解析器解析和生成XML内容,16_采 用SharedPreferences保存用户偏好设置参数,17_创建数据库与完成数据添删改查,18_在SQLite中...

    8天快速掌握Android系列视频之07_查看应用输出的错误信息 与如何部署应用到真实手机

    息,12_文件的保存与读取,13_文件的操作模式,14_把文件存放在SDCard,15_采用Pull解析器解析和生成XML内容,16_采 用SharedPreferences保存用户偏好设置参数,17_创建数据库与完成数据添删改查,18_在SQLite中...

    精通Android3 源代码

    《精通Android 3 源代码》是一本深入解析Android 3.x系统开发的专业书籍,其随书源代码涵盖了多个关键领域,旨在帮助开发者提升在Android平台上的编程技能。通过这些源代码,读者可以深入了解Android应用程序的设计...

    android访问web应用并返回xml字符串

    总的来说,Android通过HttpURLConnection实现GET请求,结合XMLPullParser解析返回的XML数据,可以实现与Web应用的高效交互。在实际开发中,你可能还需要考虑错误处理、网络权限、异步执行(如使用AsyncTask或...

    android-sdk\platforms\android-19

    《深入解析Android SDK Platforms android-19》 在Android开发领域,`android-sdk\platforms\android-19`是一个至关重要的目录,它包含了Android 4.4 KitKat(API Level 19)的系统框架和相关的开发资源。这个版本...

    android color.xml

    在Android开发中,颜色资源文件(`colors.xml`)扮演着非常重要的角色。通过定义颜色资源,开发者可以轻松地为应用程序设置统一的颜色风格,并且方便后期维护与修改。颜色资源文件通常位于项目的`res/values/`目录下...

    Android SDK 19-31的Build tools

    6. **Apache相关**:Apache是一个开源项目,其许多工具和技术在Android开发中被广泛使用,如HTTP客户端库、XML解析库等。Apache HTTP库在早期版本中是Android SDK的一部分,但在后来的安全考虑下,从Android 6.0 ...

    12-19_.zip_源码

    这可能是一个项目的布局文件,比如用户界面的设计蓝图,或者是某种特定格式的配置文件,如XML布局文件(在Android开发中常见)。 综合以上信息,我们可以推测这是一个与Linux开发相关的项目,其中包含了源代码和...

    Android_api_demo

    本文档旨在全面解析 Android API Demo 中的各种案例,通过具体实例深入理解 Android 开发中的关键技术和应用实践。该文档覆盖了从简单的用户界面设计到复杂的后台服务管理等多个方面,为开发者提供了丰富的实践指导...

    android_wireless_application_development_3rd_edition 卷II 源代码

    9. **Chapter 12 - Web APIs**: 网络API章节会涵盖如何在Android中使用HttpURLConnection或Volley库进行网络请求,处理JSON或XML数据,以及实现WebSocket通信,为应用添加网络功能。 10. **Chapter 17 - Hardware ...

    svg2vector:SVG图像到Android矢量可绘制XML资源文件的在线批处理转换器

    - 在导入到Android Studio之前,确保项目的build.gradle文件已启用vectorDrawables.useSupportLibrary = true,以便支持API 19以下的设备。 总之,"svg2vector"工具为Android开发者提供了一种便捷的方式,将SVG资源...

    疯狂Android讲义(第三版)17-19章源码,内附19章详细使用说明

    - **文件存储**:了解Android中如何读写文件,包括内部存储和外部存储。 3. **第19章:服务器端开发与集成**: - **RESTful API设计**:掌握RESTful架构风格,如何设计符合REST原则的HTTP接口。 - **Web服务框架...

    疯狂android讲义源码11-19章

    - 文件系统:了解Android的文件操作,包括读写文件、创建目录等。 - SQLite数据库:创建数据库,执行SQL语句,学习ContentProvider进行数据共享。 4. **Chapter 14:Android网络编程** - HTTP通信:使用...

    android-apk-parser:用于 J2EE 的 Android APK 文件解析器

    使用Android Interface等工具解析APK文件获取manifest。使用android api做原型实现的APK包解析,用于J2SE环境中读取APK做验证。 特征 在 apk 中解码 manifest.xml。 解码资源。 在 apk 中。 构建包信息。 从清单...

    mars android 源代码

    在Android开发中,Mars老师可能讲解了如何使用Android Studio进行项目构建,包括设置环境、创建新项目、理解和使用布局XML文件。此外,他还可能讲解了Activity的生命周期、Intent的概念以及Service的使用,这些都是...

    android手机短信管理系统论文 完整版

    4.1.3 更新Ec1ipse并下载ADT(Android开发插件) 19 4.1.4 使用Ec1ipse开发Android应用 20 4.2 短信管理软件程序中各类组件 21 4.2.1 Package Explorer中的组件 22 4.2.2 应用程序的资源 22 4.2.3 布局文件main.xml 22...

    基于Android平台的星座查询软件设计

    4.1.4使用Ec1ipse开发Android应用 19 4.2“星座”查询软件程序中各类组件 20 4.2.1 Package Explorer中的组件 20 4.2.2应用程序的资源 21 4.2.3布局文件main.xml 21 4.2.4 AndroidManifest.xml 21 4.3手机“星座”...

Global site tag (gtag.js) - Google Analytics