在网上传输数据时最常用的格式有两种:XML和JSON。
1.解析XML格式
有两种解析方法:Pull和SAX
需要解析的XML格式的内容如下:
<apps> <app> <id>1</id> <name>Google Maps</name> <version>1.0</version> </app> <app> <id>21</id> <name>Google</name> <version>2.11.0</version> </app> <app> <id>3</id> <name>Maps</name> <version>2.3</version> </app> </apps> Pull解析方式:
public class MainActivity extends ActionBarActivity { private Button btn; private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); tv = (TextView) findViewById(R.id.tv); tv.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { sendRequestWithHttpClient(); } }); } private void sendRequestWithHttpClient(){ new Thread(new Runnable() { @Override public void run() { try { HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet("http://127.0.0.1/get_data.xml"); HttpResponse httpResponse = httpClient.execute(httpGet); if(httpResponse.getStatusLine().getStatusCode() == 200){ HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity,"utf-8"); parseXMLWithPull(response); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } private void parseXMLWithPull(String response) { try { XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser xmlPullParser = factory.newPullParser(); xmlPullParser.setInput(new StringReader(response)); //将服务器返回的XML文件设置进去就可以进行解析了 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("MainActivity","id is "+ id); Log.d("MainActivity","name is "+ name); Log.d("MainActivity","id is "+ version); } break; } default: break; } eventType = xmlPullParser.next(); } } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }解读代码:
首先获得一个XmlPullParserFactory的实例,通过这个实例获得XmlPullParser对象,然后调用XmlPullParser的setInput()方法将服务器返回的XML数据设置进去就可以解析了。通过getEventType()可以得到当前的解析事件,然后在一个while循环中不断解析,如果当前的解析事件不等于XmlPullParser.END_DOCUMENT,说明解析还未完成,调用next()方法可以获得下一个解析事件。
SAX解析: 通常会新建一个类继承自DeaultHandler,并重写父类的5个方法,如下:
public class MyHandler extends DefaultHandler { // 此方法会在开始XML解析的时候调用 @Override public void startDocument() throws SAXException { super.startDocument(); } // 此方法会在开始解析某个节点的时候调用 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); } // 此方法会在获取节点内容的时候调用 @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); } // 解析完某个节点调用 @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); } // 完成整个XML解析时调用 @Override public void endDocument() throws SAXException { super.endDocument(); } }其中startElement()、characters()、endElement()这三个方法是有参数的,从XML中解析出来的数据会以参数的形式传入这些方法中。 public class MyHandler extends DefaultHandler { private String nodeName; private StringBuilder id; private StringBuilder name; private StringBuilder version; // 此方法会在开始XML解析的时候调用 @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(nodeName,start,length); }else if(version.equals(nodeName)){ version.append(nodeName,start,length); } } // 解析完某个节点调用 @Override public void endElement(String uri, String localName, String qName) throws SAXException { if("app".equals(localName)){ Log.d("MyHandler","id is"+id.toString().trim()); Log.d("MyHandler","name is"+name.toString().trim()); Log.d("MyHandler","version is"+version.toString().trim()); // 最后将StringBuilder清空掉 id.setLength(0); name.setLength(0); version.setLength(0); } } // 完成整个XML解析时调用 @Override public void endDocument() throws SAXException { super.endDocument(); } } MainActivity中的代码: public class MainActivity extends ActionBarActivity { private Button btn; private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); tv = (TextView) findViewById(R.id.tv); tv.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { sendRequestWithHttpClient(); } }); } private void sendRequestWithHttpClient(){ new Thread(new Runnable() { @Override public void run() { try { HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet("http://127.0.0.1/get_data.xml"); HttpResponse httpResponse = httpClient.execute(httpGet); if(httpResponse.getStatusLine().getStatusCode() == 200){ HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity,"utf-8"); parseXMLWithSAX(response); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } private void parseXMLWithSAX(String response) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); XMLReader xmlReader= factory.newSAXParser().getXMLReader(); MyHandler myHandler = new MyHandler(); // 将MyHandler的实例设置到XMLReader中 xmlReader.setContentHandler(myHandler); // 开始执行 xmlReader.parse(new InputSource(new StringReader(response))); } catch (SAXException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }