前言
本文主要介绍在android中怎样来解析xml文件。主要采用的是sax机制,sax全称为simple api for xml,它既是一种接口,也是一个软件包。作为接口,sax是事件驱动型xml解析的一个标准接口。xml文件解析一般有2种方法,dom和sax。其中dom需要先将xml文档全部读入到电脑内存中,当文档内容太大时,该方法并不适用。sax就比较好的解决了该问题,它是逐行解析的,可以随时中断。但是sax的操作比较复杂。因此,这2种方法各有优缺点,看具体应用情况。在前面的文章qt学习之路_12(简易数据管理系统)中使用的是qt中的dom方法。
实验说明
大多数sax实现都会产生类似下面的事件:
在文档的开始和结束处触发文档处理事件;在文档内每一xml元素结束解析的前后触发元素事件;任何元数据通常豆油单独的事件交付;在处理文档的dtd或者schema时产生dtd 或者schema事件;产生错误事件用来通知主机应用程序解析错误。
sax模型示意图如下所示:
如果要用sax来解析xml文档,则需要一个类来继承android系统提供的contenthandler类。但是如果继承contenthandler这个类, 即使你不使用这个类提供的所有方法,你也必须实现其内部的所有方法(一般情况下没有使用的方法可以直接用空方法代替),但是这样开发起来不是很方便。因此我们可以改为继承defaulthandler这个类,这样的话我们只需要实现程序中所需要的方法即可,其它的方法这个类内部其实已经用空方法代替了。
contenthandler接口的方法有以下几种:
void startdocument();//文档解析开始时执行
void enddocument();//文档解析结束时执行
void startelement(string uri, string localname, string qname, attributes atts);//标签开始解析时执行
void endelement(string uri, string localname, string qname, attributes atts);//标签解析结束时执行
void characters(char[] ch, int start, int length );//解析标签属性时执行
android中使用sax来解析xml文件,需先建立一个sax工厂,即saxparserfactory对象,还需建立一个xmlreader对象,该类绑定contenthandler子类,且与xml源文件结合在一起。即其处理过程为创建事件处理程序,创建sax解析器,键事件处理程序分配给解析器,对文档进行解析,将每个事件发送给处理程序。
判断string类型的值是否相等采用的是string类的equal方法。
本实验是解析一段xml代码,然后在上面每个解析函数中打印一些内容。主要是学会怎么使用sax模型来来创建解析器,怎样使用contenthandler子类的函数来进行解析。
实验主要部分代码:
mainactivity.java:
package com.example.xml;
import java.io.stringreader;
import javax.xml.parsers.saxparserfactory;
import org.xml.sax.inputsource;
import org.xml.sax.xmlreader;
import android.app.activity;
import android.os.bundle;
import android.view.menu;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.textview;
public class mainactivity extends activity {
private button start = null;
private textview display = null;
@override
public void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
start = (button)findviewbyid(r.id.start);
start.setonclicklistener(new startonclicklistener());
}
public class startonclicklistener implements onclicklistener{
public void onclick(view v) {
// todo auto-generated method stub
//注意2点,第1:字符串中如果要换行写,则应该用引号和加号来相加得到,不能直接换行写
//第2点:如果字符串中有字符,则用括号里面的符合(\")代替引号。
//我这里用的xml文件直接为该程序layout的布局xml文件
// string result_str =
// "<relativelayout " +
// " xmlns:tools=\"http://schemas.android.com/tools\" " +
// " android:layout_width=\"match_parent\" " +
// " android:layout_height=\"match_parent\" > " +
//
// " <button " +
// " android:id=\"@+id/start\" " +
// " android:layout_width=\"fill_parent\" " +
// " android:layout_height=\"wrap_content\" " +
// " android:layout_alignparentbottom=\"true\" " +
// " android:text=\"start xml parse\" " +
// " /> " +
// " <textview " +
// " android:id=\"@+id/display\" " +
// " android:layout_width=\"fill_parent\" " +
// " android:layout_height=\"fill_parent\" " +
// " android:gravity=\"center\" " +
// " android:layout_alignparentleft=\"true\" " +
// " android:layout_above=\"@+id/start\" " +
// " android:text=\"the xml parse example!!\" " +
// " /> " +
// " </relativelayout>";
string result_str =
" <button " +
" id=\"@+id/start\" " +
" layoutwidth=\"fillparent\" " +
" layoutheight=\"wrapcontent\" " +
" layoutalignparentbottom=\"true\" " +
" text=\"start xml parse\" " +
" </button> " ;
system.out.println(result_str);
try{
//创建sax工厂
saxparserfactory factory = saxparserfactory.newinstance();
xmlreader reader = factory.newsaxparser().getxmlreader();
reader.setcontenthandler(new mycontenthandler());
reader.parse(new inputsource(new stringreader(result_str)));
}
catch(exception e) {
e.printstacktrace();
}
}
}
@override
public boolean oncreateoptionsmenu(menu menu) {
getmenuinflater().inflate(r.menu.activity_main, menu);
return true;
}
}
mycontenthandler.java:
package com.example.xml;
import org.xml.sax.attributes;
import org.xml.sax.saxexception;
import org.xml.sax.helpers.defaulthandler;
public class mycontenthandler extends defaulthandler {
string tagname, sid, swidth, sheight, text, salign;
//当解析到标签的属性栏时调用该方法
@override
public void characters(char[] ch, int start, int length)
throws saxexception {
// todo auto-generated method stub
if(tagname.equals("id"))
sid = new string(ch, start, length);
else if(tagname.equals("layoutwidth"))
swidth = new string(ch, start, length);
else if(tagname.equals("layoutheight"))
sheight = new string(ch, start, length);
else if(tagname.equals("layoutalignparentbottom"))
salign = new string(ch, start, length);
else if(tagname.equals("text"))
text = new string(ch, start, length);
super.characters(ch, start, length);
}
//解析文档结束调用
@override
public void enddocument() throws saxexception {
// todo auto-generated method stub
system.out.println("........end.......");
super.enddocument();
}
//解析标签结束时调用
@override
public void endelement(string uri, string localname, string qname)
throws saxexception {
// todo auto-generated method stub
if(tagname.equals("button")) {
this.printout();
}
super.endelement(uri, localname, qname);
}
//解析文档开始时调用
@override
public void startdocument() throws saxexception {
// todo auto-generated method stub
system.out.println("........begin.......");
super.startdocument();
}
//标签开始时执行
@override
public void startelement(string uri, string localname, string qname,
attributes attributes) throws saxexception {
// todo auto-generated method stub
tagname = localname;
if(tagname.equals("button")) {
for(int i = 0; i < attributes.getlength(); i++) {
//得到第i个属性的名字和值
system.out.println(attributes.getlocalname(i) + "=" + attributes.getvalue(i));
}
}
super.startelement(uri, localname, qname, attributes);
}
//输出标签属性解析结果
private void printout() {
system.out.print("id: ");
system.out.println(sid);
system.out.print("layout_width: ");
system.out.println(swidth);
system.out.print("layout_height: ");
system.out.println(sheight);
system.out.print("layout_alignparentbottom: ");
system.out.println(salign);
system.out.print("text: ");
system.out.println(text);
}
}