準備工作:首先開啓wamp server,然後在wamp/www目錄下新建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://127.0.0.1/get_data.xml來獲取這個文件的內容了:
接下來看看怎麼用PULL方法將XML文件解析,然後得到我們想要的數據:
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);
}
default:
break;
}
eventType = xmlPullParser.next();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
代碼不難理解:首先獲取XmlPullParse的實例,然後從先到後分析XML的標籤,如果是開始標籤,就查看是否是id、name或者是version,如果是就保存當前的值(三個是接着保存的,因爲從XML可知它們是連在一起的);如果是結束標籤,就把當前保存的id、name和version輸出。
最後的效果:
2、SAX解析方式
SAX解析方式比Pull方式要複雜一些,但是在語義方面會更加清楚。下面新建類ContentHandler,繼承DefaultHandler:
public class ContentHandler extends DefaultHandler{
private String nodeName;
private StringBuilder id;
private StringBuilder name;
private StringBuilder version;
// 在獲取節點內容的時候調用
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
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);
}
super.characters(ch, start, length);
}
// 完成整個XML解析的時候調用
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
// 完成解析某個節點的時候調用
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("apps".equals(localName)) {
// 由於characters()方法可能被調用多次,一些換行符也會被當作內容解析出來,所以需要進行處理
Log.d("ContentHandler", id.toString().trim());
Log.d("ContentHandler", name.toString().trim());
Log.d("ContentHandler", version.toString().trim());
// 最後還要清空StringBuilder
id.setLength(0);
name.setLength(0);
version.setLength(0);
}
super.endElement(uri, localName, qName);
}
// 開始XML解析的時候調用
@Override
public void startDocument() throws SAXException {
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
super.startDocument();
}
// 在開始解析某個節點的時候調用
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// 記錄當前結點名
nodeName = localName;
super.startElement(uri, localName, qName, attributes);
}
}
然後在MainActivity中調用它:
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();
}
}
實現效果:
還有一種解析方式:DOM解析,這裏暫時不展開講了。