android-关于xml的解析

本文介绍在安卓环境中使用SAX方式解析XML的方法,包括下载XML文件、解析XML结构及内容的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天讲讲关于Xml的解析问题,在安卓上面,可以使用java.xml.parsers。这里面有关于xml的解析的类。

至于这么解析,首先先上一段代码:

HttpDownloader httpDownloader = new HttpDownloader();
            String xmlString = httpDownloader.download("http://192.168.2.100:8080/sourse/data.xml");
            Log.e("juetion", xmlString);
            //创建一个SXAParserFactory
            SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
            try {
                //
                XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();
                //为XMLReader设置内容处理器
                xmlReader.setContentHandler(new MyXMLContentHandler());
                //开始解析文件
                xmlReader.parse(new InputSource(new StringReader(xmlString)));
            } catch (Exception e) {
                e.printStackTrace();
            }

代码里面的HttpDownLoader这个类,请参考: android-关于下载网络资源以及写入到SD卡中 这里里面的代码。简单来说就是把网络上的Xml下载放在String里面。

SAXParserFactory是创建一个SAX的一个解析工厂。

XMLReader,如其名,就是用于读取XML文件的类。

重点是:xml.setContentHandler这个方法,里面的参数是ContentHandler类。这个下面会讲到。

xmlReader.parse这个方法就是开始解析某一个xml。

-----------我是可爱的分割线--------------------

话说回来,重点是在ContentHandler这个类。这个类是用于在处理解析时所触发的。有点像触发器。

一般的写法是继承DefaultHandler这个类。里面有很多方法:

如:1、startDocument 这个方法是在开始解析时触发的。

2、endDocument 这个方法是结束解析时触发的。

3、startElement 这个防范是开始解析某一元素时触发的

等等,很多。就不多说了。

我们需要关注的如何解析。所以我这里就直接附上代码,里面有注释

package org.juetion.xml.util;

import android.util.Log;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Created by juetionke on 13-12-23.
 */
public class MyXMLContentHandler extends DefaultHandler {

    private String tagName;
    private StringBuffer id,name,sex,address,grade;

    public MyXMLContentHandler() {
        //因为DefaultHandler.characters继承后,这个函数不是自信一次就获取标签内的内容的,所以需要用StringBuffer来拼接。
        id = new StringBuffer();
        name = new StringBuffer();
        sex = new StringBuffer();
        address = new StringBuffer();
        grade = new StringBuffer();
    }

    @Override
    public void startDocument() throws SAXException {
        Log.i("juetion","----------startDocument----------");
    }

    @Override
    public void endDocument() throws SAXException {
        Log.i("juetion","----------endDocument----------");
    }

    /**
     * localName是没有前缀的,qName是包括前缀的
     * @param uri
     * @param localName
     * @param qName
     * @param attributes
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        Log.i("juetion","----------startElement----------");
        tagName = localName;
        if (localName.equals("student")) {
            for (int i = 0; i < attributes.getLength(); i++) {
                Log.i("juetion",attributes.getLocalName(i) + "=" + attributes.getValue(i));
                if (attributes.getLocalName(i).equals("id")){
                    //获取标签内的属性
                    id = id.append(attributes.getValue(i));
                }
            }
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        Log.i("juetion","----------endElement----------");
        if (localName.equals("student")) {
            Log.i("juetion", "id:"+id+" name:" + name + " sex:" + sex + " address:" + address + " grade:" + grade);
            //拼接完了需要置空,这里直接new一个新对象,因为Java是垃圾处理机制,所以就不去用同一个对象然后再删除数据。
            id = new StringBuffer();
            name = new StringBuffer();
            sex = new StringBuffer();
            address = new StringBuffer();
            grade = new StringBuffer();
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        Log.i("juetion","----------characters----------");
        String str = new String(ch, start, length);
        //判断是否为空内容,如果是空内容,则不要拼接
        if (str.trim().equals("") )
            return ;
        if (tagName.equals("name")) {
            name = name.append(str);
        }else if (tagName.equals("sex")) {
            sex = sex.append(str);
        }else if (tagName.equals("address")) {
            address = address.append(str);
        }else if (tagName.equals("grade")) {
            grade = grade.append(str);
        }
    }
}

这段代码解析的XML文件内容:

<?xml version="1.0" encoding="UTF-8"?>

<students>
    <student id="A001">
        <name>张三</name>
        <sex>男</sex>
        <address>广州A区</address>
        <grade>A班</grade>
    </student>
    <student id="B001">
        <name>李四</name>
        <sex>男</sex>
        <address>广州B区</address>
        <grade>B班</grade>
    </student>
    <student id="C001">
        <name>王五</name>
        <sex>女</sex>
        <address>广州C区</address>
        <grade>C班</grade>
    </student>
</students>

我们这里重点讲以下的是:characters(char[] ch, int start, int length)这个方法。

它解析的是标签里面的内容。不是属性哦。属性的解析是在startElement这个方法里面。

characters(char[] ch, int start, int length)这个方法有点奇葩,因为它的ch本来是获取内容的。但是不知道为何,它获取并不是一次性全部内容获取的。而是会分断开的,所以这个方法会被调用多次的。如上面的<address>广州A区</address>,可能会分两次调用这个方法,第一次的ch为:广州,第二次的ch为:A区。也有可能分三次。这也就是为什么上面会用到StringBuffer这个类。因为我们需要拼接。

附上代码下载:http://download.youkuaiyun.com/detail/juetion/6763281

今月今日的android学习回顾到此结束了。谢谢观看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小明是我的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值