本文实例讲述了使用sax来解析xml。通常来说在android里面可以使用sax和dom,dom需要把整个xml文件读入内存再解析,比较消耗内存,而sax是基于事件驱动的处理方式,可以在各节点触发回调函数,不过sax适合节点结构简单的xml文档,复杂的xml文档在后期的节点深度处理会有点麻烦。
本文要解析的test.xml文件如下:
1
2
3
4
5
6
7
8
|
<?xml version= "1.0" encoding= "utf-8" ?>
<test>
<title>testsax</title>
<content aa= "1" bb= "2" >
<name>hellogv</name>
<url>http: //blog.csdn.net/hellogv</url>
</content>
</test>
|
解析如上xml的结果如下图所示:
使用sax解析,需要定义saxparserfactory(使应用程序能够配置和获取基于 sax 的解析器以解析 xml 文档),saxparser(从各种输入源解析 xml),xmlreader(使用回调函数读取 xml 文档),其中xmlreader是个关键。xmlreader可以为解析xml定义各种回调函数,“条件符合”的时候触发这些回调函数。
1
2
3
4
5
6
|
saxparserfactory factory = saxparserfactory.newinstance();
saxparser parser = factory.newsaxparser();
xmlreader reader = parser.getxmlreader();
reader.setcontenthandler(handler);
reader.parse( new inputsource(testsax. this .getresources()
.openrawresource(r.raw.test)));
|
在这段代码里,xmlreader就调用继承defaulthandler的saxhandler。defaulthandler已实现contenthandler, dtdhandler, entityresolver, errorhandler等接口,包含常见读取xml的操作,具体请看下面的saxhandler.java源码。
最终生成xml的结果如下图所示:
上图是读取各节点之后,使用xmlserializer重新组合并输出xml字符串。
本文的main.xml代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
<?xml version= "1.0" encoding= "utf-8" ?>
<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android"
android:orientation= "vertical" android:layout_width= "fill_parent"
android:layout_height= "fill_parent" >
<button android:layout_height= "wrap_content"
android:layout_width= "fill_parent" android:id= "@+id/btnsax"
android:text= "使用sax解析xml" ></button>
<button android:layout_height= "wrap_content"
android:layout_width= "fill_parent" android:text= "生成xml" android:id= "@+id/btnoutput" ></button>
<edittext android:text= "@+id/edittext01" android:id= "@+id/edittext01"
android:layout_width= "fill_parent" android:layout_height= "fill_parent" ></edittext>
</linearlayout>
|
saxhandler.java的源码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
package com.testsax;
import java.util.arraylist;
import org.xml.sax.attributes;
import org.xml.sax.saxexception;
import org.xml.sax.helpers.defaulthandler;
import android.util.log;
public class saxhandler extends defaulthandler{
private arraylist<string> keys = new arraylist<string>(); //保存字段名称
private arraylist<object> values = new arraylist<object>(); //保存值
@override
public void startdocument() throws saxexception {
super .startdocument();
}
@override
public void enddocument() throws saxexception {
super .enddocument();
}
@override
public void startelement(string uri, string localname, string qname,
attributes attributes) throws saxexception {
//保存开始标记
keys.add( "starttag" );
values.add(localname);
log.e( "starttag" ,localname);
//保存属性值
for ( int i = 0 ; i < attributes.getlength(); i++ ){
keys.add( "attr" );
string[] str= new string[ 2 ];
str[ 0 ]=attributes.getlocalname(i);
str[ 1 ]=attributes.getvalue(i);
values.add(str);
log.e( "attr" ,str[ 0 ]+ "=" +str[ 1 ]);
}
}
@override
public void endelement(string uri, string localname, string qname)
throws saxexception {
//保存结束标记
keys.add( "endtag" );
values.add(localname);
log.e( "endtag" ,localname);
}
@override
public void characters( char [] ch, int start, int length)
throws saxexception {
string value = new string(ch, start, length);
value = value.trim();
if (value.length() == 0 )
return ;
keys.add( "text" );
values.add(value);
log.e( "text" ,value);
}
public arraylist<string> getkeys()
{
return keys;
}
public arraylist<object> getvalues()
{
return values;
}
}
|
testsax.java的源码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
package com.testsax;
import java.io.stringwriter;
import javax.xml.parsers.saxparser;
import javax.xml.parsers.saxparserfactory;
import org.xml.sax.inputsource;
import org.xml.sax.xmlreader;
import org.xmlpull.v1.xmlserializer;
import android.app.activity;
import android.os.bundle;
import android.util.xml;
import android.view.view;
import android.widget.button;
import android.widget.edittext;
public class testsax extends activity {
/** called when the activity is first created. */
button btnsax, btnoutput;
edittext memo;
saxhandler handler = new saxhandler();
@override
public void oncreate(bundle savedinstancestate) {
super .oncreate(savedinstancestate);
setcontentview(r.layout.main);
btnsax = (button) this .findviewbyid(r.id.btnsax);
btnsax.setonclicklistener( new clickevent());
btnoutput = (button) this .findviewbyid(r.id.btnoutput);
btnoutput.setonclicklistener( new clickevent());
memo = (edittext) this .findviewbyid(r.id.edittext01);
}
class clickevent implements view.onclicklistener {
@override
public void onclick(view v) {
if (v == btnsax) { //解析xml,并保存标记,属性等值
try {
saxparserfactory factory = saxparserfactory.newinstance();
saxparser parser = factory.newsaxparser();
xmlreader reader = parser.getxmlreader();
reader.setcontenthandler(handler);
reader.parse( new inputsource(testsax. this .getresources()
.openrawresource(r.raw.test)));
} catch (exception ee) {}
}
else if (v == btnoutput) { //生成xml
try {
xmlserializer serializer = xml.newserializer();
stringwriter writer = new stringwriter();
try {
serializer.setoutput(writer);
serializer.startdocument( "utf-8" , true );
for ( int i= 0 ;i<handler.getkeys().size();i++)
{
if (handler.getkeys().get(i).equals( "starttag" ))
{
serializer.starttag( "" , (string) handler.getvalues().get(i));
}
else if (handler.getkeys().get(i).equals( "attr" )){
string[] str= (string[]) handler.getvalues().get(i);
serializer.attribute( "" ,str[ 0 ],str[ 1 ]);
}
else if (handler.getkeys().get(i).equals( "text" ))
serializer.text((string)handler.getvalues().get(i));
else if (handler.getkeys().get(i).equals( "endtag" ))
{
serializer.endtag( "" , (string) handler.getvalues().get(i));
}
}
serializer.enddocument();
string text=writer.tostring();
text=text.replace( "><" , ">/r/n<" );
memo.settext(text); //输出到文本框
} catch (exception e) {
throw new runtimeexception(e);
}
} catch (exception e) {}
}
}
}
}
|
感兴趣的读者可以自己动手调试运行一下本实例代码,希望能对大家的android项目开发起到参考借鉴作用。