天天看點

Android XML小工具

Android XML小工具

<b>一、概述</b>

    XML與Object互相轉化,支援8種基本類型、String和byte[]。byte[]需要經由base64編碼(API8以後才有,之前版本可以自己拷入)。

    更多代碼及測試用例,見附件工程!

<b>二、Object –&gt; XML</b>

public class XmlBuilder {  

    /**  

     * 由對象屬性生成XML  

     *   

     * @param outs 輸出流  

     * @param encoding 字元編碼  

     * @param obj 對象  

     */ 

    public void buildXml(OutputStream outs, String encoding, Object obj)  

            throws IllegalArgumentException, IllegalStateException,  

            IOException, IllegalAccessException {  

        XmlSerializer serializer = Xml.newSerializer(); // 建立一個Xml序列化  

        serializer.setOutput(outs, encoding); // 設定輸出流及字元編碼  

        serializer.startDocument(encoding, true); // 開始文檔  

        writeXml(serializer, obj); // 寫文檔  

        serializer.endDocument(); // 結束文檔  

        outs.close(); // 關閉輸出流  

    }  

     * 将對象屬性寫入XML  

     * @param serializer XML序列化  

    private void writeXml(XmlSerializer serializer, Object obj)  

        final String tag_type = "type";  

        final String tag_value = "value";  

        Class&lt;?&gt; cls = obj.getClass(); // 擷取對象運作時類  

        String clsName = cls.getName(); // 擷取對象名稱  

        serializer.startTag(null, clsName);  

        Field[] fields = cls.getDeclaredFields(); // 傳回類聲明的所有字段  

        boolean isWrite;  

        Class&lt;?&gt; type; // 變量類型  

        String varName, typeName, value = null; // 變量名、類型名、變量值  

        for (Field field : fields) {  

            isWrite = true;  

            type = field.getType(); // 擷取變量類型  

            typeName = type.getName(); // 擷取類型名  

            field.setAccessible(true); // 設定變量可通路  

            if (type.isPrimitive()) { // 是否為基本類型  

                if (typeName.equals("boolean")) {  

                    value = String.valueOf(field.getBoolean(obj));  

                } else if (typeName.equals("char")) {  

                    // char型未指派,為預設'\u0000'時,會影響parser.next()  

                    char c = field.getChar(obj);  

                    value = c == '\u0000' ? "null" : String.valueOf(field  

                            .getChar(obj));  

                } else if (typeName.equals("byte")) {  

                    value = String.valueOf(field.getByte(obj));  

                } else if (typeName.equals("short")) {  

                    value = String.valueOf(field.getShort(obj));  

                } else if (typeName.equals("int")) {  

                    value = String.valueOf(field.getInt(obj));  

                } else if (typeName.equals("long")) {  

                    value = String.valueOf(field.getLong(obj));  

                } else if (typeName.equals("float")) {  

                    value = String.valueOf(field.getFloat(obj));  

                } else if (typeName.equals("double")) {  

                    value = String.valueOf(field.getDouble(obj));  

                }  

            } else if (typeName.equals("java.lang.String")) { // 是否為String  

                value = field.get(obj) == null ? "null" : field.get(obj)  

                        .toString();  

            } else if (typeName.equals("[B")) { // 是否為byte[]  

                typeName = getTypeHelper(type); // 字元代碼-&gt;[]形式  

                // 用Base64将byte[]轉成字元串(SDK 2.2之後自帶)  

                value = field.get(obj) == null ? "null" 

                        : Base64.encodeToString((byte[]) field.get(obj),  

                                Base64.DEFAULT);  

            } else { // 其他類型暫不需要  

                isWrite = false;  

            }  

            if (isWrite) {  

                varName = field.getName(); // 擷取變量名  

                serializer.startTag(null, varName);  

                writeTag(serializer, tag_type, typeName);  

                writeTag(serializer, tag_value, value);  

                serializer.endTag(null, varName);  

        }  

        serializer.endTag(null, clsName);  

     * 字元代碼-&gt;[]形式  

    private String getTypeHelper(Class&lt;?&gt; type) {  

        if (type.isArray()) {  

            Class&lt;?&gt; c = type.getComponentType();  

            return getTypeHelper(c) + "[]";  

        } else {  

            return type.getName();  

     * 寫一個标簽及值  

    private void writeTag(XmlSerializer serializer, String tag, String value)  

            throws IllegalArgumentException, IllegalStateException, IOException {  

        serializer.startTag(null, tag);  

        serializer.text(value);  

        serializer.endTag(null, tag);  

<b>三、XML -&gt; Object</b>

public class XmlParser {  

     * 分析XML将對應值賦予對象  

     * @param ins 輸入流  

    public void parseXml(InputStream ins, String encoding, Object obj)  

            throws XmlPullParserException, IllegalArgumentException,  

            UnsupportedEncodingException, IllegalAccessException, IOException {  

        XmlPullParser parser = Xml.newPullParser(); // 建立一個Xml分析器  

        parser.setInput(ins, encoding); // 設定輸入流及字元編碼  

        parseXml(parser, obj); // 解析文檔  

        ins.close(); // 關閉輸入流  

     * 分析XML詳細步驟  

     * @param parser Xml分析器  

    private void parseXml(XmlPullParser parser, Object obj)  

        Field field = null;  

        int tagDepth; // 标簽深度  

        String tagName; // 标簽名稱  

        int eventType = parser.getEventType(); // 擷取事件類型  

        while (true) {  

            if (eventType == XmlPullParser.START_DOCUMENT) {  

                // Log.i("START_DOCUMENT", "=START_DOCUMENT");  

            } else if (eventType == XmlPullParser.START_TAG) {  

                // Log.i("START_TAG", "=START_TAG");  

                tagDepth = parser.getDepth(); // 擷取标簽深度  

                tagName = parser.getName(); // 擷取标簽名稱  

                if (tagDepth == 1) { // 一級标簽  

                    if (!tagName.equals(clsName)) { // 與對象名稱不一緻時  

                        throw new XmlPullParserException("XML首标簽名與對象名稱不一緻");  

                    }  

                } else if (tagDepth == 2) { // 二級标簽  

                    // 判斷标簽名稱是否符合類的某一字段名稱  

                    field = hasField(tagName, fields);  

                } else if (tagDepth == 3 &amp;&amp; field != null) { // 三級标簽  

                    if (tagName.equals(tag_value)) { // 如果是value标簽  

                        setValue(obj, field, parser.nextText());  

                        field = null;  

            } else if (eventType == XmlPullParser.END_TAG) {  

                // Log.i("END_TAG", "=END_TAG");  

            } else if (eventType == XmlPullParser.TEXT) {  

                // Log.i("TEXT", "=TEXT");  

            } else if (eventType == XmlPullParser.END_DOCUMENT) {  

                // Log.i("END_DOCUMENT", "=END_DOCUMENT");  

                break;  

            eventType = parser.next(); // 下一解析事件  

     * 判斷标簽名稱是否符合類的某一字段名稱  

     * @param tagName 标簽名稱  

     * @param fields 類字段集合  

     * @return 符合:Field;否則:null  

    private Field hasField(String tagName, Field[] fields) {  

            if (tagName.equals(field.getName())) {  

                return field;  

        return null;  

     * 給字段設值  

     * @param field 字段  

     * @param value 值  

    private void setValue(Object obj, Field field, String value)  

            throws IllegalArgumentException, IllegalAccessException,  

            UnsupportedEncodingException {  

        Class&lt;?&gt; type = field.getType(); // 變量類型  

        String typeName = type.getName(); // 類型名  

        field.setAccessible(true); // 設定變量可通路  

        if (type.isPrimitive()) { // 是否為基本類型  

            if (typeName.equals("boolean")) {  

                field.setBoolean(obj, Boolean.parseBoolean(value));  

            } else if (typeName.equals("char")) {  

                if (!value.equals("null")) {  

                    field.setChar(obj, value.charAt(0));  

            } else if (typeName.equals("byte")) {  

                field.setByte(obj, Byte.parseByte(value));  

            } else if (typeName.equals("short")) {  

                field.setShort(obj, Short.parseShort(value));  

            } else if (typeName.equals("int")) {  

                field.setInt(obj, Integer.parseInt(value));  

            } else if (typeName.equals("long")) {  

                field.setLong(obj, Long.parseLong(value));  

            } else if (typeName.equals("float")) {  

                field.setFloat(obj, Float.parseFloat(value));  

            } else if (typeName.equals("double")) {  

                field.setDouble(obj, Double.parseDouble(value));  

        } else if (typeName.equals("java.lang.String")) { // 是否為String  

            if (!value.equals("null")) {  

                field.set(obj, value);  

        } else if (typeName.equals("[B")) { // 是否為byte[]  

                // 用Base64将字元串轉成byte[](SDK 2.2之後自帶)  

                field.set(obj, Base64.decode(value, Base64.DEFAULT));  

        } // 其他類型暫不需要  

<b>四、後記</b>

<a href="http://down.51cto.com/data/2360816" target="_blank">附件:http://down.51cto.com/data/2360816</a>

     本文轉自winorlose2000 51CTO部落格,原文連結:http://blog.51cto.com/vaero/900852,如需轉載請自行聯系原作者