Android-XmlPullParser解析XML
16lz
2021-01-23
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 方法,打印多叉树。
更多相关文章
- android中textview控件中的文字的位置是如何调整的
- Android中设置控件可见与不可见详解
- Android下拉框控件Spinner的使用
- android之控件EditText学习
- Android 线性布局(LinearLayout)内各控件如何设置间距
- android刮奖控件,使用简单。
- android 5.0系统 EditText控件