这篇文章不是完全原创,XML解析的部分参考了 liuhe688 的文章。文章地址:http://blog.csdn.net/liuhe688/article/details/6415593

这是一个几乎完整的过程。覆盖面也比较广。应用了AsyncTask, BaseAdapter, ListView, Dom, Sax, Pull等,这些也是开发应用中必不可少的部分。

效果图:

    

首先,做了些准备工作。down了一份xml数据放在本地服务器上

定义了一个model。

book.java

package com.example.phonedemo.model;

public class Book {
private int id;
private String name;
private float price; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public float getPrice() {
return price;
} public void setPrice(float price) {
this.price = price;
} }

1、客户端发起请求,

这是通过AsyncTask异步发起的请求。

AsyncTask 主要需要复写四个方法:

onProExecute():这个方法会在UI线程中调用 execute(..)之后立即执行,在开发中通常做一些初始化和加载UI显示的工作。

doInBackground(String... params):比较费时的操作,可以放在这里。网络请求等...

onProgressUpdate(Integer... values):通常,我们在耗时操作时候,比如download,会有一个百分比进度。在doInBackground()方法中调用

publishProgress()方法后,系统会调用此方法,更新进度信息。

onPostExecute(InputStream result):执行完毕以后调用的方法。

2、服务器端返回xml数据,

3、客户端解析数据,最终呈现出来

我用了三种解析方法,参照上述blog的地址。不过,在他得代码中稍有问题。ID是没有的。我在我的代码中改正了。

三种方式都是解析一个xml,所以写了一个接口文件。

BookParserImpl.java

package com.example.phonedemo.util;

import java.io.InputStream;
import java.util.List; import com.example.phonedemo.model.Book; public interface BookParserImpl {
public List<Book> parse(InputStream is); public String serialize(List<Book> books);
}

然后,三种解析分别实现它即可。

Dom解析方式

优点:功能齐全,强大。缺点:因为需要完全加载文档,导致,比较耗资源。前辈说j2ee中用的较多。

我虽然也学Java,但是一直都与前台打交道。曾经学的东西,工作中不用,就全忘了。罪过,罪过...

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parser(InputStream input);

上述dom初始化解析实例的代码。

DomBookParser.java

package com.example.phonedemo.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import com.example.phonedemo.model.Book; public class DomBookParser implements BookParserImpl { @Override
public List<Book> parse(InputStream is) {
List<Book> list = new ArrayList<Book>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
Document doc = null;
try {
builder = factory.newDocumentBuilder();
doc = builder.parse(is);
NodeList itemList = doc.getDocumentElement().getElementsByTagName(
"book");
for (int i = 0; i < itemList.getLength(); i++) {
Book book = new Book();
Node node = itemList.item(i);
NodeList child = node.getChildNodes();
NamedNodeMap attr = node.getAttributes();
book.setId(Integer.parseInt(attr.getNamedItem("id")
.getNodeValue()));
for (int j = 0; j < child.getLength(); j++) {
Node childItem = child.item(j);
String nodeName = childItem.getNodeName();
if (nodeName.equals("name")) {
book.setName(childItem.getFirstChild().getNodeValue());
} else if (nodeName.equals("price")) {
book.setPrice(Float.parseFloat(childItem
.getFirstChild().getNodeValue()));
}
} list.add(book);
} } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
} @Override
public String serialize(List<Book> books) {
// TODO Auto-generated method stub
return null;
}
}

Sax解析方式

sax是事件驱动型的,比起dom来更加灵巧。也更加简单快速。

SaxBookParser.java

package com.example.phonedemo.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import com.example.phonedemo.model.Book; public class SaxBookParser implements BookParserImpl { @Override
public List<Book> parse(InputStream is) {
// TODO Auto-generated method stub
SAXParserFactory factory = SAXParserFactory.newInstance();
MyHandler handler = null;
try {
SAXParser parser = factory.newSAXParser();
handler = new MyHandler();
parser.parse(is, handler);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return handler.getBooks();
} /**
* <b>解析xml的辅助类</b><br />
* <b>startDocument()</b> 当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。<br />
* <b>endDocument()</b> 和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。 <br/>
* <b>startElement(String namespaceURI, String localName, String qName,
* Attributes atts)</b>当读到一个开始标签的时候,会触发这个方法。<br />
* <b>endElement(String uri, String localName, String name)</b>
* 这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。<br />
* <b>characters(char[] ch, int start, int length)</b>
* 这个方法用来处理在XML文件中读到的内容,第一个参数用于存放文件的内容,<br />
* 后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。
*
* @author qxj
*
*/
class MyHandler extends DefaultHandler { private List<Book> books;
private Book book;
private StringBuilder builder; public List<Book> getBooks() {
return books;
} /**
* 接收元素中字符数据的通知。
*
* @param ch
* - 字符。
* @param start
* - 字符数组中的开始位置。
* @param length
* - 从字符数组中使用的字符数。
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
builder.append(ch, start, length);
} /**
* 接收元素结束的通知
*
* @param uri
* - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。
* @param localName
* - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。
* @param qName
* - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。
* @exception SAXException
* - 任何 SAX 异常,可能包装另外的异常。
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
if (localName.equals("book")) {
books.add(book);
} else if (localName.equals("name")) {
book.setName(builder.toString());
} else if (localName.equals("price")) {
book.setPrice(Float.parseFloat(builder.toString()));
}
} /**
* 接收文档的开始的通知
*
* @exception - SAXException - 任何 SAX 异常,可能包装另外的异常
*/
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
super.startDocument();
books = new ArrayList<Book>();
builder = new StringBuilder();
} /**
* 接收元素开始的通知。
*
* @param uri
* - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。
* @param localName
* - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。
* @param qName
* - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。
* @param attributes
* - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。
* @exception SAXException
* - 任何 SAX 异常,可能包装另外的异常
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
if (localName.equals("book")) {
book = new Book();
if (attributes != null) {
book.setId(Integer.parseInt(attributes.getValue("id")));
}
}
builder.setLength(0);
} } @Override
public String serialize(List<Book> books) {
// TODO Auto-generated method stub
return null;
} }

Pull解析方式

我最喜欢这种解析方式,它最轻巧,简便。android 用到了很多xml的文件,系统都是用pull来解析的。从这个层面中可以看出来。android建议使用这种解析方式。

PullBookParser.java

package com.example.phonedemo.util;

import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer; import android.util.Xml; import com.example.phonedemo.model.Book; public class PullBookParser implements BookParserImpl { @Override
public List<Book> parse(InputStream is) {
// TODO Auto-generated method stub
List<Book> books = null;
Book book = null; XmlPullParser parser = Xml.newPullParser();
try {
parser.setInput(is, "UTF-8");
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
books = new ArrayList<Book>();
break;
case XmlPullParser.START_TAG:
if (parser.getName().equals("book")) {
book = new Book();
book.setId(Integer.parseInt(parser.getAttributeValue(0)));
} else if (parser.getName().equals("name")) {
parser.next();
book.setName(parser.getText());
} else if (parser.getName().equals("price")) {
parser.next();
book.setPrice(Float.parseFloat(parser.getText()));
}
break;
case XmlPullParser.END_TAG:
if (parser.getName().endsWith("book")) {
books.add(book);
book = null;
}
break;
}
parser.next();
eventType = parser.getEventType();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return books;
} @Override
public String serialize(List<Book> books) {
// TODO Auto-generated method stub
XmlSerializer serializer = Xml.newSerializer();
StringWriter writer = new StringWriter();
try {
serializer.setOutput(writer);
serializer.startDocument("UTF-8", true);
serializer.startTag("", "books");
for (Book book : books) {
serializer.startTag("", "book");
serializer.attribute("", "id", String.valueOf(book.getId())); serializer.startTag("", "name");
serializer.text(book.getName());
serializer.endTag("", "name"); serializer.startTag("", "price");
serializer.text(book.getPrice() + "");
serializer.endTag("", "price");
serializer.endTag("", "book");
}
serializer.endTag("", "books");
serializer.endDocument();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("doc: " + writer.toString());
return writer.toString();
}
}

最后,附上Activity

package com.example.phonedemo;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient; import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast; import com.example.phonedemo.model.Book;
import com.example.phonedemo.util.DomBookParser;
import com.example.phonedemo.util.PullBookParser;
import com.example.phonedemo.util.SaxBookParser; public class XMLParserDemo extends Activity { private static final String TAG = "XMLParserDemo"; private static final String PATH = "http://192.168.1.121:8080/wwwroot/android/book.html"; private List<Book> list = null;
private Button dom = null;
private Button sax = null;
private Button pull = null;
private Button clear = null;
private TextView parser = null;
private ListView listView = null; /**
* 异步请求数据
*
* @author qinxijuan
*
*/
private class MyAsyncTask extends AsyncTask<String, Integer, InputStream> { // 表示当前使用哪一种解析方式,0:dom ; 1: sax; 2:pull
private int flag = 0; public MyAsyncTask(int flag) {
this.flag = flag;
} @Override
protected void onPostExecute(InputStream result) {
if (result != null) {
if (flag == 0) {
domParserFromInputStream(result);
} else if (flag == 1) {
saxParserFromInputStream(result);
} else if (flag == 2) {
pullParserFromInputStream(result);
}
} else {
Toast.makeText(XMLParserDemo.this, "数据获取失败!",
Toast.LENGTH_SHORT).show();
}
} @Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute() Loading ... ");
} @Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
} @Override
protected InputStream doInBackground(String... params) { InputStream result = null;
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(params[0]);
HttpResponse response = null;
try {
response = client.execute(get);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
result = entity.getContent();
}
} catch (Exception e) {
e.printStackTrace();
} return result;
} } static class ViewHolder {
TextView id;
TextView name;
TextView price;
} class MyBaseAdapter extends BaseAdapter { private List<Book> list = null;
private LayoutInflater ly = null; public MyBaseAdapter(Context context, List<Book> list) {
this.ly = LayoutInflater.from(context);
this.list = list;
} @Override
public int getCount() {
// TODO Auto-generated method stub
return this.list.size();
} @Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
} @Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
} @Override
public View getView(int position, View convertView, ViewGroup arg2) {
ViewHolder viewHolder = null;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = ly.inflate(R.layout.simpleitem, null);
viewHolder.id = (TextView) convertView.findViewById(R.id.id);
viewHolder.name = (TextView) convertView
.findViewById(R.id.name);
viewHolder.price = (TextView) convertView
.findViewById(R.id.age);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.id.setText(String.valueOf(list.get(position).getId()));
viewHolder.name.setText(list.get(position).getName());
viewHolder.price.setText(String.valueOf(list.get(position)
.getPrice()));
return convertView;
} } @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
super.setContentView(R.layout.xml_parser_layout); this.dom = (Button) super.findViewById(R.id.dom);
this.sax = (Button) super.findViewById(R.id.sax);
this.pull = (Button) super.findViewById(R.id.pull);
this.clear = (Button) super.findViewById(R.id.clear);
this.parser = (TextView) super.findViewById(R.id.parser);
this.listView = (ListView) super.findViewById(R.id.list_view); this.clear.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
list = new ArrayList<Book>();
MyBaseAdapter adapter = new MyBaseAdapter(XMLParserDemo.this,
list);
listView.setAdapter(adapter);
parser.setText("数据清除完毕");
}
}); this.dom.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
MyAsyncTask mTask = new MyAsyncTask(0);
mTask.execute(PATH);
parser.setText("使用dom方式解析");
}
}); this.sax.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
MyAsyncTask mTask = new MyAsyncTask(1);
mTask.execute(PATH);
parser.setText("使用sax方式解析");
}
}); this.pull.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
MyAsyncTask mTask = new MyAsyncTask(2);
mTask.execute(PATH);
parser.setText("使用pull方式解析");
}
});
} public void domParserFromInputStream(InputStream input) {
list = new ArrayList<Book>();
DomBookParser domParser = new DomBookParser();
System.out.println("input: " + input.toString());
list = domParser.parse(input);
MyBaseAdapter adapter = new MyBaseAdapter(this, list);
this.listView.setAdapter(adapter);
} public void saxParserFromInputStream(InputStream input) {
list = new ArrayList<Book>();
SaxBookParser saxParser = new SaxBookParser();
list = saxParser.parse(input);
MyBaseAdapter adapter = new MyBaseAdapter(this, list);
this.listView.setAdapter(adapter);
} public void pullParserFromInputStream(InputStream input) {
PullBookParser pullParser = new PullBookParser();
list = pullParser.parse(input);
MyBaseAdapter adapter = new MyBaseAdapter(this, list);
this.listView.setAdapter(adapter);
} }

xml_parser_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" > <Button
android:id="@+id/dom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Dom" /> <Button
android:id="@+id/sax"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Sax" /> <Button
android:id="@+id/pull"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="pull" /> <Button
android:id="@+id/clear"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="clear" />
</LinearLayout> <LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" > <TextView
android:id="@+id/parser"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=" " />
</LinearLayout> <LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" > <ListView
android:id="@+id/list_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout> </LinearLayout>

Android 通过Dom, Sax, Pull解析网络xml数据的更多相关文章

  1. - XML 解析 总结 DOM SAX PULL MD

    目录 目录 XML 解析 总结 DOM SAX PULL MD 几种解析方式简介 要解析的内容 DOM 解析 代码 输出 SAX 解析 代码 输出 JDOM 解析 代码 输出 DOM4J 解析 代码 ...

  2. Android开发8——利用pull解析器读写XML文件

    一.基本介绍 对XML解析有SAX和DOM等多种方式,Android中极力推荐xmlpull方式解析xml.xmlpull不仅可用在Android上同样也适用于javase,但在javase环境中需自 ...

  3. [Swift通天遁地]四、网络和线程-(5)解析网络请求数据:String(字符串)、Data(二进制数据)和JSON数据

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  4. Android SAX、DOM、Pull解析xml文件剖析与案例讲解

    XML介绍 XML(Extensible Markup Language) 即可扩展标记语言,与HTML一样,都是SGML(Standard Generalized Markup Language,标 ...

  5. Android学习笔记_7_使用 sax 或者 dom 或者 pull 解析XML文件

    一.Pull解析介绍: Android上使用SAX和DOM方式解析XML的方法,并且对两种做了简单的比较,通过比较我们知道对在往往内存比较稀缺的移动设备上运行的Android系统来说,SAX是一种比较 ...

  6. Java sax、dom、pull解析xml

    -------------------------------------SAX解析xml---------------------------------- >Sax定义 SAX是一个解析速度 ...

  7. 解析XML:DOM,SAX,PULL

    Android解析XML有三种方式:DOM(document object model).SAX(simple api XML).PULL 1.DOM DOM解析XML文件时,会将XML文件的所有内容 ...

  8. 黎活明8天快速掌握android视频教程--15_采用Pull解析器解析和生成XML内容

    1.该项目主要有下面的两个作用 (1)将xml文件解析成对象的List对象,xml文件可以来自手机本地,也可以来自服务器返回的xml数据 (2)强list对象保存成xml文件,xml保存到手机的内存卡 ...

  9. SAX PULL解析实例

    XML三种解析方式: SAX解析:基于事件驱动,事件机制基于回调函数的,得到节点和节点之间内容时也会回调事件 PULL解析:相同基于事件驱动,仅仅只是回调时是常量 DOM解析:是先把XML文件装入内存 ...

随机推荐

  1. NSURLConnect 的简单实用(iOS8淘汰)

    Demo_1 NSRULConnection NSRULConnection 苹果公司在ios8已经抛弃了,但是我还是要讲一下,因为这和后面的NSSession有着密切的联系 下面开始使用步骤: 1. ...

  2. C++小知识之Map用法

    Map是c++的一个标准容器,她提供了很好一对一的关系,在一些程序中建立一个map可以起到事半功倍的效果,总结了一些map基本简单实用的操作! 1. map最基本的构造函数:    map<st ...

  3. 汉化testlink

    testlink版本:1.9.13 1.登录testlink后,打开my setting(左上角小人人) 2.Locale 选择chinese,然后点击save 3.over,汉化完毕

  4. hdu 2824The Euler function

    题目链接 快速求出a到b之间所有数的欧拉函数. 一个一个求肯定是不行的, 我们知道欧拉函数的公式为phi(n) = n*(1-1/i1)*(1-1/i2).......i1, i2为素因子. 那么我们 ...

  5. python一些模块的exe安装包在windows的64位系统里识别不到已安装Python目录的解决方法

    在windows里安装python一些模块时候,有时候源码安装比较困难,pip install也各种报错,这时候最喜欢用别人编译好的exe或者whl文件来安装,但是在windows的64位系统里,如果 ...

  6. iOS 使用xib创建cell的两种初始化方式

    曾几何时,被自己坑过,为了防止下次继续被自己坑,我决定了!在每个我能看到的地方,都把问题写一遍!!! 方法一: ? 1 2 3 4 第一步: [self.collectionView register ...

  7. JDK的目录结构及结构图

    -bin目录: JDK开发工具的可执行文件 -lib目录: 开发工具使用的归档包文件 -jre: Java 运行时环境的根目录,包含Java虚拟机,运行时的类包和Java应用启动器,         ...

  8. Netbeans搭建Android环境

    原文:Netbeans搭建Android环境 Netbeans环境的搭建主要依赖于NBAndroid插件,项目地址: http://www.nbandroid.org/p/installation.h ...

  9. css包含块containing block

    <css权威指南>P167: The Containing Block Every element is laid out with respect to its containing b ...

  10. openStack icehouse for centos6.4 production Env 实战

    production Env brief Overview: Management Node:  controller.cc 10.114.100.115 Neutron Network Node:  ...