一、前言
首先我们先搭建一个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解析一样的效果~~解析成功!