解析XML有三种方式:Dom、SAX、Pull

其中pull解析器运行方式与SAX类似。

我们首先认识pull解析器:http://developer.android.com/intl/zh-cn/reference/org/xmlpull/v1/XmlPullParser.html

Th following event types are seen by next()

START_TAG
An XML start tag was read.
TEXT
Text content was read; the text content can be retrieved using the getText() method. (when in validating mode next() will not report ignorable whitespace, use nextToken() instead)
END_TAG
An end tag was read
END_DOCUMENT
No more events are available

1.解析
获取解析器: Xml.newPullParser()
设置输入流: parser.setInput(InputStream, String)
获取当前事件类型: parser.getEventType(), 
获取下一个事件类型: parser.next()
获取标签名: parser.getName()
获取属性值: parser.getAttributeValue(int)、getAttributeValue(null,"id")
获取下一个文本: parser.nextText()
2.生成
获取解析器:
设置输出流:
开始文档:
结束文档:
开启标签:
结束标签:
设置属性:
设置文本:

下面我们用一个实例来看看:

在src下面新建presons.xml

 <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<persons>
<person id="1">
<name>范冰冰</name>
<age>31</age>
</person>
<person id="2">
<name>林志玲</name>
<age>38</age>
</person>
<person id="3">
<name>杨幂</name>
<age>26</age>
</person>
</persons>

然后在包中创建Person.java、PersonService.java、PersonTest.java

 public class PersonService {

     public List<Person> loadPersons(InputStream in) throws Exception {
XmlPullParser parser = Xml.newPullParser(); // 获取解析器
parser.setInput(in, "UTF-8"); // 设置输入流, 指定码表 ArrayList<Person> persons = new ArrayList<Person>();
Person p = null; // 最初type赋值为第一个事件, 只要不是文档结束就循环, 每次循环后解析下一个事件
for (int type = parser.getEventType(); type != XmlPullParser.END_DOCUMENT; type = parser.next()) {
if (type == XmlPullParser.START_TAG) { // 如果遇到了标签开始事件
if (parser.getName().equals("person")) { // 如果标签名为"person"
p = new Person(); // 创建对象
String id = parser.getAttributeValue(0); // 获取第一个属性的属性值
p.setId(Integer.parseInt(id)); // 转为int, 设置id
persons.add(p); // 装入集合
} else if (parser.getName().equals("name")) { // 如果标签名为"name"
String name = parser.nextText(); // 获取下一个文本
p.setName(name); // 设置name
} else if (parser.getName().equals("age")) { // 如果标签名为"age"
String age = parser.nextText(); // 获取下一个文本
p.setAge(Integer.parseInt(age)); // 设置age
}
}
} return persons;
} public void savePersons(List<Person> persons, OutputStream out) throws IOException {
XmlSerializer serializer = Xml.newSerializer(); // 获取序列化工具
serializer.setOutput(out, "UTF-8"); // 设置输出流, 指定码表 serializer.startDocument("UTF-8", true); // 开始文档
serializer.startTag(null, "persons"); // 开始标签 for (Person p : persons) {
serializer.startTag(null, "person");
serializer.attribute(null, "id", p.getId().toString()); // 设置属性 serializer.startTag(null, "name");
serializer.text(p.getName()); // 设置文本
serializer.endTag(null, "name"); serializer.startTag(null, "age");
serializer.text(p.getAge().toString());
serializer.endTag(null, "age"); serializer.endTag(null, "person");
} serializer.endTag(null, "persons"); // 结束标签
serializer.endDocument(); // 结束文档
} }
 public class PersonTest extends AndroidTestCase {

     public void testLoad() throws Exception {
PersonService service = new PersonService();
InputStream in = PersonTest.class.getClassLoader().getResourceAsStream("persons.xml");
List<Person> persons = service.loadPersons(in);
for (Person p : persons)
System.out.println(p); Person p = new Person(4, "张红", 18);
persons.add(p);
service.savePersons(persons, new FileOutputStream("/mnt/sdcard/persons.xml"));
} }
 public class Person {
private Integer id;
private String name;
private Integer age; public Person() {
super();
} public Person(Integer id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} @Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
} }

然后运行程序,可在日志中看到解析的数据。

(最好添加一个日志信息的过滤器,专门查看System.out输出的信息)

以上部分只讲解了PULL解析,下面我们用这三种解析方式解析同一个XML文件(在代码中注释讲解)。

需要我们解析的XML内容如下:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<persons>
<person id="1">
<name>saber</name>
<age>20</age>
</person>
<person id="2">
<name>Archer</name>
<age>21</age>
</person>
<person id="3">
<name>Lancer</name>
<age>26</age>
</person>
</persons>

其存放在名为“assets”的文件夹下,取名为“test”。

整个程序代码文件如下:

接下来,实现一个实体类,该类的属性应与XML文件对应,名为“Person.java”,其实现如下:

package com.topcsa.entity;

public class Person {
private Integer id;
private String name;
private Integer age; public Person() {
super();
} public Person(Integer id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} @Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
} }

名为“XmlUtils.java”的文件实现如下:

package com.topcsa.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import com.topcsa.entity.Person; import android.content.Context;
import android.util.Xml; public class XmlUtils { public List<Person> XmlPullParse(Context con) {
InputStream inputStream = null;
ArrayList<Person> persons = new ArrayList<Person>();
Person p = null;
XmlPullParser parser = Xml.newPullParser(); // 获取解析器
// 得到文件流,并设置编码方式
try {
inputStream = con.getResources().getAssets().open("test.xml");
parser.setInput(inputStream, "UTF-8"); // 设置输入流, 指定码表
// 最初type赋值为第一个事件, 只要不是文档结束就循环, 每次循环后解析下一个事件
for (int type = parser.getEventType(); type != XmlPullParser.END_DOCUMENT; type = parser
.next()) {
if (type == XmlPullParser.START_TAG) { // 如果遇到了标签开始事件
if (parser.getName().equals("person")) { // 如果标签名为"person"
p = new Person(); // 创建对象
String id = parser.getAttributeValue(0); // 获取第一个属性的属性值
p.setId(Integer.parseInt(id)); // 转为int, 设置id
persons.add(p); // 装入集合
} else if (parser.getName().equals("name")) { // 如果标签名为"name"
String name = parser.nextText(); // 获取下一个文本
p.setName(name); // 设置name
} else if (parser.getName().equals("age")) { // 如果标签名为"age"
String age = parser.nextText(); // 获取下一个文本
p.setAge(Integer.parseInt(age)); // 设置age
} }
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return persons; } public List<Person> XmlSaxParse(Context con) { List<Person> persons = null;
// 建立Sax解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
// 取得SaxParser对象
SAXParser parser = factory.newSAXParser();
// 获取事件源
XMLReader xmlReader = parser.getXMLReader();
// 设置sax解析器
PersonSaxHandler handler = new PersonSaxHandler();
xmlReader.setContentHandler(handler);
// 解析xml文档
xmlReader.parse(new InputSource(con.getAssets().open("test.xml")));
persons = handler.getPersons();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} return persons; } public List<Person> XmlDomParse(Context con) {
List<Person> persons = new ArrayList<Person>();
DocumentBuilderFactory factory = null;
DocumentBuilder builder = null;
Document document = null;
InputStream inputStream = null;
// 建立DocumentBuilderFactory对象,用于取得DocumentBuilder
factory = DocumentBuilderFactory.newInstance();
try {
// 找到XML文档
inputStream = con.getResources().getAssets().open("test.xml");
// 通过DocumentBuilderFactory取得DocumentBuilder
builder = factory.newDocumentBuilder();
// 读取指定路径的XML文件
document = builder.parse(inputStream);
// 找到根Element
Element root = document.getDocumentElement();
NodeList nodes = root.getElementsByTagName("person");
// 遍历所有根节点下的子节点,persons下的所有person
Person person = null;
for (int i = 0; i < nodes.getLength(); i++) {
person = new Person();
// 获取person元素节点
Element personElement = (Element) (nodes.item(i));
// 获取person中id属性值
person.setId(Integer.parseInt(personElement.getAttribute("id")));
// 获取person下name标签
Element personName = (Element) personElement
.getElementsByTagName("name").item(0);
person.setName(personName.getFirstChild().getNodeValue());
// 获取person下age标签
Element personAge = (Element) personElement
.getElementsByTagName("age").item(0);
person.setAge(Integer.parseInt(personAge.getFirstChild()
.getNodeValue()));
persons.add(person);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return persons; } //Sax解析方式需要的类
class PersonSaxHandler extends DefaultHandler { private List<Person> list = null;
private String elementName = null;
private Person person = null; @Override
public void startDocument() throws SAXException {// 文档开始,实例化集合
// TODO Auto-generated method stub
this.list = new ArrayList<Person>();
} // 元素开始
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
localName = localName.toLowerCase().trim();
// 如果读取的是person标签开始,则实例化Person
if (localName.equals("person")) {
this.person = new Person();
// 导航到person开始节点后
this.person.setId(Integer.parseInt(attributes.getValue("id")));
}
// 保存元素名称
this.elementName = localName;
} @Override
public void characters(char[] ch, int start, int length)// 获取元素类容
throws SAXException {
if (this.elementName != null) {// 表示有元素
String data = new String(ch, start, length);// 取得文字信息
if (this.elementName.equals("name")) {
this.person.setName(data);
} else if (this.elementName.equals("age")) {
this.person.setAge(Integer.parseInt(data));
}
}
} // 元素结尾
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (localName.equals("person")) {// 判断元素标记是"person"
this.list.add(this.person);// 向集合中保存数据
this.person = null;// 清空对象
}
this.elementName = null;// 青空元素标记
} public List<Person> getPersons() {// 取得全部集合
return this.list; }
} }

MainActivity的布局文件activity_main.xml实现如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <Button
android:id="@+id/btn_dom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dom解析" /> <Button
android:id="@+id/btn_sax"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sax解析" /> <Button
android:id="@+id/btn_pull"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pull解析" /> <TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> </LinearLayout>

MainActivity的实现如下:

package com.topcsa.zhj_test;

import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; import com.topcsa.entity.Person;
import com.topcsa.utils.XmlUtils; public class MainActivity extends Activity {
private XmlUtils xmlutils;
private List<Person> persons;
private StringBuffer sb;
private TextView tv; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnDom = (Button) findViewById(R.id.btn_dom);
Button btnSax = (Button) findViewById(R.id.btn_sax);
Button btnPull = (Button) findViewById(R.id.btn_pull);
xmlutils = new XmlUtils();
persons = new ArrayList<Person>();
sb = new StringBuffer(); btnDom.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
sb.append("Dom解析:");
persons = xmlutils.XmlDomParse(MainActivity.this);
for (int i = 0; i < persons.size(); i++) {
Person person = persons.get(i);
sb.append("姓名:" + person.getName() + ",id:"
+ person.getId() + ",年龄:" + person.getAge() + "; "); }
tv.setText(sb.toString());
}
});
btnSax.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
sb.append("Sax解析:");
persons = xmlutils.XmlSaxParse(MainActivity.this);
for (int i = 0; i < persons.size(); i++) {
Person person = persons.get(i);
sb.append("姓名:" + person.getName() + ",id:"
+ person.getId() + ",年龄:" + person.getAge() + "; "); }
tv.setText(sb.toString()); }
});
btnPull.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
sb.append("Pull解析:");
persons = xmlutils.XmlPullParse(MainActivity.this);
if (persons != null) {
System.out.println("不为空"+persons.size());
} else {
System.out.println("为空");
}
for (int i = 0; i < persons.size(); i++) {
Person person = persons.get(i);
sb.append("姓名:" + person.getName() + ",id:"
+ person.getId() + ",年龄:" + person.getAge() + "; "); }
tv.setText(sb.toString()); }
}); tv = (TextView) findViewById(R.id.tv); } }

最后程序运行如下:

Android XML解析的更多相关文章

  1. android XMl 解析神奇xstream 六: 把集合list 转化为 XML文档

    前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...

  2. android XMl 解析神奇xstream 五: 把复杂对象转换成 xml ,并写入SD卡中的xml文件

    前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...

  3. android XMl 解析神奇xstream 四: 将复杂的xml文件解析为对象

    前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...

  4. android XMl 解析神奇xstream 三: 把复杂对象转换成 xml

    前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...

  5. android XMl 解析神奇xstream 二: 把对象转换成xml

    前言:对xstream不理解的请看:android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 1.Javabeen 代码 packa ...

  6. Android] Android XML解析学习——方式比较

     [Android] Android XML解析学习——方式比较 (ZT)  分类: 嵌入式 (From:http://blog.csdn.net/ichliebephone/article/deta ...

  7. Android xml 解析

    XML 经常使用的三种解析方式: DOM: 所有载入到内存,生成一个树状结构,占用内存比較大. SAJ: 採用事件驱动,速度快,效率高,不支持回退. PULL:也是採用事件驱动,语法简洁. 步骤: 1 ...

  8. Android XML解析器的问题

    最近在项目中遇到了一个解析XML的问题,我们是用android自带的DOM解析器来解析XML的,但发现了一个android的问题,那就是在2.3的SDK上面,无法解析像<, >, 等字符串 ...

  9. android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件

    简介 XStream 是一个开源项目,一套简单实用的类库,用于序列化对象与 XML 对象之间的相互转换. 将 XML 文件内容解析为一个对象或将一个对象序列化为 XML 文件. 1.下载工具 xstr ...

  10. android XML解析器全解案例

    1.使用pull解析 package com.example.myxml; import java.io.InputStream; import java.util.ArrayList; import ...

随机推荐

  1. 基于WebForm+EasyUI的业务管理系统形成之旅 -- 系统设置(Ⅰ)

    上篇<基于WebForm+EasyUI的业务管理系统形成之旅 -- 总体介绍>,主要介绍系统总体的界面效果和用户体验UI设计. 在MVC.MVP大行其道的今天,写WebForm该系列篇章, ...

  2. tcxtreelist 控制单元格变颜色,或者行变颜色

    如果控制单元格变颜色,只需要把注释的放开就可以了, 也就是判断当前列,是否是你想让变颜色的列. 如果想整行变颜色, 则只需要注释下面的就可以了. procedure TfrmwpOrderSendin ...

  3. win7下安装 WINDRIVER.TORNADO.V2.2.FOR.ARM

    [风河VxWorks].WINDRIVER.TORNADO.V2.2.FOR.ARM下载 http://115.com/file/dlfo8zpy http://115.com/file/c4r01l ...

  4. [JCWC2005]Draw

    Einstein学起了画画,此人比较懒--,他希望用最少的笔画画出一张画...给定一个无向图,包含 n 个顶点(编号1~n),m 条边,求最少用多少笔可以画出图中所有的边 Input (draw.in ...

  5. wuzhicms后台菜单的添加

    红色部分都是从菜单管理处添加而来.只有少数是自定义的. 开发一个模块,首先就是菜单的管理.而,不需要的功能也可以在在菜单管理处隐藏或删除. 添加菜单:

  6. NOIP2015 斗地主(搜索+剪枝)

    4325: NOIP2015 斗地主 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 270  Solved: 192[Submit][Status] ...

  7. 【Java基础】final关键字总结

    Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使 ...

  8. 【Java基础】Java中的代码块

    什么是代码块 在Java中,用{}括起来的代码称之为代码块. 代码块分类 局部代码块:在局部变量位置且用{}括起来的代码,用于限制局部变量的生命周期. 构造代码块:在类中的成员变量位置并用{}括起来的 ...

  9. C 数据结构1——线性表分析(顺序存储、链式存储)

    之前是由于学校工作室招新,跟着大伙工作室招新训练营学习数据结构,那个时候,纯碎是小白(至少比现在白很多)那个时候,学习数据结构,真的是一脸茫然,虽然写出来了,但真的不知道在干嘛.调试过程中,各种bug ...

  10. HDU-4415 Assassin’s Creed 贪心

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4415 用贪心来解,开始分为两个集合的方法错了,没有考虑之间的相互影响,正确的姿势应该是这样的,分两种情 ...