解析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. Api项目压力测试知识荟萃

    并发用户.在线用户和注册用户以及彼此之间的换算方法(估算模型).系统的最大并发用户数根据注册用户数来获得,换算方法一般是注册总人数的5%-20%之间:系统的并发数根据在线人数来获得,换算方法一般是在3 ...

  2. Ubuntu下添加Eclipse快捷方式

    首先是在/usr/share/applications下创建eclipse.desktop文件 1. 创建并编辑eclipse.desktop sudo vim /usr/share/applicat ...

  3. 【CSS3】Advanced11:Media Queries

    1.Browser-size specific CSS @media screen and (max/min-width:1000px){} 2.Orientation-specific CSS? @ ...

  4. Java笔记(十)……面向对象II封装(Encapsulation)

    封装概念 封装: 是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. 好处: 将变化隔离. 便于使用. 提高重用性. 提高安全性. 封装原则: 将不需要对外提供的内容都隐藏起来. 把属性都隐藏,提 ...

  5. apple公司的潮起潮落——浪潮之巅

    今天代码写不下去的时候,躺在床上看了一下浪潮之巅.翻了一下书目,选了apple公司那一篇. 其实apple公司的事情我已经听过不止一次了,但是每次都是间间断断地听说,都没有系统地了解它到底是经历了怎么 ...

  6. 如何进行Hadoop二次开发指导视频下载

    本视频适合对Java有一定了解,熟悉java se的Hadoop爱好者,想对Hadoop进行二次开发.下面是以伪分布为例: 想对Hadoop二次开发:一.首先需要Hadoop和Java之间搭建Ecli ...

  7. redis在.NET下的使用

    windows SEVER包:http://code.google.com/p/servicestack/wiki/RedisWindowsDownload windows仅用来测试,性能不如在lin ...

  8. 2015 CCPC-C-The Battle of Chibi (UESTC 1217)(动态规划+树状数组)

    赛后当天学长就说了树状数组,结果在一个星期后赖床时才有了一点点思路…… 因为无法提交,不确定是否正确..嗯..有错希望指出,谢谢... 嗯..已经A了..提交地址http://acm.uestc.ed ...

  9. hdu 3722 Card Game 二分图的最大权匹配

    题目可以转化为2个集合,x集合和y集合,其中的元素是1-n个字符串. 首先预处理点与点的边权,然后直接用二分图的最大权匹配模板. #include<stdio.h> #include< ...

  10. JSON基本操作

    import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.J ...