Android系统开发之XML文件的解析

我们知道Http在网络传输中的数据组织方式有三种分别为:XML方式、HTML方式、JSON方式。其中XML为可扩展标记语言,如下:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="23">
<name>Jack</name>
<age>23</age>
</person>
<person id="20">
<name>Tom</name>
<age>25</age>
</person>
</persons>

Android中解析XML数据有三种方式:分别为
DOM、SAX、和XMLPULL。下面我们分别介绍这三种方式:

1)SAX(org.xml.sax) 方式

Simple API for XML,以事件的形式通知程序,对XML进行解析。SAX是一种以事件驱动的XML api,由他定义的事件流可以指定从解析器传到专门的处理程序的代码的XML结构,特点是:解析速度快,占用内存少。

代码流程:
1) 定义一个类继承于DefaultHandler,重写其startDocument、startElement、endDocument、endElement、characters三个方法。

public class MySaxHandler extends DefaultHandler {

	private HashMap<String, String> map = null;	// 存储单个解析的完整对象
private List<HashMap<String, String>> list = null; // 存储所有的解析对象 private String currentTag = null; // 正在解析的元素的标签
private String currentValues = null; // 解析当前元素的值
private String nodeName = null; // 解析当前的节点名称 public MySaxHandler(String nodeName) {
// TODO Auto-generated constructor stub
this.nodeName = nodeName;
} /**
* @return the list
*/
public List<HashMap<String, String>> getList() {
return list;
} @Override
public void startDocument() throws SAXException {
// 当读到第一个开始标签的时候触发
list = new ArrayList<HashMap<String,String>>();
} @Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// 当遇到文档的开头的时候触发
if(qName.equals(nodeName)) {
map = new HashMap<String, String>();
}
if(attributes != null && map != null) {
for(int i = 0; i < attributes.getLength(); i++) {
map.put(attributes.getQName(i),attributes.getValue(i));
}
}
currentTag = qName;
} @Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
} @Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// 遇到结束标记的时候调用
if(qName.equals(nodeName)) {
list.add(map);
map = null;
}
} @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// 处理XML文件所读取到的内容
if(currentTag != null && map != null) {
currentValues = new String(ch, start, length);
if(currentValues != null && !currentValues.trim().equals("") &&
!currentValues.trim().equals("\n")) {
map.put(currentTag, currentValues);
}
}
currentTag = null; // 当前节点对应的值和标签设置为空
currentValues = null;
}
}

2) 定义一个处理流的类SaxService,调用SAXParserFactory创建一个SAXParser从输入流解析XML文件。

public class SaxService {

	public static List<HashMap<String, String>> readXml(
InputStream inputStream, String nodeName) {
try {
// 创建一个解析XML的工厂对象
SAXParserFactory spFactory = SAXParserFactory.newInstance();
SAXParser parser = spFactory.newSAXParser();
MySaxHandler handler = new MySaxHandler(nodeName);
parser.parse(inputStream, handler);
inputStream.close();
return handler.getList(); } catch (Exception e) {
// TODO: handle exception
}
return null;
} public SaxService() {
}
}

3) 定义一个测试类Test,读取文件FileInputStream调用SaxService.readXml()处理。

public class Test {

	/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
File file = new File("C://test.xml");
if(file.exists()) {
FileInputStream inputStream = new FileInputStream(file);
List<HashMap<String, String>> list = SaxService.readXml(inputStream, "person");
for(HashMap<String, String> map : list) {
System.out.println(map.toString());
}
} else {
System.out.println("file is not exitst");
} } catch (Exception e) {
// TODO: handle exception
}
}
}

2)DOM方式

DOM是一种用于XML文档对象模型,可用于直接访问XML文档的各个部位,在DOM中文档被模拟为树桩
其中XML语法的每一个组成部分都表示一个节点,DOM允许用户遍历文档树,从父节点到子节点
和兄弟节点,并利用某节点类型特有的属性。

节点类型:
       整个文档是一个节点文档,每个xml标签是一个元素节点,包含在XML元素中的文本是文本节点每个XML属性是一个属性节点。

public class DomXml {

	public DomXml() {
// TODO Auto-generated constructor stub
} public List<Person> getPersons(InputStream inputStream) throws Exception {
List<Person> list = new ArrayList<Person>();
// 创建一个document解析的工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inputStream);
Element element = document.getDocumentElement();
NodeList personNodeList = element.getElementsByTagName("person");
for(int i = 0; i < personNodeList.getLength(); i++) {
Element personElement = (Element)personNodeList.item(i);
Person person = new Person();
person.setId(Integer.parseInt(personElement.getAttribute("id")));
NodeList childNodes = personElement.getChildNodes();
for(int j = 0; j < childNodes.getLength(); j++) {
if(childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {
if("name".equals(childNodes.item(j).getNodeName())) {
person.setName(childNodes.item(j).getFirstChild().getNodeValue());
} else if("age".equals(childNodes.item(j).getNodeName())) {
person.setAge(Integer.parseInt(childNodes.item(j).getFirstChild().getNodeValue()));
}
}
}
list.add(person);
}
return list;
} public static void main(String[] args) throws Exception { FileInputStream inputStream = new FileInputStream("C://test.xml");
DomXml domXml = new DomXml();
List<Person> list = domXml.getPersons(inputStream);
for(Person person : list) {
System.out.println(person.toString());
}
}
}

3)XMLPULL(org.xmlpull.v1) 方式

1) 新建一个项目,导入kxml2-2.2.2.jar包,创建一个描述信息Person类。

        kxml2-2.2.2.jar包下载地址:http://download.csdn.net/detail/llping2010/6270791

public class Person {

	private String name;
private int age;
private int id; public Person() {
// TODO Auto-generated constructor stub
} public Person(String name, int age, int id) {
super();
this.name = name;
this.age = age;
this.id = id;
} /**
* @return the name
*/
public String getName() {
return name;
} /**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
} /**
* @return the age
*/
public int getAge() {
return age;
} /**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
} /**
* @return the id
*/
public int getId() {
return id;
} /**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
} /* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", id=" + id + "]";
}
}

2) 创建一个PullXmlTools类,根据inputStream获取输入调用XmlPullParserFactoty解析XML将解析的数据保存到List<Person> list中返回。

public class PullXmlTools {

	public PullXmlTools() {
// TODO Auto-generated constructor stub
} public static List<Person> parseXml(InputStream inputStream, String encode) throws XmlPullParserException, IOException {
List<Person> list = null;
Person person = null; // 创建一个xml解析的工厂
XmlPullParserFactory xppFactovy = XmlPullParserFactory.newInstance();
// 获得xml解析类的引用
XmlPullParser parser = xppFactovy.newPullParser();
// 设置parser解析器的输入和编码类型
parser.setInput(inputStream, encode);
int eventType = parser.getEventType();
while(eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
list = new ArrayList<Person>();
break;
case XmlPullParser.START_TAG:
if("person".equals(parser.getName())) {
person = new Person();
int id = Integer.parseInt(parser.getAttributeName(0));
person.setId(id);
} else if("name".equals(parser.getName())) {
String name = parser.nextText();
person.setName(name);
} else if ("age".equals(parser.getName())) {
int age = Integer.parseInt(parser.nextText());
person.setAge(age);
}
break; case XmlPullParser.END_TAG:
if("person".equals(parser.getName())) {
list.add(person);
person = null;
}
break;
}
eventType = parser.getEventType();
}
return list;
}
}

3) 定义一个测试类Test,读取文件FileInputStream调用PullXmlTools.parserXml()处理。

public class Test {

	/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub try {
File file = new File("C://test.xml");
if(file.exists()) {
FileInputStream inputStream = new FileInputStream(file);
List<Person> list = PullXmlTools.parseXml(inputStream, "utf-8");
for(Person person : list) {
System.out.println(person.toString());
}
} else {
System.out.println("file is not exitst");
} } catch (Exception e) {
// TODO: handle exception
}
}
}

[置顶] Android开发之XML文件的解析的更多相关文章

  1. [置顶] Android开发之serviceManager分析

    Android 开发之serviceManager分析 在Android系统中用到最多的通信机制就是Binder,Binder主要由Client.Server.ServiceManager和Binde ...

  2. [置顶] Android开发之MediaPlayerService服务详解(一)

    前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState.ProcessState负责打开Binder 驱动,每个进程只有一个.而 IPCThre ...

  3. [置顶] Android开发之ProcessState和IPCThreadState类分析

    在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个 进程只有一个对象,这个对象负责打开Binde ...

  4. [置顶] Android开发之Thread类分析

    在我们Linux系统中创建线程函数为:pthread_create(),在Android中我们为线程封装了一个类Thread,实际调用的还是pthread_create() 当我们想创建线程的时候,只 ...

  5. Android开发之XML的创建和解析

    参考:http://blog.csdn.net/pi9nc/article/details/9320413 XML文件的解析,代码: public void click(View v) { Input ...

  6. Android开发之R文件丢失

    在进行android开发的过程中,不知道怎么回事,代码中出现R代码有红色波浪线了,于是进行了clean,结果还是有红色波浪线,然后就重启了eclipse,重启以后还是这个样子,随后发现工程的R文件丢失 ...

  7. [置顶] Android学习系列-把文件保存到SD卡上面(6)

    Android学习系列-把文件保存到SD卡上面(5) 一般多媒体文件,大文件需要保存到SD卡中.关键点如下: 1,SD卡保存目录:mnt/sdcard,一般采用Environment.getExter ...

  8. Android开发之httpclient文件上传实现

    文件上传可能是一个比較耗时的操作,假设为上传操作带上进度提示则能够更好的提高用户体验,最后效果例如以下图: 项目源代码:http://download.csdn.net/detail/shinay/4 ...

  9. Android开发之assets文件夹中资源的获取

    assets中的文件都是保持原始的文件格式,需要使用AssetManager以字节流的形式读取出来 步骤: 1. 先在Activity里面调用getAssets() 来获取AssetManager引用 ...

随机推荐

  1. hdu4336 Card Collector 状态压缩dp

    Card Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...

  2. FastReport配置打印预览button_C++

    如需转载请标明出处:http://blog.csdn.net/itas109 FastReport採用C++方式.配置打印预览选项 //打印预览 //配置打印预览选项 pReport->Prev ...

  3. ActionScript3游戏中的图像编程(连载十七)

    总文件夹:http://blog.csdn.net/iloveas2014/article/details/38304477 1.3.3 HSB与RGB之间的互转公式及HSL和HSV对色彩属性理解的异 ...

  4. C# MyNewQueue 消息队列

    C# using System; using System.Messaging; using System.Drawing; using System.IO; namespace MyProject ...

  5. Android中的一些基础知识(三)

    最近在回顾Android的基础知识,就把一些常见的知识点整理一下,以后忘了也可以翻出来看一看. 在TextView中显示图像(使用< img>标签) 在TextView中显示图片的方法有许 ...

  6. js 特效 手风琴效果

    $(document).ready(function(){ //定义展开的块 var lastBlock = $('#a1'); //展开的块的宽度 var maxWidth = 406; //折叠的 ...

  7. linux c: 静态库和动态库的生成和使用

    场景: main函数需要两个接口,一个求和函数,一个打印函数. int sum(int i, int j); 求两个int数字的和. void show(int i, char* name); 打印i ...

  8. ajax.js

    /**通用ajax服务的定义对象 * services可以是单个服务对象,也可以是service服务数组 * 具体服务的定义请参考appendServices成员函数 */ function Serv ...

  9. Qt Creator插件工作流程代码走读

    Qt Creator有个很风骚的插件管理器PluginManager,还有个很骚包的插件说明PluginSpec.基本上,所有的Qt程序的入口都是传统的C程序一样,代码流程从main()函数开始.  ...

  10. F#实现的单链表(函数式的思想)

    // 在 http://fsharp.net 上了解有关 F# 的更多信息 // 请参阅“F# 教程”项目以获取更多帮助. type list = | Nil | Cons of int * list ...