准备工作:首先开启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解析,这里暂时不展开讲了。