Android学习--解析XML数据格式
在网络上传输数据时最常用的格式有两种:XML和JSON,首先学习如何解析XML格式的数据。
首先搭建一个apache服务器,确认工作正常。在Apache的htdocs目录下,新建一个get_data.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>
在浏览器中验证 http://10.39.131.104/get_data.xml 可以访问 (IP依据实际情况而定)
1、Pull解析方式
布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/send_request" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Send Request"/> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/response_text" android:layout_width="match_parent" android:layout_height="wrap_content" /> </ScrollView> </LinearLayout>
主MainActivity中
package com.example.networktest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONObject;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
TextView responseText;
Response response;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button sendRequest = (Button) findViewById(R.id.send_request);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendRequestWithOkHttp();
}
});
}
private void sendRequestWithOkHttp(){
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://10.39.131.104/get_data.xml")
.build();
response = client.newCall(request).execute();
String responseData = response.body().string();
Log.d("MainActivity", "--responseData--"+responseData);
parseXMLWithPull(responseData);
// parseXMLWithSAX(responseData);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private void parseXMLWithPull(String xmlData){
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser()
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("MainActivity", "id is "+id);
Log.d("MainActivity", "name is "+name);
Log.d("MainActivity", "version is "+version);
}
break;
}
default:
break;
}
eventType = xmlPullParser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行效果图(点击button)
2、SAX解析
需要新建一个类继承DefaultHandler,并重写父类5个方法
ContentHandler 类
package com.example.networktest; import android.util.Log; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; 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 { super.endDocument(); } }
在MainActivity中修改代码
public class MainActivity extends AppCompatActivity { ...... private void sendRequestWithOkHttp(){ new Thread(new Runnable() { @Override public void run() { try { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("http://10.39.131.104/get_data.xml") .build(); response = client.newCall(request).execute(); String responseData = response.body().string(); Log.d("MainActivity", "--responseData--"+responseData); // parseXMLWithPull(responseData); parseXMLWithSAX(responseData); } catch (IOException e) { e.printStackTrace(); } } }).start(); } 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(); } } }
运行效果