一、前言
首先我們先搭建一個web服務器,我這裏用的是tomcat,搭建過程可參見tomacat服務器的搭建:http://blog.csdn.net/qq_28585471/article/details/77449526。然後在這個服務器下提供一段XML文本,然後,我們在這個程序裏去訪問這個服務器,再對得到的XML文本進行解析。
文本內容爲:
我們可以在網頁中輸入地址預覽一下:
預覽成功說明tomcat成功連接,且文本設置正確。
二、 PULL解析
我們在OkHttp的項目上進行修改,佈局文件不用變,修改MainActivity.java就可以
public class MainActivity extends AppCompatActivity {
Button sendRequest;
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest = (Button) findViewById(send_request);
sendRequest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try{
OkHttpClient client = new OkHttpClient();
//將HTTP請求的地址改爲http://10.0.2.2:8080/zwj/zwj.xml
//模擬器是連接不到localhost的,10.0.2.2對於模擬器來說就是電腦本機的IP地址
Request request = new Request.Builder().url("http://10.0.2.2:8080/zwj/zwj.xml").build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
//得到服務器返回的數據後,調用parseXMLWithPull()方法解析服務器返回的數據
parseXMLWithPull(responseData);
}catch (Exception e){
e.printStackTrace();
}
}
}).start();
}
});
}
private void parseXMLWithPull(String xmlData) {
try{
//首先獲取一個XmlPullParserFactory實例
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//藉助這個XmlPullParserFactory實例得到XmlPullParser對象
XmlPullParser xmlPullParser = factory.newPullParser();
//調用XmlPullParser的setInput()方法將服務器返回的XML數據設置進去
xmlPullParser.setInput(new StringReader(xmlData));
//開始解析
//通過getEventType得到當前的解析事件
int eventType = xmlPullParser.getEventType();
String id = "";
String name = "";
String version = "";
//在一個while循環中不斷地進行解析
//如果當前的解析事件不等於XmlPullParser.END_DOCUMENT,說明解析工作還未完成,調用next()方法後獲取下一個解析事件
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();
}
}
看一下打印的日誌:
解析成功啦~
那就再看一下SAX解析吧!
三、SAX解析
1、首先新建個ContentHandler類繼承自DefaultHandler,並重寫父類的5個方法
public class ContentHandler extends DefaultHandler {
private String nodeName;
private StringBuilder id;
private StringBuilder name;
private StringBuilder version;
/**
* 在開始XML解析的時候調用
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
}
/**
* 在開始解析某個節點的時候調用
* @param uri
* @param localName
* @param qName
* @param attributes
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//記錄當前節點名
nodeName = localName;
}
/**
* 在獲取節點內容的時候調用
* @param ch
* @param start
* @param length
* @throws SAXException
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//根據當前的節點名判斷內容添加到哪一個StringBulider對象中
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);
}
}
/**
* 在完成解析某個節點的時候調用
* @param uri
* @param localName
* @param qName
* @throws SAXException
*/
@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);
}
}
/**
* 在完成整個XML解析的時候調用
* @throws SAXException
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
}
這裏我們首先給id,name,version節點分別定義了一個StringBuilder對象,並在startDocument()方法裏對它們進行了初始化;每當開始解析某個節點的時候,startElement()方法就會得到調用,其中localName參數記錄着當前節點的名字。接着在解析節點中具體內容的時候就會調用character()方法,然後我們根據當前節點名進行判斷、將解析出的內容添加到哪一個StringBuilder對象中。最後在endElement()方法中進行判斷,如果app節點已經解析完成,就打印出id,name,version的內容。打印完成後,要將StringBuilder的內容清空掉。
2、修改MainActivity.java
public class MainActivity extends AppCompatActivity {
Button sendRequest;
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest = (Button) findViewById(R.id.send_request);
sendRequest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
try{
OkHttpClient client = new OkHttpClient();
//將HTTP請求的地址改爲http://10.0.2.2:8080/zwj/zwj.xml
//模擬器是連接不到localhost的,10.0.2.2對於模擬器來說就是電腦本機的IP地址
Request request = new Request.Builder().url("http://10.0.2.2:8080/zwj/zwj.xml").build();
Response response = client.newCall(request).execute();
String responseData = response.body().string();
//得到服務器返回的數據後,調用parseXMLWithPull()方法解析服務器返回的數據
parseXMLWithSAX(responseData);
}catch (Exception 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();
}
}
}
我們調用parseXMLWithSAX()方法來解析XML數據,首先創建一個SAXParserFactory對象,然後再獲取到XMLReader對象,接着將ContentHandler實例設置到XMLReader中,最後調用parse()方法開始執行解析。
3、看一下logcat中的日誌
和PULL解析一樣的效果~~解析成功!