Android解析XML数据

XML是超文本标记语言,是各种应用程序之间进行数据传输的最常用的工具。Android中布局文件也是使用XML格式来写的。
在Android中常用PULL解析器,SAX解析器和DOM解析器来解析XML格式数据。

PULL解析器:
XmlPull和Sax类似,是基于流(stream)操作文件,然后根据节点事件来解析的。因为是基于流的处理,因此Xmlpull和 Sax都比较节约内存资源,不会象Dom那样要把所有节点以对象树的形式展现在内存中。 但Xmlpull比Sax更简明,而且不需要扫描完整个流。

SAX解析器:
SAX(Simple API for XML),它并不是由W3C官方所提出的标准,虽然如此,使用SAX的还是不少,几乎所有的XML解析器都会支持它。与DOM比较而言,SAX是一种轻量型的方法。我们知道,在处理DOM的时候,需要读入整个的XML文档,然后在内存中创建DOM树,生成DOM树上的每个Node对象。SAX在概念上与DOM完全不同。它不同于DOM的文档驱动,它是事件驱动的,它并不需要读入整个文档,而文档的读入过程也就是SAX的解析过程。所谓事件驱动,是指一种基于回调(callback)机制的程序运行方法。

DOM解析器:
DOM(Document Object Model,文档对象模型)是W3C制定的一套规范标准,即规定了解析文件的接口。各种语言可以按照DOM规范去实现这些接口,给出解析文件的解析器。各种基于DOM规范解析器必须按照DOM规范在内存中建立数据,DOM规范的核心是DOM树模型。对于解析XML文件的解析器,解析器通过读入XML文件在内存中建立一个树,也就是说XML文件的标记、标记的文本内容、实体等都会和内存中树的某个节点相对应。一个应用程序可以方便地操作内存中树的节点来处理XML文档,获取自己所需要的数据。

下面来解析如下的XML数据:

<?xml version="1.0" encoding="utf-8"?>
<all>
    <music group="1" id="1">
        <name>七月上</name>
        <author>Jam</author>
    </music>
    <music group="2" id="2">
        <name>有点甜</name>
        <author>汪苏泷</author>
    </music>
    <music group="3" id="3">
        <name>大胆说爱</name>
        <author>落落</author>
    </music>
</all>

使用PULL解析:

/**
 * 使用pull解析
 *
 * @param in
 */
private List<Music> pullParseXML(InputStream in) {
    ArrayList<Music> musics = null;
    try {
        XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
        XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser();
        xmlPullParser.setInput(in, "UTF-8");

        int eventType = xmlPullParser.getEventType();
        Music music = null;
        while (eventType != XmlPullParser.END_DOCUMENT) {
            String nodeName = xmlPullParser.getName();
            switch (eventType) {
                case XmlPullParser.START_DOCUMENT://文档开始
                    musics = new ArrayList<>();
                    break;
                case XmlPullParser.START_TAG://开始节点
                    if ("music".equals(nodeName)) {
                        music = new Music();
                        music.group = Integer.parseInt(xmlPullParser.getAttributeValue(0));
                        music.id = Integer.parseInt(xmlPullParser.getAttributeValue(1));
                    } else if ("name".equals(nodeName)) {
                        music.name = xmlPullParser.nextText();
                    } else if ("author".equals(nodeName)) {
                        music.author = xmlPullParser.nextText();
                    }
                    break;
                case XmlPullParser.END_TAG://结束节点
                    if (music != null) {
                        musics.add(music);
                    }
                    music = null;
                    break;
                default:
                    break;
            }
            //触发下一个事件
            eventType = xmlPullParser.next();
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
    return musics;
}

使用SAX解析:

/**
 * 使用sax解析
 *
 * @param in
 */
private List<Music> saxParseXML(InputStream in) {
    try {
        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
        SaxParseXML parseXML = new SaxParseXML();
        saxParser.parse(in, parseXML);
        return parseXML.getData();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

注意使用sax解析要创建解析类继承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 2017/8/29.
 */

public class SaxParseXML extends DefaultHandler {
    private List<Music> data = new ArrayList<>();
    private Music music;
    private String tagName;

    public List<Music> getData() {
        return data;
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if ("music".equals(qName)) {
            music = new Music();
            music.group = Integer.parseInt(attributes.getValue(0));
            music.id = Integer.parseInt(attributes.getValue(1));
        }
        this.tagName = qName;
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if ("music".equals(qName)) {
            if (music != null) {
                data.add(music);
            }
        }
        this.tagName = null;
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (tagName != null) {
            String data = new String(ch, start, length);
            if ("name".equals(tagName)) {
                music.name = data;
            } else if ("author".equals(tagName)) {
                music.author = data;
            }
        }
    }
}

使用DOM解析:

/**
 * 使用dom解析
 *
 * @param in
 */
private List<Music> domParseXML(InputStream in) {
    List<Music> data = new ArrayList<>();
    //创建DOM工厂对象
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

    try {
        //DocumentBuilder对象
        DocumentBuilder documentBuilder = factory.newDocumentBuilder();
        //获取文档对象
        Document document = documentBuilder.parse(in);
        //获取文档对象的root
        Element root = document.getDocumentElement();
        //获取all根节点中所有的person节点对象
        NodeList musicNodes = root.getElementsByTagName("music");
        //遍历所有的music节点
        for (int i = 0; i < musicNodes.getLength(); i++) {
            Music music = new Music();
            //根据item(index)获取该索引对应的节点对象
            Element musicNode = (Element) musicNodes.item(i);
            music.group = Integer.parseInt(musicNode.getAttribute("group"));
            music.id = Integer.parseInt(musicNode.getAttribute("id"));

            //获取该节点下面的所有字节点
            NodeList musicChildNodes = musicNode.getChildNodes();
            //遍历music的字节点
            for (int index = 0; index < musicChildNodes.getLength(); index++) {
                //获取字节点
                Node node = musicChildNodes.item(index);
                //判断node节点是否是元素节点
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    //把节点转换成元素节点
                    Element element = (Element) node;
                    if ("name".equals(element.getNodeName())) {
                        music.name = element.getFirstChild().getNodeValue();
                    } else if ("author".equals(element.getNodeName())) {
                        music.author = element.getFirstChild().getNodeValue();
                    }
                }
            }
            data.add(music);
        }
    } catch (Exception e) {

    }
    return data;
}

这里写图片描述

完整代码如下:
目录结构
这里写图片描述

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.xmlparse.MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/pull_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="使用PULL解析" />

    <Button
        android:id="@+id/sax_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="使用SAX解析" />

    <Button
        android:id="@+id/dom_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="使用DOM解析" />
</LinearLayout>

MainActivity代码

import android.content.res.AssetManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView tv;
    private Button pullBtn, saxBtn, domBtn;

    private List<Music> data = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initEvent();
    }

    private void initView() {
        tv = (TextView) findViewById(R.id.tv);
        pullBtn = (Button) findViewById(R.id.pull_btn);
        saxBtn = (Button) findViewById(R.id.sax_btn);
        domBtn = (Button) findViewById(R.id.dom_btn);
    }

    private void initEvent() {
        pullBtn.setOnClickListener(this);
        saxBtn.setOnClickListener(this);
        domBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        data.clear();
        switch (v.getId()) {
            case R.id.pull_btn:
                data.addAll(pullParseXML(getXMLStream()));
                break;
            case R.id.sax_btn:
                data.addAll(saxParseXML(getXMLStream()));
                break;
            case R.id.dom_btn:
                data.addAll(domParseXML(getXMLStream()));
                break;
            default:
                break;
        }
        showXMLdata();
    }

    /**
     * 获取XML文件流
     *
     * @return
     */
    private InputStream getXMLStream() {
        AssetManager assets = getAssets();
        InputStream open = null;
        try {
            open = assets.open("musics.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return open;
    }

    /**
     * 显示获取的数据
     */
    private void showXMLdata() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.size(); i++) {
            sb.append(data.get(i).toString());
            sb.append("\n");
        }
        tv.setText(sb.toString());
    }

    /**
     * 使用pull解析
     *
     * @param in
     */
    private List<Music> pullParseXML(InputStream in) {
        ArrayList<Music> musics = null;
        try {
            XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
            XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser();
            xmlPullParser.setInput(in, "UTF-8");

            int eventType = xmlPullParser.getEventType();
            Music music = null;
            while (eventType != XmlPullParser.END_DOCUMENT) {
                String nodeName = xmlPullParser.getName();
                switch (eventType) {
                    case XmlPullParser.START_DOCUMENT://文档开始
                        musics = new ArrayList<>();
                        break;
                    case XmlPullParser.START_TAG://开始节点
                        if ("music".equals(nodeName)) {
                            music = new Music();
                            music.group = Integer.parseInt(xmlPullParser.getAttributeValue(0));
                            music.id = Integer.parseInt(xmlPullParser.getAttributeValue(1));
                        } else if ("name".equals(nodeName)) {
                            music.name = xmlPullParser.nextText();
                        } else if ("author".equals(nodeName)) {
                            music.author = xmlPullParser.nextText();
                        }
                        break;
                    case XmlPullParser.END_TAG://结束节点
                        if (music != null) {
                            musics.add(music);
                        }
                        music = null;
                        break;
                    default:
                        break;
                }
                //触发下一个事件
                eventType = xmlPullParser.next();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return musics;
    }


    /**
     * 使用sax解析
     *
     * @param in
     */
    private List<Music> saxParseXML(InputStream in) {
        try {
            SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
            SaxParseXML parseXML = new SaxParseXML();
            saxParser.parse(in, parseXML);
            return parseXML.getData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用dom解析
     *
     * @param in
     */
    private List<Music> domParseXML(InputStream in) {
        List<Music> data = new ArrayList<>();
        //创建DOM工厂对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        try {
            //DocumentBuilder对象
            DocumentBuilder documentBuilder = factory.newDocumentBuilder();
            //获取文档对象
            Document document = documentBuilder.parse(in);
            //获取文档对象的root
            Element root = document.getDocumentElement();
            //获取all根节点中所有的person节点对象
            NodeList musicNodes = root.getElementsByTagName("music");
            //遍历所有的music节点
            for (int i = 0; i < musicNodes.getLength(); i++) {
                Music music = new Music();
                //根据item(index)获取该索引对应的节点对象
                Element musicNode = (Element) musicNodes.item(i);
                music.group = Integer.parseInt(musicNode.getAttribute("group"));
                music.id = Integer.parseInt(musicNode.getAttribute("id"));

                //获取该节点下面的所有字节点
                NodeList musicChildNodes = musicNode.getChildNodes();
                //遍历music的字节点
                for (int index = 0; index < musicChildNodes.getLength(); index++) {
                    //获取字节点
                    Node node = musicChildNodes.item(index);
                    //判断node节点是否是元素节点
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        //把节点转换成元素节点
                        Element element = (Element) node;
                        if ("name".equals(element.getNodeName())) {
                            music.name = element.getFirstChild().getNodeValue();
                        } else if ("author".equals(element.getNodeName())) {
                            music.author = element.getFirstChild().getNodeValue();
                        }
                    }
                }
                data.add(music);
            }
        } catch (Exception e) {

        }
        return data;
    }
}

xml对应JavaBean类:

public class Music {
    public int group;
    public int id;
    public String name;
    public String author;

    @Override
    public String toString() {
        return "Music{" +
                "group=" + group +
                ", id=" + id +
                ", name='" + name + '\'' +
                ", author='" + author + '\'' +
                '}';
    }
}

SaxParseXML类已经贴上了,这里就不重复写了。
到这里常用的3种解析方式已经写完了,相信大家可以根据不同的XML文件来解析对应的数据了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值