今天讲讲关于Xml的解析问题,在安卓上面,可以使用java.xml.parsers。这里面有关于xml的解析的类。
至于这么解析,首先先上一段代码:
HttpDownloader httpDownloader = new HttpDownloader();
String xmlString = httpDownloader.download("http://192.168.2.100:8080/sourse/data.xml");
Log.e("juetion", xmlString);
//创建一个SXAParserFactory
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
try {
//
XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();
//为XMLReader设置内容处理器
xmlReader.setContentHandler(new MyXMLContentHandler());
//开始解析文件
xmlReader.parse(new InputSource(new StringReader(xmlString)));
} catch (Exception e) {
e.printStackTrace();
}
代码里面的HttpDownLoader这个类,请参考: android-关于下载网络资源以及写入到SD卡中 这里里面的代码。简单来说就是把网络上的Xml下载放在String里面。
SAXParserFactory是创建一个SAX的一个解析工厂。
XMLReader,如其名,就是用于读取XML文件的类。
重点是:xml.setContentHandler这个方法,里面的参数是ContentHandler类。这个下面会讲到。
xmlReader.parse这个方法就是开始解析某一个xml。
-----------我是可爱的分割线--------------------
话说回来,重点是在ContentHandler这个类。这个类是用于在处理解析时所触发的。有点像触发器。
一般的写法是继承DefaultHandler这个类。里面有很多方法:
如:1、startDocument 这个方法是在开始解析时触发的。
2、endDocument 这个方法是结束解析时触发的。
3、startElement 这个防范是开始解析某一元素时触发的
等等,很多。就不多说了。
我们需要关注的如何解析。所以我这里就直接附上代码,里面有注释
package org.juetion.xml.util;
import android.util.Log;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Created by juetionke on 13-12-23.
*/
public class MyXMLContentHandler extends DefaultHandler {
private String tagName;
private StringBuffer id,name,sex,address,grade;
public MyXMLContentHandler() {
//因为DefaultHandler.characters继承后,这个函数不是自信一次就获取标签内的内容的,所以需要用StringBuffer来拼接。
id = new StringBuffer();
name = new StringBuffer();
sex = new StringBuffer();
address = new StringBuffer();
grade = new StringBuffer();
}
@Override
public void startDocument() throws SAXException {
Log.i("juetion","----------startDocument----------");
}
@Override
public void endDocument() throws SAXException {
Log.i("juetion","----------endDocument----------");
}
/**
* localName是没有前缀的,qName是包括前缀的
* @param uri
* @param localName
* @param qName
* @param attributes
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
Log.i("juetion","----------startElement----------");
tagName = localName;
if (localName.equals("student")) {
for (int i = 0; i < attributes.getLength(); i++) {
Log.i("juetion",attributes.getLocalName(i) + "=" + attributes.getValue(i));
if (attributes.getLocalName(i).equals("id")){
//获取标签内的属性
id = id.append(attributes.getValue(i));
}
}
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
Log.i("juetion","----------endElement----------");
if (localName.equals("student")) {
Log.i("juetion", "id:"+id+" name:" + name + " sex:" + sex + " address:" + address + " grade:" + grade);
//拼接完了需要置空,这里直接new一个新对象,因为Java是垃圾处理机制,所以就不去用同一个对象然后再删除数据。
id = new StringBuffer();
name = new StringBuffer();
sex = new StringBuffer();
address = new StringBuffer();
grade = new StringBuffer();
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
Log.i("juetion","----------characters----------");
String str = new String(ch, start, length);
//判断是否为空内容,如果是空内容,则不要拼接
if (str.trim().equals("") )
return ;
if (tagName.equals("name")) {
name = name.append(str);
}else if (tagName.equals("sex")) {
sex = sex.append(str);
}else if (tagName.equals("address")) {
address = address.append(str);
}else if (tagName.equals("grade")) {
grade = grade.append(str);
}
}
}
这段代码解析的XML文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="A001">
<name>张三</name>
<sex>男</sex>
<address>广州A区</address>
<grade>A班</grade>
</student>
<student id="B001">
<name>李四</name>
<sex>男</sex>
<address>广州B区</address>
<grade>B班</grade>
</student>
<student id="C001">
<name>王五</name>
<sex>女</sex>
<address>广州C区</address>
<grade>C班</grade>
</student>
</students>
我们这里重点讲以下的是:characters(char[] ch, int start, int length)这个方法。
它解析的是标签里面的内容。不是属性哦。属性的解析是在startElement这个方法里面。
characters(char[] ch, int start, int length)这个方法有点奇葩,因为它的ch本来是获取内容的。但是不知道为何,它获取并不是一次性全部内容获取的。而是会分断开的,所以这个方法会被调用多次的。如上面的<address>广州A区</address>,可能会分两次调用这个方法,第一次的ch为:广州,第二次的ch为:A区。也有可能分三次。这也就是为什么上面会用到StringBuffer这个类。因为我们需要拼接。
附上代码下载:http://download.youkuaiyun.com/detail/juetion/6763281
今月今日的android学习回顾到此结束了。谢谢观看。