解析Xml格式数据
一.搭建一个最简单的web服务器,在这个服务器上提供一段xml文本,然后我们在程序中去访问这个服务器,再对得到的XML文本进行解析。
下载一个Apache服务器的安装包,安装后打开服务,可以打开电脑的浏览器来验证一下,在地址栏输入127.0.0.1,如果出现如下图所示,就说明服务器已经启动成功了。
接下来到你安装Apache目录下的Apache\htdocs目录下,在这里新建一个名为get_data.xml的文件,然后编辑这个文件,并加入XML格式的内容:
<apps>
<app>
<id>1</id>
<name>Google Maps</name>
<version>1.0</version>
</app>
<app>
<id>2</id>
<name>Chome</name>
<version>2.1</version>
</app>
<app>
<id>3</id>
<name>Google Play</name>
<version>2.3</version>
</app>
</apps>
在浏览器中访问就会出现如图所示:
好了,准备工作已经结束,接下来就让我们在Android程序里去获取这段XML数据吧。
### Pull解析方式: ###
解析xml格式的数据其实也有很多方式,本节中我们学习比较常用的两种,Pull解析和SAX解析。那么简单起见,这里仍然在NetworkTest项目中的基础上继续开发,这样我们就可以重用之前网络通信部分的代码,从而把工作的重心放在XML数据解析上。
既然XML格式的数据已经提供好了,现在要做的就是从中解析出我们想要得到的那部分内容。
修改MainActivity中的代码,如下所示:
```java
package net.nyist.lenovo.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.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendRequest = (Button) findViewById(R.id.send_request);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId()==R.id.send_request){
//sendRequestWithHttpURLConnection();
sendRequestWithOkHttp();
}
}
private void sendRequestWithOkHttp() {
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
//指定访问的服务器地址是电脑本机
.url("http://10.0.2.2/get_data.xml")
.build();
try {
Response response = client.newCall(request).execute();
String responseData = response.body().string();
parseXMLWithPull(responseData);
//showResponse(responseData);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private void parseXMLWithPull(String xmlData) {
try {
//首先获取一个XmlPullParserFactory的实例,主要调用其静态方法newInstance()得到。
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//然后利用XmlPullParserFactory的实例,调用newPullParser()方法,得到XmlPullParser对象。
XmlPullParser xmlPullParser = factory.newPullParser();
//然后调用XmlPullParser的setInput()方法将服务器返回的XML数据设置进去就可以开始解析了。
// 注意:这里的StringReader类是Reader类的子类。
//public class StringReaderextends ReaderAspecialized Reader that reads characters from a String in a sequential manner.
xmlPullParser.setInput(new StringReader(xmlData));
//具体解析的时候,首先通过XmlPullParser类的getEventType()方法得到当前的解析事件。
int eventType = xmlPullParser.getEventType();
String id = "";
String name = "";
String version = "";
//然后在一个while循环中不断地进行解析,
// 如果当前的解析事件不等于XmlPullParser.END_DOCUMENT,
// 说明解析工作还没完成,调用XmlPullParser的next()方法可以获取下一个解析事件。
while(eventType != XmlPullParser.END_DOCUMENT){
String nodeName = xmlPullParser.getName();
switch (eventType){
//开始解析某个节点
/*
* 在while循环中,通过XmlPullParser类的getName()方法得到当前结点的名字,
* 如果发现结点名等于id,name,或version,
* 就调用nextText()方法来获取结点内具体的内容
* ,每当解析完一个app结点后就将获取到的内容打印出来。
* */
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();
}
}
private void sendRequestWithHttpURLConnection() {
//开启线程来发起网络请求
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL("https://www.baidu.com");
connection =(HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
//下面对获取到的输入流进行读取
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine())!=null){
response.append(line);
}
showResponse(response.toString());
} catch (Exception e) {
e.printStackTrace();
}finally {
if (reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection!=null){
connection.disconnect();
}
}
}
}).start();
}
private void showResponse(final String response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//在这里进行UI操作,将结果显示到界面上
responseText.setText(response);
}
});
}
}