导航
XML的三种解析方式
json全面解析和使用
Gson官方推荐的json解析方式
三种解析XML方法的比较
XML
Android 提供了三种解析XML的方式:SAX(Simple API XML), DOM(Document Object Model), Pull
本文中所用的XML文档内容如下:
小明
明明
小红
红红
小亮
亮亮
第一种、Pull解析方式
1)、创建对应XML的Bean对象
public class Student {
private String name;
private String sex;
private String nickName;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", nickName='" + nickName + '\'' +
'}';
}
}
2)、Pull解析
public class pullxml{
public List pull2xml(InputStream is) throws Exception {
List list = null;
Student student = null;
//创建xmlPull解析器
XmlPullParser parser = Xml.newPullParser();
///初始化xmlPull解析器
parser.setInput(is, "utf-8");
//读取文件的类型
int type = parser.getEventType();
//无限判断文件类型进行读取
while (type != XmlPullParser.END_DOCUMENT) {
switch (type) {
//开始标签
case XmlPullParser.START_TAG:
if ("students".equals(parser.getName())) {
list = new ArrayList<>();
} else if ("student".equals(parser.getName())) {
student = new Student();
} else if ("name".equals(parser.getName())) {
//获取sex属性
String sex = parser.getAttributeValue(null,"sex");
student.setSex(sex);
//获取name值
String name = parser.nextText();
student.setName(name);
} else if ("nickName".equals(parser.getName())) {
//获取nickName值
String nickName = parser.nextText();
student.setNickName(nickName);
}
break;
//结束标签
case XmlPullParser.END_TAG:
if ("student".equals(parser.getName())) {
list.add(student);
}
break;
}
//继续往下读取标签类型
type = parser.next();
}
return list;
}}
调用的时候只需传入xmlData即可
List list=pullxml.pull2xml(getResources().getAssets().open("news.xml"));
tv.setText(list.toString());
第二种、SAX解析方式
SAX(Simple API for XML)解析器是一种基于事件的解析器,事件驱动的流式解析方式是,从文件的开始顺序解析到文档的结束,不可暂停或倒退。
- 优点:解析速度快,占用内存少。非常适合在Android移动设备中使用。
- 缺点:不会记录标签的关系,而要让你的应用程序自己处理,这样就增加了你程序的负担。
- 工作原理:对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档 (document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。
使用步骤:
1. 新建 ContentHanlder 类继承 DefaultHandler 类,并重写父类的五个方法
- startDocument(): 开始解析XML时调用
- startElement(): 开始解析某个结点时调用
- characters(): 在获取节点内容时调用
- endElement(): 在完成解析某个结点时调用
- endDocument(): 在完成整个XML解析的时候调用
2.创建函数 parseXMLWithSAX
3.调用函数 parseXMLWithSAX 解析 XML
代码如下:
新建 ContentHandler 类继承 DefaultHandler类,重写五个父类方法
public class saxxml {
public static List sax2xml(InputStream is) throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
//初始化Sax解析器
SAXParser sp = spf.newSAXParser();
//新建解析处理器
MyHandler handler = new MyHandler();
//将解析交给处理器
sp.parse(is, handler);
//返回List
return handler.getList();
}
public static class MyHandler extends DefaultHandler {
private List list;
private student student;
//用于存储读取的临时变量
private String tempString;
/**
* 解析到文档开始调用,一般做初始化操作
*
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
list = new ArrayList<>();
super.startDocument();
}
/**
* 解析到文档末尾调用,一般做回收操作
*
* @throws SAXException
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
/**
* 每读到一个元素就调用该方法
*
* @param uri
* @param localName
* @param qName
* @param attributes
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if ("student".equals(qName)) {
//读到student标签
student = new student();
} else if ("name".equals(qName)) {
//获取name里面的属性
String sex = attributes.getValue("sex");
System.out.println("sex-----"+sex);
student.setSex(sex);
}
super.startElement(uri, localName, qName, attributes);
}
/**
* 读到元素的结尾调用
*
* @param uri
* @param localName
* @param qName
* @throws SAXException
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("student".equals(qName)) {
list.add(student);
}
if ("name".equals(qName)) {
student.setName(tempString);
} else if ("nickName".equals(qName)) {
student.setNiceName(tempString);
}
super.endElement(uri, localName, qName);
}
/**
* 读到属性内容调用
*
* @param ch
* @param start
* @param length
* @throws SAXException
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
tempString = new String(ch, start, length);
super.characters(ch, start, length);
}
/**
* 获取该List
*
* @return
*/
public List getList() {
return list;
}
}
}
调用的时候只需传入xmlData即可
List list=saxxml.sax2xml(getResources().getAssets().open("news.xml"));
tv.setText(list.toString());
【注:在Android API中,另外提供了Android.util.Xml类,同样可以解析XML文件,使用方法类似SAX,也都需编写Handler来处理XML的解析,但是在使用上却比SAX来得简单 ,如下所示:
以android.util.XML实现XML解析:
MyHandler myHandler=new MyHandler0;
android.util.Xm1.parse(ur1.openC0nnection().getlnputStream0,Xm1.Encoding.UTF-8,myHandler);】
第三种、Dom解析方式
1)、创建对应XML的Bean对象
和第一种一样这里就不贴了
2)、Dom解析
public List dom2xml(InputStream is) throws Exception {
//一系列的初始化
List list = new ArrayList<>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
//获得Document对象
Document document = builder.parse(is);
//获得student的List
NodeList studentList = document.getElementsByTagName("student");
//遍历student标签
for (int i = 0; i < studentList.getLength(); i++) {
//获得student标签
Node node_student = studentList.item(i);
//获得student标签里面的标签
NodeList childNodes = node_student.getChildNodes();
//新建student对象
Student student = new Student();
//遍历student标签里面的标签
for (int j = 0; j < childNodes.getLength(); j++) {
//获得name和nickName标签
Node childNode = childNodes.item(j);
//判断是name还是nickName
if ("name".equals(childNode.getNodeName())) {
String name = childNode.getTextContent();
student.setName(name);
//获取name的属性
NamedNodeMap nnm = childNode.getAttributes();
//获取sex属性,由于只有一个属性,所以取0
Node n = nnm.item(0);
student.setSex(n.getTextContent());
} else if ("nickName".equals(childNode.getNodeName())) {
String nickName = childNode.getTextContent();
student.setNickName(nickName);
}
}
//加到List中
list.add(student);
}
return list;
}