安卓使用DOM,SAX,PULL解析xml,安卓写入xml文件

Xml简介

对Xml不太了解的同学可以看一下这篇Xml的简介:http://www.cnblogs.com/SkySoot/archive/2012/08/24/2654319.html

DOM解析Xml

Dom解析Xml的时候,会将Xml文件的所有内容以文件树的形式存储到内存中,然后用户通过使用DOM API遍历Xml树,检索需要的内容。

但是,因为它将文件树放在了内存中,如果文件较大的时候,对于安卓开发来说内存消耗太大,所以文件大时不推荐用DOM解析。

DOM解析的步骤如下:

1.利用DocumentBuilderFactory.newInstance()创建DocumentBuilderFactory实例

2.利用DocumentBuilderFactory创建DocumentBuilder

3.加载Document

4.获取文档根节点(Element)

5.用递归的方式读取各个子节点

 /**
     * 使用递归解析一个XML文档
     *
     */
    private void domParse() {
        InputStream inputStream = null;
        try {
            inputStream = getResources().getAssets().open("myuser.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(inputStream == null)
            return;
        StringBuffer stringBuffer = new StringBuffer();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(inputStream);
            Element rootElement = document.getDocumentElement();//users
            stringBuffer.append(parseElement(rootElement));
            textView.setText(stringBuffer.toString());
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private String parseElement(Element element) {
        StringBuffer stringBuffer = new StringBuffer();
        String tagName = element.getNodeName();
        stringBuffer.append("<" + tagName);
        // element元素的所有属性构成的NamedNodeMap对象,需要对其进行判断
        NamedNodeMap attributeMap = element.getAttributes();
        // 如果存在属性,则打印属性
        if (null != attributeMap) {
            for (int i = 0; i < attributeMap.getLength(); i++) {
                // 获得该元素的每一个属性
                Attr attr = (Attr) attributeMap.item(i);
                // 属性名和属性值
                String attrName = attr.getName();
                String attrValue = attr.getValue();
                // 注意属性值需要加上引号,所以需要\转义
                stringBuffer.append(" " + attrName + "=\"" + attrValue + "\"");
            }
        }
        // 关闭标签名
        stringBuffer.append(">");
        // 至此已经打印出了元素名和其属性
        // 下面开始考虑它的子元素
        NodeList children = element.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            // 获取每一个child
            Node node = children.item(i);
            // 获取节点类型
            short nodeType = node.getNodeType();
            if (nodeType == Node.ELEMENT_NODE) {
                // 如果是元素类型,则递归输出
                stringBuffer.append(parseElement((Element) node));
            } else if (nodeType == Node.TEXT_NODE) {
                // 如果是文本类型,则输出节点值,及文本内容
                stringBuffer.append(node.getNodeValue());
            } else if (nodeType == Node.COMMENT_NODE) {
                // 如果是注释,则输出注释
                stringBuffer.append("<!--");
                Comment comment = (Comment) node;
                // 注释内容
                String data = comment.getData();
                stringBuffer.append(data);
                stringBuffer.append("-->");
            }
        }
        // 所有内容处理完之后,输出,关闭根节点
        stringBuffer.append("</" + tagName + ">");
        return stringBuffer.toString();
    }

SAX解析Xml

Sax是基于事件驱动,边加载边解析的。我们会在解析的时候收到相应事件的回调

Sax解析的步骤如下:

1.根据SAXParserFactory.newInstance()得到SAXParserFactory实例

2.根据SAXParserFactory得到SAXParser

3.继承DefaultHandler,实现它的回调函数(startDocument() , startElement() , characters() , endElement() , endDocument() )

4.调用saxParser的parse()方法开始解析

private void saxParse() {
        InputStream inputStream = null;
        try {
            inputStream = getResources().getAssets().open("mylaunch.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(inputStream == null)
            return;

        final StringBuffer stringBuffer = new StringBuffer();
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            SAXParser saxParser = factory.newSAXParser();
            DefaultHandler defaultHandler = new DefaultHandler(){
                //开始解析文档,即开始解析XML根元素时调用该方法
                @Override
                public void startDocument() throws SAXException {
                    Log.d("zyr","startDocument");
                    super.startDocument();
                }
                //开始解析每个元素时都会调用该方法
                @Override
                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                    Log.e("zyr","startElement " + qName);
                    super.startElement(uri, localName, qName, attributes);
                    stringBuffer.append("<" + qName);
                    if(attributes!=null){
                        for(int i=0;i<attributes.getLength();i++){
                            stringBuffer.append(" " + attributes.getQName(i) + "=" + attributes.getValue(i));
                        }
                    }
                    stringBuffer.append(">");
                }
                //解析到每个元素的内容时会调用此方法
                @Override
                public void characters(char[] ch, int start, int length) throws SAXException {
                    Log.d("zyr","characters " + new String(ch,start,start+length));
                    super.characters(ch, start, length);
                    stringBuffer.append(new String(ch,start,start+length));
                }
                //每个元素结束的时候都会调用该方法

                @Override
                public void endElement(String uri, String localName, String qName) throws SAXException {
                    Log.e("zyr","endElement " + qName);
                    super.endElement(uri, localName, qName);
                    stringBuffer.append("</" + qName + ">");
                }
                //结束解析文档,即解析根元素结束标签时调用该方法
                @Override
                public void endDocument() throws SAXException {
                    Log.d("zyr","endDocument");
                    super.endDocument();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(stringBuffer.toString());
                        }
                    });
                }
            };
            saxParser.parse(inputStream,defaultHandler);

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

Pull解析Xml

Pull也是基于事件驱动的,它的使用步骤如下:

1.通过XmlPullParserFactory.newInstance()获取XmlPullParserFactory实例

2.通过XmlPullParserFactory获取XmlPullParser

3.通过xmlPullParser.setInput(inputStream,"UTF-8")设置输入流和编码

4.通过xmlPullParser.getEventType获得事件类型

5.通过xmlPullParser.next()循环,并且根据eventType进行相应的解析

private void pullParse() {
        InputStream inputStream = null;
        try {
            inputStream = getResources().getAssets().open("myfriends.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(inputStream == null)
            return;

        StringBuffer stringBuffer = new StringBuffer();
        try {
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser xmlPullParser = factory.newPullParser();
            xmlPullParser.setInput(inputStream,"UTF-8");
            int eventType = xmlPullParser.getEventType();
            while (eventType!= XmlPullParser.END_DOCUMENT){
                switch (eventType){
                    case XmlPullParser.START_DOCUMENT:
                        break;
                    case XmlPullParser.START_TAG:
                        stringBuffer.append("<" + xmlPullParser.getName());
                        for(int i=0;i<xmlPullParser.getAttributeCount();i++){
                            stringBuffer.append(" " + xmlPullParser.getAttributeName(i) + "=" + xmlPullParser.getAttributeValue(i));
                        }
                        stringBuffer.append(">");
                        break;
                    case XmlPullParser.TEXT:
                        stringBuffer.append(xmlPullParser.getText());
                        break;
                    case XmlPullParser.END_TAG:
                        stringBuffer.append("</" + xmlPullParser.getName() + ">");
                        break;
                    case XmlPullParser.END_DOCUMENT:
                        break;
                }
                eventType = xmlPullParser.next();
            }
            textView.append(stringBuffer.toString());
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

安卓写入Xml文件

安卓使用XmlSerializer创建Xml文件,具体步骤如下:

1.在manifest.xml中添加权限

   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

2.在需要的路径创建一个File,并且获得File的outPutStream流

3.通过Xml.newSerializr()获得XmlSerializer

4.通过xmlSerializer.setOutput(outputStream,"UTF-8")设置流和编码

5.调用startDocument()方法写入xml开始的标志

6.调用setFeature方法设置属性

7.调用startTag方法写入开始标签,调用attribute方法写入属性

8.调用text方法写入内容

9.调用endTag方法结束标签

10.调用endDocument方法结束文档

11.调用xmlSerializer.flush()方法和fileOutputStream.close()方法

  /**
     * 使用XmlSerializer创建XML文件
     */
    private void writeXml() {
        //别忘记在Mainfest添加权限
        //在SD卡创建名为poem.xml的文件
        File xmlFile = new File(getApplicationContext().getFilesDir().getAbsolutePath()+"/poem.xml");
        try {
            xmlFile.createNewFile();
            Log.d("zyr","path:" + xmlFile.getAbsolutePath());
            FileOutputStream os = new FileOutputStream(xmlFile);
            //创建XmlSerializer对象
            XmlSerializer xmlSerializer = Xml.newSerializer();
            xmlSerializer.setOutput(os,"UTF-8");
            xmlSerializer.startDocument("UTF-8",Boolean.valueOf(true));
            xmlSerializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",true);

            xmlSerializer.startTag(null,"poems");
                xmlSerializer.startTag(null,"poem");
                xmlSerializer.attribute(null,"id","1");
                xmlSerializer.text("你是谁呀");
                xmlSerializer.endTag(null,"poem");

                xmlSerializer.startTag(null,"poem");
                xmlSerializer.attribute(null,"id","2");
                    xmlSerializer.startTag(null,"author");
                    xmlSerializer.text("白居易");
                    xmlSerializer.endTag(null,"author");

                    xmlSerializer.startTag(null,"name");
                    xmlSerializer.text("待填写");
                    xmlSerializer.endTag(null,"name");

                    xmlSerializer.startTag(null,"content");
                    xmlSerializer.text("忘记了");
                    xmlSerializer.endTag(null,"content");
                xmlSerializer.endTag(null,"poem");
            xmlSerializer.endTag(null,"poems");
            xmlSerializer.endDocument();
            xmlSerializer.flush();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值