解析XML格式数据文件

Pull解析

使用HttpGet从服务器获得xml的文件
然后调用parseXMLWithPull(response);

parseXMLWithPull类

    private void parseXMLWithPull(String xmlData){
        try{
            XmlPullParserFactory factory=XmlPullParseFactory.newInstance();
            XmlPullParse xmlPullParser = factory.newPullParse();
            xmlPullParser.setInput(new StringReader(xmlData));
            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();
                        }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("aaa","id is"+id);
                            Log.d("aaa","name is"+name);
                            Log.d("aaa","version is"+version);
                        }
                        break;
                    }
                    default:
                        break;
                    }
                    eventType=xmlPullParse.next();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
  1. 这里首先要获得一个XmlPullParserFactory的实例,并借助这个实例得到XmlPullParser对象,然后调用XmlPullParser的setInput()方法将服务器返回的xml数据设置进去就可以解析了。
  2. 解析过程,通过getEventType()可以得到当前的解析时间,然后在一个while循环里进行解析,如果当前的解析事件不等于XmlPullParser.END_DOCUMENT,说明解析工作还没有完成,调用next()方法来获取下一个事件进行解析。
  3. 在while 循环中,我们通过getName()方法得到当前节点的名字,如果发现节点名等于id、name或version,就可以调用nextText()方法来获取节点内的具体内容,每当解析完一个app节点后就将数据打印出来。

SAX解析

SAX解析是一种特别常用的XML解析方式,虽然它的用法比Pull解析要复杂一些,但在语义方面会更加的清楚。

首先我们要新建一个类继承DefaultHandler,并重写其中的5个方法。

    public class MyHandler extends DefaultHandler{
        @override
        public void startDocument() throws SAXException{
        }
        @override
        public void startElement(String uri,String localName,String qName,Attributes attributes)throws SAXException{
        }
        @override 
        publiv void characters(char[] ch,int start,int length)throws SAXException{
        }
        @override
        public void endElement(String uri,String localName,String qName)throws SAXException{
        }
        @override
        public void endDocument throws SAXException{
        }
    }
  1. startDocument()方法会在开始XML解析的时候调用
  2. startElement()方法会在开始解析某个结点的时候调用
  3. characters()方法会在获取结点中内容的时候调用
  4. endElement()方法会在完成解析某个结点的时候调用
  5. endDocument()方法会在完成整个XML解析的时候调用

需要注意的是,在获取结点中内容时,characters()方法可能会被多次调用,一些换行符也被当做内容解析出来,我们需要针对这种情况在代码中做好控制。

示例

    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 StringBulider;
            version=new StringBuilder;
        }
        @override
        public void startElement(String uri,String localName,String qName,Attributes attributes)throws SAXException{
            //记录当前结点名
            nodeName=localName;
        }
        @override 
        publiv void characters(char[] ch,int start,int length)throws SAXException{
            //根据当前的结点名判断将内容添加到哪一个StringBuilder对象中
            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("content","id is"+id.toString().trim());
                Log.d("content","name is"+name.toString().trim());
                Log.d("content","version is"+version.toString().trim());
                //最后将StringBuilder清空掉
                id.setLength(0);
                name.setLength(0);
                version.setLength(0);
        }
        @override
        public void endDocument throws SAXException{
        }
    }
  1. 我们首先给id、name和version分别定义了一个StringBuilder对象,并在startDocument()方法里对它们进行了初始化。每当开始解析某个结点时,startElement()方法就会得到调用,其中localName参数记录着当前结点的名字,这里我们记录下来。
  2. 接着在解析结点中的具体内容的时候就会调用characters()方法,我们会根据当前的结点名进行判断,将解析出的内容添加到哪一个StringBuilder对象中。
  3. 最后在endElement()方法中进行判断,如果app已经解析完成,就会打印出来所有的内容。
  4. 需要注意的是,目前id、name和version中都可能是包括回车或者换行符的,因此在打印之前调用一下trim()方法,并且打印完后还要清空StringBuilder.

在接收到服务器返回的程序中调用

    parseXMLWithSAX(response);



    private void parseXMLWithSAX(String xmlData){
        try{
            SAXParserFactory factory=SAXParserFactory.newInstance();
            XMLReader xmlReader=factory.newSAXParser().getXMLReader();
            ContentHandler handler = new ContentHandler();
            //将ContentHandler的实例设置到XMLReader中
            xmlReader.setContentHandler(handler);
            //开始执行解析
            xmlReader.parse(new InputSource(new StringReader(xmlData)));
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

在得到了服务器的返回数据后,我们这次调用parseXMLWithSAX()方法来解析XML数据。parseXMLWithSAX()方法中先是创建了一个SAXParserFactory的对象,然后再获取到XMLReader对象,接着将我们编写的ContentHandler的实例设置到XMLReader中,最后调用parse()方法开始执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值