解析XML格式数据

比如下面这个格式的xml:

<apps>
    <app id="1">
         <name>Google Maps</name>
         <version>1.0</version>
    </app>   
    <app id="2">
         <name>Chrome</name>
         <version>2.1</version>
    </app>  
    <app id="3">
         <name>Google Play</name>
         <version>2.3</version>
    </app>
</apps>

App类

public class App implements Parcelable {
    private int id;
    private String name;
    private double version;

    @Override
    public String toString() {
        return "App [id=" + id + ", name=" + name + ", version=" + version
                + "]";
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getVersion() {
        return version;
    }

    public void setVersion(double version) {
        this.version = version;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeString(name);
        dest.writeDouble(version);
    }

    public static final Parcelable.Creator<App> CREATOR = new Parcelable.Creator<App>() {

        @Override
        public App createFromParcel(Parcel source) {
            App app = new App();
            app.id = source.readInt();
            app.name = source.readString();
            app.version = source.readDouble();
            return app;
        }

        @Override
        public App[] newArray(int size) {
            return new App[size];
        }
    };

}

DOM方式解析

public class XmlDomParserUtils {
    public static String parserXmlwithDom(InputStream inputStream) {
        List<App> mAppList = new ArrayList<App>();
        try {
            // 第一步:得到DOM 解析器的工厂实例
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            // 第二步:从DOM 工厂获取DOM 解析器
            DocumentBuilder db = dbf.newDocumentBuilder();
            // 第三步:解析xml 文档,获得document 对象,即DOM 树
            Document doc = db.parse(inputStream);
            convertXMLtoApp(doc, mAppList);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return mAppList.toString();
    }

    public static String parserXmlwithDom(String xml) {
        List<App> games = new ArrayList<App>();
        try {
            // 第一步:得到DOM 解析器的工厂实例
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            // 第二步:从DOM 工厂获取DOM 解析器
            DocumentBuilder builder = dbf.newDocumentBuilder();
            // 第三步:解析xml 文档,获得document 对象,即DOM 树
            Document document = builder.parse(new File(xml));
            convertXMLtoApp(document, games);
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        return games.toString();
    }

    /** * 解析 * * @param document * @param apps * @return */
    private static List<App> convertXMLtoApp(Document document, List<App> apps) {
        // 获取根节点 该方法在获取到Document实例对象后,通过document对象来获取根节点
        Element rootElement = document.getDocumentElement();
        rootElement.normalize();
        // 打印根节点的名字
        System.out.println(rootElement.getNodeName());
        // 获取根节点的子节点中名字为"app"的节点列表 ,
        NodeList appNodes = document.getElementsByTagName("app");
        // Nodelist是一个存放节点对象的集合
        // 遍历<app>节点
        for (int i = 0; i < appNodes.getLength(); i++) {
            // 获取一个<app>节点
            Element node = (Element) appNodes.item(i);
            // 打印app节点的名字
            System.out.println("--" + node.getNodeName());
            // 获取<app>节点中的属性(getAttribute()获取属性值)
            String id = node.getAttribute("id");
            System.out.println("\tid:" + id);
            // 获取<app>节点的子节点中名字为"name"的节点列表
            NodeList nameNodes = node.getElementsByTagName("name");
            // 取得第一个name
            Element nameNode = (Element) nameNodes.item(0);
            // getTextContent()这方法是 获取节点对应的值
            // <name>Google Maps</name> : “Google Maps”即为元素节点“name”的
            // txtContent值
            String name = nameNode.getTextContent();
            System.out.println("-------" + name);

            // 获取<app>节点的子节点中名字为"version"的节点列表
            NodeList versionNodes = node.getElementsByTagName("version");
            // 取得第一个version
            Element versionNode = (Element) versionNodes.item(0);
            // getTextContent()这方法是 获取节点对应的值
            // <version>1.0</version> : “1.0”即为 元素节点“version”的 txtContent值
            String version = versionNode.getTextContent();
            System.out.println("-------" + version);
            App app = new App();
            app.setId(Integer.parseInt(id));
            app.setName(name);
            app.setVersion(Double.parseDouble(version));
            apps.add(app);
        }
        return apps;
    }

}

Pull方式解析:

public class XmlPullParserUtils {

    public static String parserXmlwithPull(InputStream inputStream) {
        StringBuilder sb = new StringBuilder();
        List<App> mAppList = null;
        App app = null;
        try {
            XmlPullParserFactory mXmlFactory = XmlPullParserFactory
                    .newInstance();
            XmlPullParser parser = mXmlFactory.newPullParser();
            parser.setInput(inputStream, "utf-8");
            // 得到当前的解析事件
            int eventType = parser.getEventType();
            boolean flag = false;
            // 不等于XmlPullParser.END_DOCUMENT,说明解析工作没有结束
            while (eventType != XmlPullParser.END_DOCUMENT) {
                // getName()得到当前节点的名字
                String mNode = parser.getName();
                switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    mAppList = new LinkedList<App>();
                    break;
                case XmlPullParser.START_TAG:
                    if (mNode.equalsIgnoreCase("app")) {
                        app = new App();
                        String mStrId = parser.getAttributeValue(0);
                        app.setId(Integer.valueOf(mStrId));
                        flag = true;
                    }
                    if (flag) {
                        if (mNode.equalsIgnoreCase("name")) {
                            // nextText()获取节点内具体的内容
                            app.setName(parser.nextText());
                        } else if (mNode.equalsIgnoreCase("version")) {
                            app.setVersion(Double.valueOf(parser.nextText()));
                        }
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if (mNode.equalsIgnoreCase("app")) {
                        if (app != null) {
                            mAppList.add(app);
                            app = null;
                            flag = true;
                        }
                    }
                    break;
                case XmlPullParser.TEXT:
                    eventType = parser.next();
                    continue;
                default:
                    break;
                }
                // 获取下一个解析事件
                eventType = parser.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (mAppList != null) {
            for (App mAPP : mAppList) {
                sb.append(mAPP);
                sb.append("\n");
            }
        }
        return sb.toString();
    }

    public static String parserXmlwithPull(String xml) {

        StringBuilder sb = new StringBuilder();
        List<App> mAppList = null;
        App app = null;
        try {
            XmlPullParserFactory mXmlFactory = XmlPullParserFactory
                    .newInstance();
            XmlPullParser parser = mXmlFactory.newPullParser();
            parser.setInput(new StringReader(xml));
            int eventType = parser.getEventType();
            boolean flag = false;
            while (eventType != XmlPullParser.END_DOCUMENT) {
                print(eventType);
                String mNode = parser.getName();
                switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    mAppList = new LinkedList<App>();
                    break;
                case XmlPullParser.START_TAG:
                    if (mNode.equalsIgnoreCase("app")) {
                        app = new App();
                        String mStrId = parser.getAttributeValue(0);
                        app.setId(Integer.valueOf(mStrId));
                        flag = true;
                    }
                    if (flag) {
                        if (mNode.equalsIgnoreCase("name")) {
                            app.setName(parser.nextText());
                        } else if (mNode.equalsIgnoreCase("version")) {
                            app.setVersion(Double.valueOf(parser.nextText()));
                        }
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if (mNode.equalsIgnoreCase("app")) {
                        if (app != null) {
                            mAppList.add(app);
                            app = null;
                            flag = true;
                        }
                    }
                    break;
                case XmlPullParser.TEXT:
                    eventType = parser.next();
                    continue;
                default:
                    break;
                }
                eventType = parser.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (mAppList != null) {
            for (App mAPP : mAppList) {
                sb.append(mAPP);
                sb.append("\n");
            }
        }
        return sb.toString();
    }
}

SAX方式解析

public class XmlSAXParserUtils {
    public static String parserXmlwithSAX(InputStream input) {
        String content = "";
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            SAXHandler mHandler = new SAXHandler();
            parser.parse(input, mHandler);
            content = mHandler.getmAppList();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }

    public static String parserXmlwithSAX(String xml) {
        String content = "";
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            SAXHandler mHandler = new SAXHandler();
            parser.parse(new InputSource(new StringReader(xml)), mHandler);
            content = mHandler.getmAppList();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }

    public static final class SAXHandler extends DefaultHandler {
        private List<App> mAppList;
        private App app;
        private String tag;

        public String getmAppList() {
            Log.e("SAX", "getmAppList");
            StringBuilder sb = new StringBuilder();
            if (mAppList != null && mAppList.size() > 0) {
                for (App mApp : mAppList) {
                    sb.append(mApp.toString());
                    sb.append("\n");
                }
            }
            return sb.toString();
        }

        // 开始读文档时触发,在解析整个xml文档时,只会被触发一次
        @Override
        public void startDocument() throws SAXException {
            mAppList = new LinkedList<App>();
        }

        // 接收元素开始
        // uri:元素的命名空间
        // localName:元素的本地名称(不带前缀)
        // qName:元素的限定名(带前缀)
        // atts:元素的属性集合
        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            if (localName.equals("app")) {
                if (app == null) {
                    app = new App();
                }
                int attr = attributes.getLength();
                for (int i = 0; i < attr; i++) {
                    String attrName = attributes.getLocalName(i);
                    if (attrName.equals("id")) {
                        String attrValue = attributes.getValue(i);
                        app.setId(Integer.parseInt(attrValue));
                    }
                }
            }
            tag = localName;
        }

        // 接收元素中字符数据的通知 <></>一对元素节点内的值
        // eg:<name>Google Maps</name>,那characters 这个方法就是在获取Google Maps这个值

        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            if (tag != null) {
                if (tag.equals("name")) {
                    String data = new String(ch, start, length).trim();
                    app.setName(data);
                }
                if (tag.equals("version")) {
                    String data = new String(ch, start, length).trim();
                    app.setVersion(Double.parseDouble(data));
                }
            }
        }

        // 接收文档的结尾的通知。
        // uri:元素的命名空间
        // localName:元素的本地名称(不带前缀)
        // name:元素的限定名(带前缀)
        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            if (localName.equals("app")) {
                mAppList.add(app);
                app = null;
            }
            tag = null;// 这个很关键,执行完了endElement之后,还会回调几次characters
        }

        // 完成整个文档解析工作
        @Override
        public void endDocument() throws SAXException {

        }
    }

}

完整代码下载

你可能感兴趣的:(sax,dom,xml解析,pull)