Android使用Pull解析和SAX解析两种方法解析XML格式数据

在网络上传输数据时最常用的格式有两种:XML和JSON。解析XML格式数据常用的方法有两种:Pull解析和SAX解析。

首先假设服务器上有一个XML文件,文件内容为:

<apps>
	<app>
		<id>1</id>
		<name>Google Maps</name>
		<version>1.0</version>
	</app>

	<app>
		<id>2</id>
		<name>Chrome</name>
		<version>2.1</version>
	</app>

	<app>
		<id>3</id>
		<name>Google Play</name>
		<version>2.3</version>
	</app>
</apps>

假设已经使用OkHttp向服务器请求该文件,并将结果保存在responseData字符串里。

1.Pull解析

Pull解析是一个遍历文档的过程,具体代码如下:

private void parseXMLWithPull(String responseData){//参数为存放数据的字符串
        try{
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();//获取XmlPullParserFactory实例
            XmlPullParser xmlPullParser = factory.newPullParser();//获取XmlPullParser对象
            xmlPullParser.setInput(new StringReader(responseData));//将获取到的数据传入XmlPullParser对象
            int eventType = xmlPullParser.getEventType();//获取解析事件类型
            String id = "";
            String name = "";
            String version = "";

            while (eventType != XmlPullParser.END_DOCUMENT){//若解析未完成,继续解析
                String nodeName = xmlPullParser.getName();//获取节点名字
                switch (eventType){//根据解析事件类型判断是开始标签还是结束标签
                    case XmlPullParser.START_TAG:{//如果是开始标签通过判断将数据写入字符串
                        if ("id".equals(nodeName)){
                            id = xmlPullParser.nextText();//调用nextText()方法获取节点内具体的内容
                        }
                        else if ("name".equals(nodeName)){
                            name = xmlPullParser.nextText();
                        }
                        else if ("version".equals(nodeName)){
                            version = xmlPullParser.nextText();
                        }
                        break;
                    }
                    case XmlPullParser.END_TAG:{//如果是结束标签则表示某个节点完成解析
                        if ("app".equals(nodeName)){
                            Log.d("MainActivity","id is " + id);
                            Log.d("MainActivyty","name is " + name);
                            Log.d("MainActivity","version is " + version);

                        }
                        break;
                    }
                    default:

                        break;
                }
                eventType = xmlPullParser.next();//获取下一个解析事件类型
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

分析上述代码,可将解析过程分为如下几步:

(1)首先获取一个XmlPullParserFactory实例,并借助这个实例得到XmlPullParser对象。

(2)调用XmlPullParser对象的setInput()方法,把从服务器获取到的XML数据传入到对象中。

(3)从上到下开始遍历数据。通过XmlPullParser对象的getEventType()方法判断当前的解析事件类型是不是开始标签,通过调用XmlPullParser对象的getName()方法可以获取该标签节点的名字。

(4)如果是id/name/version节点的开始标签,就调用XmlPullParser对象的nextText()方法获取该节点里的内容,并且此时事件类型会自动跳转到该节点的结束标签,所以id/name/version节点的结束标签会被跳过,当getEventType()方法获取到的是结束标签时,该结束标签一定是app或apps的结束标签。

(5)倘若事件类型是app的结束标签就表示一个app节点的内容解析完成,通过Log将内容打印出来;

(6)在一个while循环中不断地进行解析,就可以将所有app节点的内容都解析出来。

 

2.SAX解析

SAX解析将数据的解析过程写在一个类里面,该类继承自DefaultHandler类,并且有5个方法需要重写,分别为:

(1)startDocument()方法:在开始XML解析的时候调用。

(2)startElement()方法:在开始解析某个节点的时候调用。

(3)characters()方法:在获取节点内容的时候调用。

(4)endElement()方法:在完成解析某个节点的时候调用。

(5)endDocument()方法:在完成整个XML解析的时候调用。

具体代码如下:

public class ContentHandler extends DefaultHandler{
    private String nodeName;

    private  StringBuilder id;

    private StringBuilder name;

    private  StringBuilder version;

    @Override
    public void startDocument() throws SAXException{//进行初始化操作
        id = new StringBuilder();
        name = new StringBuilder();
        version = new StringBuilder();
    }

    @Override
    public void startElement(String uri, String localName, String qName,
 Attributes attributes) throws SAXException{//开始解析节点的时候记录该节点的名字
        nodeName = localName;
    }

    @Override
    public void characters(char[] ch,int start, int length) throws  SAXException{
        if ("id".equals(nodeName)){//将解析内容保存在字符串中
            id.append(ch,start,length);
        }
        else if ("name".equals(nodeName)){
            name.append(ch,start,length);
        }
        else if ("version".equals(nodeName)){
            version.append(ch,start,length);
        }
    }

    @Override
    public void endElement(String uri,String localName,String qName) throws SAXException{//解析节点结束时打印该节点内容
        if ("app".equals(localName)){
            Log.d("ContentHandler","id is "+ id.toString().trim());//调用trim()方法清除内容里面的回车或换行符
            Log.d("ContentHandler","name is " + name.toString().trim());
            Log.d("ContentHandler","name is " + version.toString().trim());
            id.setLength(0);//将字符串里的内容打印后清空字符串,方便解析下一个节点时使用
            name.setLength(0);
            version.setLength(0);
        }
    }

    @Override
    public void endDocument() throws SAXException{//结束解析
        super.endDocument();
    }
}

上述代码中新建了一个ContentHandler类继承DefaultHandler类,类里面重写了5个父类方法,其中:startDocument()方法完成初始化操作,startElement()方法记录开始解析的节点名字,characters()方法通过节点名字判断该节点是否是id/name/version节点,endElement()方法内打印出节点内容,endDocument()方法结束解析。

在创建完ContentHandler类之后就可以开始解析工作了,代码如下:

 private void parseXMLWithSAX(String responseData){
        try{
            SAXParserFactory factory = SAXParserFactory.newInstance();//获取一个SAXParserFactory实例
            XMLReader xmlReader = factory.newSAXParser().getXMLReader();//通过SAXParserFactory实例获取XMLReader对象
            ContentHandler handler = new ContentHandler();//创建ContentHandler实例
            xmlReader.setContentHandler(handler);//将ContentHandler实例设置到XMLReader对象中
            xmlReader.parse(new InputSource(new StringReader(responseData)));//将从服务器中获取的数据传到XMLReader的parse()方法内开始解析工作
        }catch (Exception e){
            e.printStackTrace();
        }
    }

分析上述代码,可将解析过程分为如下几步:

(1)获取一个SAXParserFactory实例。

(2)通过SAXParserFactory实例得到XMLReader对象。

(3)创建ContentHandler实例并将ContentHandler实例设置到XMLReader对象中。

(4)将从服务器中获取的数据传到XMLReader的parse()方法内开始解析工作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值