dom 我的理解就是先把整个文档读取到内存中,然后才解析,读取大点的文件的话这样效率就会很低。而 sax和pull 它们是基于事件解析的。一行一行去解析,效率会高点。
下面就讲这三种的用法:
首先在main创建个assets目录,创建好后,然后在这目录下创建个person.xml文件
person.xml里面的内容为:
<persons>
<person id="1">
<name>张三name>
<age>22age>
<major>通信工程major>
person>
<person id="2">
<name>李四name>
<age>32age>
<major>软件工程major>
person>
<person id="3">
<name>王五name>
<age>29age>
<major>土木工程major>
person>
persons>
接下来我们用三种方法就解析这个内容。掌握解析了这个,其他的基本上也会了。
activity_main.xml布局文件代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
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"
android:orientation="vertical"
tools:context="com.example.edu.androidforparsexml.MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="解析XML"
android:onClick="parseXML"
/>
<TextView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="content"
android:gravity="center"
/>
LinearLayout>
很简单就一个按钮,还有一个是显示解析出来的内容,
PersonBean.java代码如下:
public class PersonBean {
private int id;
private String name;
private int age;
private String major;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
@Override
public String toString() {
return "PersonBean{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", major='" + major + '\'' +
'}';
}
}
ParseXMLForDom.java代码如下:
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
/**
* Created by Administrator on 2016/10/4.
*/
public class ParseXMLForDom {
/**
* dom方式解析xml
*/
public static List parseXML(InputStream is) throws Exception {
//获取集合实例
List list = new ArrayList<>();
//获取DocumentBuilderFactory实例
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//获取documentBuilder实例
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
//获取document实例
Document document = documentBuilder.parse(is);
//获取person节点集合
NodeList personNodeList = document.getElementsByTagName("person");
for (int i = 0; i < personNodeList.getLength(); i++) {
PersonBean bean = new PersonBean();//获取personbean实例
Node person = personNodeList.item(i);//获取person节点
NamedNodeMap nnm = person.getAttributes();
/*
* 获取person节点的属性值
*/
for (int j = 0; j < nnm.getLength(); j++) {
Node n = nnm.item(j);
bean.setId(Integer.valueOf(n.getNodeValue()));
}
/*
获取person里的子节点,并赋值给bean
*/
NodeList personChildNodeList = person.getChildNodes();
for (int j = 0; j < personChildNodeList.getLength(); j++) {
//获取person节点的子节点
Node personChileNode = personChildNodeList.item(j);
if (Node.ELEMENT_NODE == personChileNode.getNodeType()) {
if ("name".equals(personChileNode.getNodeName())) {
bean.setName(personChileNode.getTextContent().trim());
} else if ("age".equals(personChileNode.getNodeName())) {
bean.setAge(Integer.valueOf(personChileNode.getTextContent().trim()));
} else if ("major".equals(personChileNode.getNodeName())) {
bean.setMajor(personChileNode.getTextContent().trim());
}
}
}
list.add(bean);
}
return list;
}
}
这个是dom解析xml,
//获取DocumentBuilderFactory实例
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//获取documentBuilder实例
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
//获取document实例
Document document = documentBuilder.parse(is);
这几步是必须要,我们要拿到整个document实例才能去解析。
MainActivity.java代码如下:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private TextView mContent;
private List list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWidgets();//初始化控件
}
/**
* 为按钮绑定点击事件
*
* @param view
*/
public void parseXML(View view) {
parseXMLForDom();
}
/**
* dom解析xml
*/
private void parseXMLForDom() {
try {
list = ParseXMLForDom.parseXML(getResources().getAssets().open("person.xml"));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i).toString() + "\n");
}
mContent.setText(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 初始化控件
*/
private void initWidgets() {
mContent = (TextView) findViewById(R.id.content);
}
}
里面逻辑不难。就不解释了。。
运行结果:
再创建个MyHandler类继承DefaultHandler ,代码如下
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2016/10/4.
*/
public class MyHandler extends DefaultHandler {
private PersonBean bean;
private List list;
private String contentFlag;//只是一个标记,把值放到contentFlag中
/**
* 解析到文档开始调用,一般做初始化操作
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
list=new ArrayList<>();//初始化list
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 {
//当读到person节点时就创建一个personbean实例
if ("person".equals(qName)){
bean=new PersonBean();
String id= attributes.getValue("id");
bean.setId(Integer.valueOf(id));
}
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 ("person".equals(qName)){
list.add(bean);
bean=null;//通知jvm回收
}
if ("name".equals(qName)){
bean.setName(contentFlag);
}else if ("age".equals(qName)){
bean.setAge(Integer.valueOf(contentFlag));
}else if ("major".equals(qName)){
bean.setMajor(contentFlag);
}
contentFlag=null;//设为null
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 {
contentFlag=new String(ch,start,length).trim();
super.characters(ch, start, length);
}
/**
* 把list暴露出去,
* @return
*/
public List getList() {
return list;
}
}
改下MainActivity代码如下:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import org.xml.sax.SAXException;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class MainActivity extends AppCompatActivity {
private TextView mContent;
private List list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWidgets();//初始化控件
}
/**
* 为按钮绑定点击事件
*
* @param view
*/
public void parseXML(View view) {
// parseXMLForDom();//dom解析xml
parseForXMLForSax();//sax解析xml
}
/**
* dom解析xml
*/
private void parseXMLForDom() {
try {
list = ParseXMLForDom.parseXML(getResources().getAssets().open("person.xml"));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i).toString() + "\n");
}
mContent.setText(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* sax解析xml
*/
public void parseForXMLForSax() {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = null;
try {
sp = spf.newSAXParser();
MyHandler handler = new MyHandler();
sp.parse(getResources().getAssets().open("person.xml"), handler);
list = handler.getList();//这是解析出来的内容放在list集合中
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i).toString() + "\n");
}
mContent.setText(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 初始化控件
*/
private void initWidgets() {
mContent = (TextView) findViewById(R.id.content);
}
}
运行结果是一样的,不放出来了
sax解析大概调用方法的顺序:
创建ParseXMLForPull类代码如下:
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2016/10/4.
*/
public class ParseXMLForPull {
public static List parseXML(InputStream is) {
List list=null;
PersonBean bean=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:
list = new ArrayList<>();
break;
case XmlPullParser.START_TAG:
if ("person".equals(parser.getName())) {
bean = new PersonBean();
String id= parser.getAttributeValue(null,"id");
bean.setId(Integer.valueOf(id));
}
if (bean != null) {
if ("name".equals(parser.getName())) {
bean.setName(parser.nextText().trim());
} else if ("age".equals(parser.getName())) {
bean.setAge(Integer.valueOf(parser.nextText().trim()));
} else if ("major".equals(parser.getName())) {
bean.setMajor(parser.nextText().trim());
}
}
break;
case XmlPullParser.END_TAG:
if ("person".equals(parser.getName())){
list.add(bean);
bean=null;
}
break;
}
eventType = parser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
pull也是基于事件解析的,感觉跟sax解析xml差不多、
MainActivity.java代码如下:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class MainActivity extends AppCompatActivity {
private TextView mContent;
private List list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWidgets();//初始化控件
}
/**
* 为按钮绑定点击事件
*
* @param view
*/
public void parseXML(View view) {
// parseXMLForDom();//dom解析xml
// parseForXMLForSax();//sax解析xml
parseXMLForPull();//pull解析xml
}
/**
* dom解析xml
*/
private void parseXMLForDom() {
try {
list = ParseXMLForDom.parseXML(getResources().getAssets().open("person.xml"));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i).toString() + "\n");
}
mContent.setText(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* sax解析xml
*/
public void parseForXMLForSax() {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = null;
try {
sp = spf.newSAXParser();
MyHandler handler = new MyHandler();
sp.parse(getResources().getAssets().open("person.xml"), handler);
list = handler.getList();//这是解析出来的内容放在list集合中
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i).toString() + "\n");
}
mContent.setText(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* pull解析xml
*/
public void parseXMLForPull() {
try {
list= ParseXMLForPull.parseXML(getResources().getAssets().open("person.xml"));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
sb.append(list.get(i).toString() + "\n");
}
mContent.setText(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 初始化控件
*/
private void initWidgets() {
mContent = (TextView) findViewById(R.id.content);
}
}
运行结果还是一样的。不放出来了、
边学边写,终于完成了。dom跟sax解析xml以前是学过的,pull解析xml以前没接触过,感觉也不是太难。哈哈。。pull解析xml没写什么解释,我感觉明白了sax解析xml,pull解析应该也会 了。
https://github.com/songshuilin/AndroidForBlog/tree/master/androidforparsexml