Android SAX解析xml文件.docx
《Android SAX解析xml文件.docx》由会员分享,可在线阅读,更多相关《Android SAX解析xml文件.docx(8页珍藏版)》请在冰豆网上搜索。
AndroidSAX解析xml文件
AndroidSAX解析xml文件
andorid读取xml文件内容方法有三种saxdompull,其中pull是android自带的
1.先认识一下xml文件中的些术语
Xml代码
xmlversion="1.0"encoding="UTF-8"?
>
李明
23
李量
25
xml中的标签和内容都可以叫做节点,其中的personspersonnameage这些都叫做元素(element).而像李明25这些值叫做文本节点.那么有个问题中到之间的是什么,什么都没有?
答案是他也是节点,是文本节点,你会说他里面什么都没有啊,错了,它有回车和空格.这个在sax解析xml中你debug一下就会发现.回车和空格(或者是tab)是会被读取出来的.id是属性.
2.sax
sax是采用事件驱动,就是说他不需要完全读完xml文件,他是读到一个节点就解析一个节点是否符合xml语法,如果符合就调用相对应的方法其实就是回调方法,并且没有记忆功能.下面提到的这些方法都是在ContentHander()接口中的方法.
startDocumnet():
当开始解析xml文件的声明的时候就会触发这个事件,可以做一些初始化的工作
startElement()当开始解析元素的开始标签的时候,就会触发这个事件
characters()当读到文本元素的时候要触发这个事件.
endElement()当读到结束标签的时候就会触发这个事件
sax就是这样按照顺序来解析的.
3.sax读取xml文件举例
3-1创建一个项目ReadXml
3-2将xml文件拷贝到根目录下.
Xml代码
xmlversion="1.0"encoding="UTF-8"?
>
李明
23
李量
25
可以看出这个xml文件中有一个可以抽象出来的对象就是person属性有idnameage
那么我们就建立一个bean
3-3:
创建bean
Java代码
packagecom.leequer.service.demo;
/**
*
李明
23
李量
25
*@authorleequer
*
*xml文件对应的bean
*/
publicclassPerson{
privateIntegerid;
privateStringname;
privateintage;
publicPerson()
{}
publicPerson(Stringname,intage)
{
this.name=name;
this.age=age;
}
publicIntegergetId(){
returnid;
}
publicvoidsetId(Integerid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
@Override
publicStringtoString(){
//TODOAuto-generatedmethodstub
returnthis.id+",name"+this.name+"age"+this.age+"\n";
}
}
3-4:
遵循mvc的架构,我们建立一个service用来读取xml
Java代码
packagecom.leequer.service;
importjava.io.InputStream;
importjava.util.List;
importjavax.xml.parsers.SAXParser;
importjavax.xml.parsers.SAXParserFactory;
importorg.xml.sax.XMLReader;
importcom.leequer.service.demo.Person;
publicclassSaxReadxml{
publicstaticListreadXml(InputStreaminStream)throwsException{
SAXParserFactoryspf=SAXParserFactory.newInstance();//初始化sax解析器
SAXParsersp=spf.newSAXParser();//创建sax解析器
//XMLReaderxr=sp.getXMLReader();//创建xml解析器
XMLContentHandlerhandler=newXMLContentHandler();
sp.parse(inStream,handler);
returnhandler.getPersons();
}
}
sp.parse(inStream,handler);
这句可以看出xml文件是以流的形式传进来的,参数handler就是回调函数的实例,当sax解析器解析xml文件的时候当遇到符合xml的内容就会去handle类中调用对应的上面提到的方法.那我们建立这个XMLContentHandler就要求这个类要实现ContentHandler()这个接口,但是这个接口中有很多需要实现的方法.sax提供了一个DefaultHandler接口只要实现这个接口中你感兴趣的方法就可以了.
3-5:
创建XMLContentHandler并完成读取时的事件的实现注意看注释
Java代码
packagecom.leequer.service;
importjava.util.ArrayList;
importjava.util.List;
importorg.xml.sax.Attributes;
importorg.xml.sax.SAXException;
importorg.xml.sax.helpers.DefaultHandler;
importcom.leequer.service.demo.Person;
publicclassXMLContentHandlerextendsDefaultHandler{
privateListpersons;
privatePersonperson;
privateStringtempString;
privatestaticfinalStringNAMESTRING="name";
privatestaticfinalStringAGESTRING="age";
privatestaticfinalStringPERSONSTRING="person";
privatestaticfinalStringIDSTRING="id";
publicListgetPersons(){
returnpersons;
}
/**
*sax解析文件不带记忆,只读取对xml文件中的李明23
*李量25这部分感兴趣
*那么这部分包含了person这个节点元素的开始和结尾,那么就要有startElement和endElement
*这两个方法;还有text的节点元素,(就是像节点之间的回车和空格还有标签中的像李明这样的文字都是文本节点元素
*(text节点元素)那么要解析文本节点元素就要用到characters这个方法来获取信息。
)
*/
/**
*要开始读取xml文件的时候调用的方法
*初始化persons
*/
@Override
publicvoidstartDocument()throwsSAXException{
//这里做list的初始化工作
persons=newArrayList();
}
/**
*sax读取到文本节点的时候调用了这个方法
*/
@Override
publicvoidcharacters(char[]ch,intstart,intlength)
throwsSAXException{
if(person!
=null){
StringvalueString=newString(ch,start,length);
if(NAMESTRING.equals(tempString)){
//如果当前解析到的节点是name就要将name中的文本节点元素的值得到
person.setName(valueString);
}elseif(AGESTRING.equals(tempString)){
person.setAge(newInteger(valueString).intValue());
}
}
}
/**
*sax读取到元素节点的时候用到这个方法;
*/
@Override
publicvoidstartElement(Stringuri,StringlocalName,Stringname,
Attributesattributes)throwsSAXException{
//先判断读到的元素是否是person
if(PERSONSTRING.equals(localName)){
//如果读到的是person这个元素就要保存起来,保存在我们创建的那个person的类中所以我们要new一个person类
person=newPerson();
//attributes是属性。
person.setId(newInteger(attributes.getValue(IDSTRING)));
}
tempString=localName;
}
/**
*这个方法是每次遇到结束的标签都会执行的并不是只遇到最后的结尾才调用
*
*读取完毕遇到person'的结尾就将封装好的一个personbean保存到list中并且清空person对象
*
*/
@Override
publicvoidendElement(Stringuri,StringlocalName,Stringname)
throwsSAXException{
if(PERSONSTRING.equals(localName)&&person!
=null)
{
persons.add(person);
person=null;
}
tempString=null;
}
}
3-6:
写个测试类来实验将xml文件装载入然后读取
packagecom.leequer.readxml;
/**
*测试类
*/
importjava.io.InputStream;
importjava.util.Iterator;
importjava.util.List;
importcom.leequer.service.SaxReadxml;
importcom.leequer.service.demo.Person;
importandroid.test.AndroidTestCase;
importandroid.util.Log;
publicclassSaxReadxmlTestextendsAndroidTestCase{
privateStringPERSONSTRING="ObjectPerson";
publicvoidtestReadXml()throwsException
{//类装载器
InputStreaminputStream=SaxReadxmlTest.class.getClassLoader().getResourceAsStream("NewFile.xml");
ListpersonsList=SaxReadxml.readXml(inputStream);
for(Iteratoriterator=personsList.iterator();iterator.hasNext();){
Personperson=(Person)iterator.next();
Log.i(PERSONSTRING,person.toString());
}
}
}