首页 > 代码库 > Android中通过SAX方式解析XML

Android中通过SAX方式解析XML

    每个访问网络的应用程序都有一个自己的服务器,我们可以向服务器提交数据,也可以从服务器上获取数据。那么,这些数据是用什么格式在网络上传输的呢?一般,我们会在网络上传输一些格式化的数据,这些数据有一定的结构和语义。另一方收到数据消息后就可以按照相同的结构规格来进行解析,从而获取到想要的那部分内容。

  网络上传输数据最常用的格式有两种,XML和JSON。下面,我们介绍通过SAX方式来解析XML。

  首先,进行准备一段XML格式的数据。 get_data.xml

 1 <apps>     2     <app> 3         <id></id> 4         <name>Google Maps</name> 5         <version>1.0</version> 6     </app> 7     <app> 8         <id>2</id> 9         <name>Chrome</name>10         <version>2.1</version>11     </app>12     <app>13         <id>3</id>14         <name>Google Play</name>15         <version>2.3</version>16     </app>17 </apps>

   我们搭建的服务器网址为:http://10.0.105.36/get_data.xml

   接下来通过HttpURLConnection方式来获取服务器上的内容,代码如下

private void sendRequestWithHttpURLConnection(){        //开启线程来发送网络请求        new Thread(new Runnable() {            @Override            public void run() {                HttpURLConnection connection=null;                try {                    URL url=new URL("http://10.0.105.36/get_data.xml");                    connection= (HttpURLConnection) url.openConnection();                    connection.setRequestMethod("GET");                    connection.setConnectTimeout(8000);                    connection.setReadTimeout(8000);                    //获取输入流                    InputStream in=connection.getInputStream();                    //对获取到的流进行读取                    BufferedReader br=new BufferedReader(new InputStreamReader(in));                    StringBuilder response=new StringBuilder();                    String line;                    while ((line=br.readLine())!=null){                        response.append(line);                    }                      parseXMLWithSAX(response.toString()); //这里调用的是下文中parseXMLWithSAX()方法                }catch (Exception e){                    e.printStackTrace();                }finally {                    if (connection!=null){                        connection.disconnect();                    }                }            }        }).start();    }

 

 

    一般情况我们会新建一个类ContentHandler继承自DefaultHandler ,并重写父类的五个方法 ,如下:

  

package com.example.NetTest21;import android.util.Log;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;/** * Created by Demon on 2015/1/18. */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 {        //根据当前的节点名判断将内容添加到哪一个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("ContentHandler","id is "+id.toString().trim());            Log.d("ContentHandler","name is "+name.toString().trim());            Log.d("ContentHandler","version is "+version.toString().trim());            //最后将StringBuilder清空            id.setLength(0);            name.setLength(0);            version.setLength(0);        }    }    @Override    public void endDocument() throws SAXException {    }}

 

    我们首先给id、name和version节点分别定义了一个StringBuilder对象,并在startDocument()方法中对它们进行了初始化。每当开始解析某个节点的时候,startElement()方法就会得到调用。其中localName参数记录着当前结点的名字,我们将它记录下来。接着在解析结点中具体内容的时候就会调用characters()方法,我们根据当前的结点名进行判断,将解析出的内容添加到哪一个StringBuilder对象中。最后在endElement()方法中进行判断,如果app结点已经解析完成,就打印出id name  和version的内容。注意,目前id、name和version中可能包括回车或换行符,因此在打印之前我们还需要调用一下trim()方法,并且打印完成后还要将StringBuilder的内容清空掉,不然会影响下一次内容的读取。

    接下来新建一个parseXMLWithSAX(String xmlData)方法 用来解析数据。

 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()方法中先是创建了一个SAXParseFactory的对象,然后再获取到XMLReader对象,接着将我们编写的ContentHandler的实例设置到XMLReader中,最后调用parse()方法开始执行解析。

 

 ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------

 

  文章来自于郭霖大神的《第一行代码》,转载请注明出处。

Android中通过SAX方式解析XML