[置顶] Android开发之XML文件的解析
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文件的解析的更多相关文章
- [置顶] Android开发之serviceManager分析
Android 开发之serviceManager分析 在Android系统中用到最多的通信机制就是Binder,Binder主要由Client.Server.ServiceManager和Binde ...
- [置顶] Android开发之MediaPlayerService服务详解(一)
前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState.ProcessState负责打开Binder 驱动,每个进程只有一个.而 IPCThre ...
- [置顶] Android开发之ProcessState和IPCThreadState类分析
在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个 进程只有一个对象,这个对象负责打开Binde ...
- [置顶] Android开发之Thread类分析
在我们Linux系统中创建线程函数为:pthread_create(),在Android中我们为线程封装了一个类Thread,实际调用的还是pthread_create() 当我们想创建线程的时候,只 ...
- Android开发之XML的创建和解析
参考:http://blog.csdn.net/pi9nc/article/details/9320413 XML文件的解析,代码: public void click(View v) { Input ...
- Android开发之R文件丢失
在进行android开发的过程中,不知道怎么回事,代码中出现R代码有红色波浪线了,于是进行了clean,结果还是有红色波浪线,然后就重启了eclipse,重启以后还是这个样子,随后发现工程的R文件丢失 ...
- [置顶] Android学习系列-把文件保存到SD卡上面(6)
Android学习系列-把文件保存到SD卡上面(5) 一般多媒体文件,大文件需要保存到SD卡中.关键点如下: 1,SD卡保存目录:mnt/sdcard,一般采用Environment.getExter ...
- Android开发之httpclient文件上传实现
文件上传可能是一个比較耗时的操作,假设为上传操作带上进度提示则能够更好的提高用户体验,最后效果例如以下图: 项目源代码:http://download.csdn.net/detail/shinay/4 ...
- Android开发之assets文件夹中资源的获取
assets中的文件都是保持原始的文件格式,需要使用AssetManager以字节流的形式读取出来 步骤: 1. 先在Activity里面调用getAssets() 来获取AssetManager引用 ...
随机推荐
- hdoj 1824 Let's go home(2-SAT)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1824 思路分析:该问题为2-SAT问题:需要注意逻辑推理的等价性: (1)题目第一个条件:每一个队或者 ...
- 先登录 在跳转到tabBar
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...
- C语言实验——一元二次方程Ⅱ
C语言实验--一元二次方程Ⅱ Time Limit: 1 Sec Memory Limit: 64 MB Submit: 169 Solved: 131 [Submit][Status][Web ...
- 赵雅智:service_startService生命周期
案例演示 布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xm ...
- [爬虫]通过url获取连接地址中的数据
1. 要想获取指定连接的数据,那么就得使用HtmlDocument对象,要想使用HtmlDocument对象就必需引用using HtmlAgilityPack; 2. 详细步骤如下: 步骤一 ...
- Flex中神奇的快速辅助 Ctrl+1
Adobe Flash Builder 中的快速辅助功能提供基于上下文的辅助,有助于您快速执行任务.通过快速辅助,可以在适用于当前代码段的操作列表中选择一个操作. 要调用快速辅助,请在编辑器的上下文菜 ...
- BZOJ 1800: [Ahoi2009]fly 飞行棋( 枚举 )
O(N2)算出有x条直径然后答案就是x(x-1)/2...这个数据范围是闹哪样! ----------------------------------------------------------- ...
- javascript 学习随笔7
<head> <title>标题页-学无忧(www.xue51.com)</title> <script language="JavaScript& ...
- TC基础使用指南(基于xbeta的TC配置文件)
所有常用目录都可以通过ctrl+d加一个或几个字母的超快捷方式直接跳转到位. 按下BackSpace键,就可以进入到上一级目录 Ctrl+q 在右侧打开左侧选定文件,再按一次Ctrl+q退出 按 Ct ...
- tf–idf算法解释及其python代码实现(下)
tf–idf算法python代码实现 这是我写的一个tf-idf的简单实现的代码,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四 ...