android之三种方式解析xml(dom,sax,pull)

dom 我的理解就是先把整个文档读取到内存中,然后才解析,读取大点的文件的话这样效率就会很低。而 sax和pull 它们是基于事件解析的。一行一行去解析,效率会高点。

下面就讲这三种的用法:

  1. dom解析xml
  2. sax解析xml
  3. pull解析xml

首先在main创建个assets目录,创建好后,然后在这目录下创建个person.xml文件

这里写图片描述

person.xml里面的内容为:

<persons>
    <person id="1">
        <name>张三</name>
        <age>22</age>
        <major>通信工程</major>
    </person>
    <person id="2">
        <name>李四</name>
        <age>32</age>
        <major>软件工程</major>
    </person>
    <person id="3">
        <name>王五</name>
        <age>29</age>
        <major>土木工程</major>
    </person>

</persons>

接下来我们用三种方法就解析这个内容。掌握解析了这个,其他的基本上也会了。

1 , dom解析xml

activity_main.xml布局文件代码如下:

<?xml version="1.0" encoding="utf-8"?>
<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<PersonBean> parseXML(InputStream is) throws Exception {
        //获取集合实例
        List<PersonBean> 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<PersonBean> 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);
    }
}

里面逻辑不难。就不解释了。。

运行结果:

这里写图片描述

2 , sax解析xml

再创建个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<PersonBean> 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<PersonBean> 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<PersonBean> 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解析大概调用方法的顺序:

这里写图片描述

3, pull解析xml

创建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<PersonBean>  parseXML(InputStream is) {
        List<PersonBean> 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<PersonBean> 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

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值