1.准备好要解析的data.xml文件到项目src目录下:
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<users>
<user id="1">
<name>张三</name>
<age>19</age>
<address>广州</address>
<phoneNumber>1811111111</phoneNumber>
</user>
<user id="2">
<name>李四</name>
<age>20</age>
<address>深圳</address>
<phoneNumber>1822222222</phoneNumber>
</user>
<user id="3">
<name>王五</name>
<age>21</age>
<address>上海</address>
<phoneNumber>1833333333</phoneNumber>
</user>
</users>
2.解析的具体操作步骤:
(1).写一个类UserInfo.java与data.xml节点相对应:
package com.sheng.user.domain;
public class UserInfo {
private int id;
private String name;
private int age;
private String address;
private String phoneNumber;
@Override
public String toString() {
return "UserInfo [id=" + id + ", name=" + name + ", age=" + age
+ ", address=" + address + ", phoneNumber=" + phoneNumber + "]";
}
public UserInfo() {
}
public UserInfo(int id, String name, int age, String address,
String phoneNumber) {
super();
this.id = id;
this.name = name;
this.age = age;
this.address = address;
this.phoneNumber = phoneNumber;
}
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
(2).简单的activity_main.xml文件写成如下:
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.sheng.saxxml.MainActivity" >
<Button
android:id="@+id/button_get_user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="getUserInfo"
android:text="SAX解析XML" />
<TextView
android:layout_below="@id/button_get_user"
android:id="@+id/show_user_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
(3).写一个handler类SAXHandler.java继承DefaultHandler类,并重写里面的几个方法:
package com.sheng.saxxml.hanler;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.sheng.user.domain.UserInfo;
public class SAXHandler extends DefaultHandler {
private UserInfo userInfo;
private List<UserInfo> userInfoList;
private String content;
public List<UserInfo> getUserInfoList() {
return userInfoList;
}
public void setUserInfoList(List<UserInfo> userInfoList) {
this.userInfoList = userInfoList;
}
/**
* 当SAX解析器解析到XML文档开始时调用
*/
@Override
public void startDocument() throws SAXException {
super.startDocument();
}
/**
* 当SAX解析器解析到某个元素开始时调用
* localName记录节点名
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if ("users".equals(localName)) {
// 开始解析数据时,new一个userInfoList
userInfoList = new ArrayList<UserInfo>();
} else if ("user".equals(localName)) {
// 开始解析到每一条数据时,new一个UserInfo对象
userInfo = new UserInfo();
// 取得user标签里的id属性,然后设置id
userInfo.setId(Integer.parseInt(attributes.getValue("id")));
}
}
/**
* 当SAX解析器解析到某个属性值时调用
* ch标签里的值的内容
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
// 标签里的值先存放到临时变量里,等待使用
content = new String(ch, start, length);
}
/**
* 当SAX解析器解析到某个元素结束时,会调用此方法
* 其中localName记录的是元素的属性名
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
if ("name".equals(localName)) {
// 标签名与name一样时,把取得的值设置给name
userInfo.setName(content);
} else if ("age".equals(localName)) {
// 标签名与age一样时,把取得的值设置给age
userInfo.setAge(Integer.parseInt(content));
} else if ("address".equals(localName)) {
// 标签名与address一样时,把取得的值设置给address
userInfo.setAddress(content);
} else if ("phoneNumber".equals(localName)) {
// 标签名与phoneNumber一样时,把取得的值设置给phoneNumber
userInfo.setPhoneNumber(content);
} else if ("user".equals(localName)) {
// 每当完成解析一条记录时,把这条记录添加到userInfoList里
userInfoList.add(userInfo);
}
}
/**
* 当SAX解析器解析到XML文档结束时调用
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
}
(4).在MainActivity.java里,调用SAXHandler类的方法进行具体的解析过程:
package com.sheng.saxxml;
import java.io.InputStream;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.sheng.saxxml.hanler.SAXHandler;
import com.sheng.user.domain.UserInfo;
public class MainActivity extends Activity {
protected static final int SHOW_USERINFO = 0;
protected static final int ERROR = 1;
private SAXHandler saxHandler;
private TextView userInfoView;
private List<UserInfo> userInfoList;
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_USERINFO:
StringBuffer sbStr = (StringBuffer) msg.obj;
userInfoView.setText(sbStr);
break;
case ERROR:
userInfoView.setText("解析失败");
Toast.makeText(getApplicationContext(), "解析失败", 0).show();
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userInfoView = (TextView) findViewById(R.id.show_user_info);
}
public void getUserInfo(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try {
// 通过类加载器,读入data.xml数据文件
InputStream is = MainActivity.class.getClassLoader().getResourceAsStream("data.xml");
// 传入数据流,解析xml数据
parseXMLWithSAX(is);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
/**
* SAX解析器解析XML的方法
*/
public void parseXMLWithSAX(InputStream is) {
try {
// 1.新建一个工厂类SAXParserFactory
SAXParserFactory factory = SAXParserFactory.newInstance();
// 2.让工厂类生产一个SAX解析类 SAXParser
SAXParser saxParser = factory.newSAXParser();
saxHandler = new SAXHandler();
// 3.开始解析,使用SAXParser.parse(InputStream is, DefaultHandler dh)进行解析
saxParser.parse(is, saxHandler);
// 得到返回的userInfoList
userInfoList = saxHandler.getUserInfoList();
StringBuffer sb = new StringBuffer();
for (UserInfo info : userInfoList) {
String user = info.toString();
sb.append(user);
sb.append("\n");
}
Message msg = new Message();
msg.what = SHOW_USERINFO;
msg.obj = sb;
handler.sendMessage(msg);
} catch (Exception e) {
Message msg = new Message();
msg.what = ERROR;
handler.sendMessage(msg);
e.printStackTrace();
}
}
}
以上已经完成xml的简单解析过程,另附上使用SAXParser.parse(InputStream is, DefaultHandler dh)进行解析的写法,去掉以上第三步骤,然后接上下面的代码:
// 3.从SAXParser中得到一个XMLReader实例
// XMLReader xmlReader = saxParser.getXMLReader();
// 4.把自己写的SAXHandler注册到XMLReader中
// xmlReader.setContentHandler(saxHandler);
// 5.将一个xml文档或者资源变成一个java可以处理的InputStream流,解析正式开始
// xmlReader.parse(new InputSource(is));