Android使用Dom与SAX解析XML文件支持任意对象的读

来源:互联网 发布:英文seo教程 编辑:程序博客网 时间:2024/06/05 17:34


本工具类:主要运用到了java的反射来解析泛型的属性,并根据泛型属性来设置对象属性值,如果这点弄很熟悉的话,对于类似这种小框架的话应该都不成问题,


我的上一编文章没使用反射与泛型,各位大神可以比较下,哪种方式的灵活度

不使用反射与泛型


一.使用dom方式:

package com.example.lxb.mircoxml.xml;import com.example.lxb.mircoxml.AppContext;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;/** * Created by lxb on 2017/4/27. */public class XmlByDom<T> {    /**     * T t :为生返回的对象     * <p>     * <Volbook>     * <p>     * <Item>           通常解析从这个结点开始     * <ID>0</ID>     * <type>1</type>     * <key>518</key>     * <cmd>no</cmd>     * </Item>     * </Volbook>     *     * @param path     * @return     */    public List<T> parseXMLByDom(String path, T t) {        InputStream is = null;        try {            is = AppContext.getInstance().getAssets().open(path);            Field[] fields = t.getClass().getDeclaredFields();      // 获得实例的属性,顺序并不会保证有序            Map<String, Field> fieldList = FieldUtils.buildFiledList(fields);            Method setmeth;                // 实例的set方法            List<T> s = new ArrayList<>();            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();            DocumentBuilder builder = factory.newDocumentBuilder();            Document doc = builder.parse(is);            Element rootElement = doc.getDocumentElement();            String secondNode = t.getClass().getSimpleName();       //二级结点作为解析开始的结点            NodeList items = rootElement.getElementsByTagName(secondNode);            /**             * 每遍历一次解析的结点,需要实例一个对象             */            for (int i = 0; i < items.getLength(); i++) {                t = (T) t.getClass().newInstance();                     // 获得对象的新的实例                Node item = items.item(i);                NodeList properties = item.getChildNodes();                for (int j = 0; j < properties.getLength(); j++) {                    Node property = properties.item(j);                    if (property instanceof Element) {                        String nodeName = property.getNodeName();                        /**                         * 这里主要,处理 反射获取 属性无序的情况                         */                        String method = "set" + nodeName.substring(0, 1).toUpperCase() + nodeName.substring(1);                        setmeth = t.getClass().getMethod(method, fieldList.get(nodeName).getType());                        //System.out.println("95--------" + fieldList.get(nodeName).getType().toString());                        if(fieldList.get(nodeName).getType().toString().equals("int")){                            setmeth.invoke(t, Integer.parseInt(property.getFirstChild().getNodeValue()));                        }else if(fieldList.get(nodeName).getType().toString().equals("boolean")){                            setmeth.invoke(t, Boolean.parseBoolean(property.getFirstChild().getNodeValue()));                        }                        else{                            setmeth.invoke(t, property.getFirstChild().getNodeValue());                        }                    }                }                s.add(t);            }            return s;        } catch (IOException e) {            e.printStackTrace();        } catch (ParserConfigurationException e) {            e.printStackTrace();        } catch (SAXException e) {            e.printStackTrace();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        }        return null;    }}

2.使用SAX方式:

package com.example.lxb.mircoxml.xml;import com.example.lxb.mircoxml.AppContext;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;import java.util.Map;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;/** * 使用Sax解析xml文档 * <p> * Created by lxb on 2017/4/26. */public class ParseXMLSAX<T> {    private static ParseXMLSAX parseXMLSAX;    public static ParseXMLSAX getInstance() {        if (parseXMLSAX == null) {            parseXMLSAX = new ParseXMLSAX();        }        return parseXMLSAX;    }    /**     * 获取assets文件     *     * @param path     * @return     */    public InputStream getFileInputStream(String path) {        try {            return AppContext.getInstance().getAssets().open(path);        } catch (IOException e) {            e.printStackTrace();        }        return null;    }    /**     * 解析xml文档     *     * @param path     * @return     * @throws Exception     */    public List<T> parse(String path, T t) throws Exception {        InputStream is = getFileInputStream(path);        SAXParserFactory factory = SAXParserFactory.newInstance();        SAXParser parser = factory.newSAXParser();        SaxXmlHandler<T> handler = new SaxXmlHandler<>(t);        parser.parse(is, handler);        return handler.getvoiceEntitys();    }    /**     * DefaultHandler是一个事件处理器,可以接收解析器报告的所有事件,处理所发现的数据     */    private class SaxXmlHandler<T> extends DefaultHandler {        private List<T> voiceEntitys;        private T second;        private StringBuilder builder;        private Field[] fields;        private String secondNode;        private Method setMethod;                // 实例的set方法        private  Map<String, Field> fieldList;        public List<T> getvoiceEntitys() {            return voiceEntitys;        }        public SaxXmlHandler(T t) {            this.second = t;        }        @Override        public void startDocument() throws SAXException {            // TODO Auto-generated method stub            super.startDocument();            voiceEntitys = new ArrayList<>();            builder = new StringBuilder();            fields = this.second.getClass().getDeclaredFields();      // 获得实例的属性,顺序并不会保证有序            fieldList = FieldUtils.buildFiledList(fields);            secondNode = this.second.getClass().getSimpleName();        }        @Override        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {            // TODO Auto-generated method stub            super.startElement(uri, localName, qName, attributes);            if (localName.equals(secondNode)) {     //在开始解析的结点处先new一个实例                try {                    second = (T) this.second.getClass().newInstance();                } catch (InstantiationException e) {                    e.printStackTrace();                } catch (IllegalAccessException e) {                    e.printStackTrace();                }            }            builder.setLength(0);        }        @Override        public void characters(char[] ch, int start, int length) throws SAXException {            // TODO Auto-generated method stub            super.characters(ch, start, length);            builder.append(ch, start, length);                  //将读取的字符数组追加到builder        }        @Override        public void endElement(String uri, String localName, String qName) throws SAXException {            // TODO Auto-generated method stub            super.endElement(uri, localName, qName);            try {                if(fieldList.containsKey(localName)){                    String method = "set" + localName.substring(0, 1).toUpperCase() + localName.substring(1);                    setMethod =  this.second.getClass().getMethod(method, fieldList.get(localName).getType());                    if(fieldList.get(localName).getType().toString().equals("int")){                        setMethod.invoke(this.second, Integer.parseInt(builder.toString()));                    }else if(fieldList.get(localName).getType().toString().equals("boolean")){                        setMethod.invoke(this.second, Boolean.parseBoolean(builder.toString()));                    }                    else{                        setMethod.invoke(this.second, builder.toString());                    }                }                if(localName.equals(secondNode)){       //说明第一层结点解析结束                    voiceEntitys.add(this.second);                }            } catch (NoSuchMethodException e) {                e.printStackTrace();            } catch (InvocationTargetException e) {                e.printStackTrace();            } catch (IllegalAccessException e) {                e.printStackTrace();            }        }    }}

3.工具类:

package com.example.lxb.mircoxml.xml;import java.lang.reflect.Field;import java.util.HashMap;import java.util.Map;/** * Created by lxb on 2017/4/28. */public class FieldUtils {    public static  Map<String, Field> buildFiledList(Field[] fields) {        Map<String, Field> fieldList = new HashMap<>();        for (int i = 0; i < fields.length; i++) {            String key = fields[i].toString().substring(fields[i].toString().lastIndexOf(".") + 1, fields[i].toString().length());            fieldList.put(key, fields[i]);        }        return fieldList;    }}

4.与xml文件对应的实体类:

package com.example.lxb.mircoxml.model;/** * Created by lxb on 2017/4/27. */public class Item {    private int ID;    private String type;    private String key;    private String cmd;    private boolean b;    public int getID() {        return ID;    }    public void setID(int ID) {        this.ID = ID;    }    public String getType() {        return type;    }    public void setType(String type) {        this.type = type;    }    public String getKey() {        return key;    }    public void setKey(String key) {        this.key = key;    }    public String getCmd() {        return cmd;    }    public void setCmd(String cmd) {        this.cmd = cmd;    }    public void setB(boolean b){        this.b = b;    }    public boolean getB(){        return this.b;    }}

xml文件:

<?xml version="1.0" encoding="UTF-8"?><volbook>    <!-- 音量加 -->    <Item>        <ID>0</ID>        <type>1</type>        <key>518</key>        <cmd>ywrtwer</cmd>        <b>true</b>    </Item>    <!-- 音量减 -->    <Item>        <ID>1</ID>        <type>1</type>        <key>517</key>        <cmd>no</cmd>        <b>true</b>    </Item>    <!-- 亮度加 -->    <Item>        <ID>2</ID>        <type>1</type>        <key>520</key>        <cmd>刘胡来</cmd>        <b>true</b>    </Item></volbook>  

6.测试代码:

private void readDom(){  /*  XmlByDom<Item> dom = new XmlByDom<>();    List<Item> tt = dom.parseXMLByDom("123.xml",new Item());*/    ParseXMLSAX<Item> dom = new ParseXMLSAX<>();    List<Item> tt = null;    try {        tt = dom.parse("123.xml",new Item());    } catch (Exception e) {        e.printStackTrace();    }    System.out.println("62------------------id :"+tt.get(0).getID() + "  type:" + tt.get(0).getType()            + " key:" + tt.get(0).getKey() + " cmd:" +tt.get(0).getCmd() + " b: "+tt.get(0).getB());}

可以仿造这种方式将任意对象写到xml文件中去


0 0
原创粉丝点击