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. Jsp、Servlet

    1 forward.redirect forward 转发是服务器行为,浏览器根本不知道服务器发送的内容是从哪儿来,所以它的地址栏中还是原来的地址. redirect 重定向是客户端行为.redire ...

  2. Warning: Unable to send packet: Error with PF_PACKET send() [11]: Message too long (errno = 90)

    今天在使用tcpreplay重放流量时,发现有的数据包没有发送成功: Warning: Unable to send packet: Error with PF_PACKET send() [215] ...

  3. Sql server 事务 存储过程

    事务( Transaction )是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位. 通过事务,SQL Server能将逻辑相关的一组操作绑定在一起, ...

  4. SQL中的Update、delete与inner join 联合使用

    Update XXX set XXX where 这种写法大家肯定都知道,才发现update和delete居然支持inner join的update方式,太神奇了. update的格式是 update ...

  5. 我在网站开发中经常用到的几个js函数01

    这是我在最近的一个网站项目中频繁用到的几个js函数,非常实用.包括:1.js获取地址栏参数:2.返回cookies字符串中指定键对应的值:3.json格式的日期转换为正常格式4.清除cookie. / ...

  6. Oracle语句优化规则(一)

    1. 选用适合的ORACLE优化器     ORACLE的优化器共有3种:    a. RULE (基于规则)   b. COST (基于成本) c. CHOOSE (选择性)     设置缺省的优化 ...

  7. easyui好例子,值得借鉴

    http://www.cnblogs.com/wuhuacong/p/3317223.html

  8. spoj 3871 gcd extreme

    题目大意给出一个n,求sum(gcd(i,j),<i<j<=n); 可以明显的看出来s[n]=s[n-]+f[n]; f[n]=sum(gcd(i,n),<i<n); 现 ...

  9. 5.对象创建型模式-原型PROTOTYPE

    原型:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型实现:1.用于创建对象的具体类必须实现clone()操作,用于对象克隆自己以生成新的对象.下面通过原型来实现一个抽象工厂Ma ...

  10. sql中select语句的逻辑执行顺序

    下面是SELECT语句的逻辑执行顺序: FROMONJOINWHEREGROUP BYWITH CUBE or WITH ROLLUPHAVINGSELECTDISTINCTORDER BYTOP M ...