Adroid开发之解析xml数据的两种方式
前言在android开发中,从服务器拿到的xml数据存在两种解析方式:
接下来我们来一一说一下具体用法。 1.Pull解析方式代码如下: @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.send_req:
sendRequestWithHttpClient();
break;
default:
break;
}
}
// The code that request is Success
private static final int REQUEST_SUCCESS = 200;
// Encoding format
private static final String UTF_8 = "UTF-8";
/** * HttpClient * * The HttpClient was supported by Apache * */
private void sendRequestWithHttpClient() {
new Thread(new Runnable() {
@Override
public void run() {
// this is a GET request
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() == REQUEST_SUCCESS) {
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity,UTF_8);
// Parse xml data by Pull method
parseXMLWithPull(response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
/** * parse XML data by Pull method * * @param xmlData */
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) {
// Begin to parse a tag
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;
// When we parsed a tag,print the infos
case XmlPullParser.END_TAG:
if ("app".equals(nodeName)) {
Log.d("Info","id is " + id);
Log.d("Info","name is " + name);
Log.d("Info","version is " + version);
}
break;
default:
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
这里首先要获取到一个XmlPullParserFactory 的 实 例 , 并 借 助 这 个 实 例 得 到 XmlPullParser 对 象 , 然 后 调 用 打印结果: 2.SAX解析方式除了Pull方式来解析外,我们还可以用SAX方式来解析,用法上比Pull方式稍微复杂一些,但是语义方面更加清晰。 这里说明一下上面几个方法的用处:
其中,startElement()、characters()和 endElement()这三个方法是有参数的,从 XML 中解析出的数据就会以参数的形式传入到这些方法中。需要注意的是,在获取结点中的内容时,characters()方法可能会被调用多次,一些换行符也被当作内容解析出来,我们需要针对这种情况在代码中做好控制。 接下来,我们来看看具体应用代码: import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
/** * 解析xml * */
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 endDocument() throws SAXException {}
@Override
public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException {
// 记录当前节点名
nodeName = localName;
}
@Override
public void endElement(String uri,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 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,length);
} else if ("version".equals(nodeName)) {
version.append(ch,length);
}
}
}
我们在startDocument()中初始化相关StringBuilder对象,接下来每当开始解析某个结点的时候,startElement()方法就会得到调用,其中 localName 参数记录着当前结点的名字,这里我们把它记录下来。接着在解析结点中具体内容的时候就会调用 characters()方法,我们会根据当前的结点名进行判断,将解析出的内容添加到哪一个 StringBuilder 对象中。最后在 endElement()方法中进行判断,如果 app 结点已经解析完成,就打印出 id、name 和 version 的内容。需要注意的是,目前 id、name 和 version 中都可能是包括回车或换行符的,因此在打印之前我们还需要调用一下 trim()方法,并且打印完成后还要将 StringBuilder 的内容清空掉,不然的话会影响下一次内容的读取。 修改MainActivity.java中的代码: /** * HttpClient * * The HttpClient was supported by Apache * */
private void sendRequestWithHttpClient() {
new Thread(new Runnable() {
@Override
public void run() {
// this is a GET request
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() == REQUEST_SUCCESS) {
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity,UTF_8);
// Parse xml data by SAX method
parseXMLWithSAX(response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
/** * pares XML data by SAX method * * @param xmlData */
private void parseXMLWithSAX(String xmlData) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader reader = factory.newSAXParser().getXMLReader();
ContentHandler handler = new ContentHandler();
// 将contentHandler实例设置到reader中
reader.setContentHandler(handler);
// 开始解析
reader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
e.printStackTrace();
}
}
附
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |