解析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. BrnShop开源网上商城第五讲:自定义视图引擎

    今天这篇博文主要讲解自定义视图引擎,大家都知道在asp.net mvc框架中默认自带一个Razor视图引擎,除此之外我们也可以自定义自己的视图引擎,只需要实现IViewEngine接口,接口定义如下: ...

  2. js打印的两种方法

    第一种: <!--startprint1-->……打印的内容放在这里…… <!--endprint1--> //打印 function preview(DivID) { ) { ...

  3. 字典转模型第三方框架---MJExtension

    字典转模型第三方框架 Mantle 所有模型都必须继承自MTModel JSONModel 所有模型都必须继承自JSONModel MJExtension 不需要强制继承任何其他类 设计框架需要考虑的 ...

  4. 【原】Redis基本操作

    Redis基本操作 遍历操作 Pub-Sub server Lua脚本 Redis中的这些操作都是不分大小写的. 除了针对于具体类型的具体操作.还有一些其他操作. 遍历操作 SCAN cursor [ ...

  5. aix挂载centos 的nfs

    centos作为服务器,提供nfs文件系统,aix作为客户端,挂载centos的指定目录 (1)NFS的安装配置:centos 5 : yum -y install nfs-utils portmap ...

  6. 解读(GoogLeNet)Going deeper with convolutions

    (GoogLeNet)Going deeper with convolutions Inception结构 目前最直接提升DNN效果的方法是increasing their size,这里的size包 ...

  7. SecureCRTPortable的安装和使用

    玩玩这个远程连接软件,是个绿色软件. 别人已经做好了的. 解压之后, 下面,软件展示下, 这会默认去打开, 为了,方便,使用,放到桌面,作为快捷方式 成功

  8. 引入less报错解决方法以及浏览器设计不同的地方

    XMLHttpRequest cannot load file:///C:/Users/PAXST/Desktop/805/first.less. Cross origin requests are ...

  9. struts2设置<s:select>默认选中项的方法

    struts2的select标签中,常用的有以下几个属性:(1)struts2中的select 标签中,必须设置的属性只有一个,即是list.(2)select标签的list中必须有值,不然会报错.如 ...

  10. MySQL check the manual that corresponds to your MySQL server version for the right syntax错误

    地化GO的时候一直遇到一个错误就是check the manual that corresponds to your MySQL server version for the right syntax ...