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()方法开始执行解析。
---------------------------------------------------------------------------
---------------------------------------------------------------------------
文章来自于郭霖大神的《第一行代码》,转载请注明出处。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。