Android-XmlPullParser解析XML

Android-XmlPullParser解析XML

前言

Android提供了XmlPullParser作为XML的解析器。以Android的布局xml为例,我们可以把Android的XML抽象成

我们把XML的节点进行抽象WidgetModel类。


    public class WidgetModel {

        private WidgetModel parent;// 父节点

        private String widgetName;// widgetName: RelativeLayout , ImageView .etc
        private List<WidgetModel> children;// 布局内部的控件
        private Map<String, String> properties;// 控件的属性

        ...

那么,如何将一个XML解析出来呢?以如下XML为例:


    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout
    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:fitsSystemWindows="true"
    tools:context="com.example.mochuanzhb.myapplication.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

    </android.support.design.widget.CoordinatorLayout>

解析的Utils代码如下:


    import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * @version mochuan.zhb on 2016/3/21.
 * @Author Zheng Haibo
 * @PersonalWebsite http://www.mobctrl.net
 * @Description 使用xml的pull方式,进行xml解析
 */
public class XmlPullParseTools {

    /**
     * Use XmlPullParse parse the xml
     *
     * @param inputStream
     * @return
     */
    public static WidgetModel parseXml(InputStream inputStream) {
        Stack<WidgetModel> widgetModels = new Stack<WidgetModel>();//store the tree node
        try {
            XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
            parser.setInput(inputStream, null);
            int eventType = parser.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                    case XmlPullParser.START_DOCUMENT:
                        Utils.LOG("###START_DOCUMENT");
                        break;
                    case XmlPullParser.START_TAG://push
                        WidgetModel node = createWidgetModel(parser);
                        widgetModels.push(node);
                        break;
                    case XmlPullParser.END_TAG://pop
                        String endTag = parser.getName();
                        Utils.LOG("###END_TAG tagName = " + endTag);
                        wrappedWidgetModel(widgetModels);
                        break;
                    case XmlPullParser.END_DOCUMENT:
                        Utils.LOG("###END_DOCUMENT");
                        break;
                }
                eventType = parser.next();
            }
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return widgetModels.pop();//pop the root of tree
    }

    public static WidgetModel parseXml(String xml) {
        return parseXml(new ByteArrayInputStream(xml.getBytes()));
    }

    /**
     * build tree
     *
     * @param widgetModels
     */
    private static void wrappedWidgetModel(Stack<WidgetModel> widgetModels) {
        Utils.LOG("###wrappedWidgetModel size = " + widgetModels.size());
        if (widgetModels.size() == 1) {
            return;
        }
        WidgetModel child = widgetModels.pop();
        WidgetModel parent = widgetModels.peek();
        List<WidgetModel> children = parent.getChildren();
        if (children == null) {
            children = new ArrayList<WidgetModel>();
        }
        children.add(child);
        parent.setChildren(children);
        child.setParent(parent);
    }

    /**
     * create one tree node
     *
     * @param parser
     * @return
     */
    private static WidgetModel createWidgetModel(XmlPullParser parser) {
        String widgetName = parser.getName();
        Utils.LOG("###START_TAG widgetName = " + widgetName);
        WidgetModel node = new WidgetModel();
        node.setWidgetName(widgetName);
        Map<String, String> properties = new LinkedHashMap<String, String>();
        int count = parser.getAttributeCount();
        for (int i = 0; i < count; i++) {
            String key = parser.getAttributeName(i);
            String value = parser.getAttributeValue(i);
            Utils.LOG("###printAttribute= (" + key + "," + value + ")");
            properties.put(key, value);
        }
        node.setProperties(properties);
        return node;
    }


    public static void printWidgetModel(WidgetModel widgetModel) {
        if (widgetModel == null) {
            return;
        }
        Utils.LOG("###widgetName = " + widgetModel.getWidgetName());
        for (Map.Entry<String, String> entry : widgetModel.getProperties().entrySet()) {
            Utils.LOG("###" + entry.getKey() + "," + entry.getValue());
        }
        if (widgetModel.getChildren() != null) {
            for (WidgetModel child : widgetModel.getChildren()) {
                printWidgetModel(child);
            }
        }
    }


    }

调用parseXml方法之后,XML就解析为以WidgetModel为根节点的多叉树。可以调用printWidgetModel 方法,打印多叉树。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值