http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E7%89%9B/24821.shtml
一、简述
xml语言是跨平台开发,java对xml语言支持得比较好,android系统开发的应用开发层平台是java做的,所以用xml。
xml解析比较简单。xml解析就是将获取到的数据分离出来,基本的网络数据传输,需要使用xml
比如天气预报,从网上获取的是xml文件,通过xml解析可以把天气状态读出来
例:
1 <forecast_date data="2009-07-31" />
2 <condition data="晴" />
3 <humidity data="湿度: 65%" />(xml文件不全)
可得到 2009-07-31 晴 湿度:65%
还有一作用是保存你的数据,比如做个旅游网站,你需要把全国各个省、城市名称写到xml文件进行保存,在程序中通过解析读取调用。
android 平台上可用的xml解析有三种
1、simple api for xml(sax)
2、document object model(dom)
3、android附带的pull解析器
二、实例
分别用三种开发方法 解析如下persons.xml文件(文件放在assert目录下)
1 <?xml version="1.0" encoding="utf-8"?>
2 <persons>
3 <person id="23">
4 <name>liming</name>
5 <age>30</age>
6 </person>
7 <person id="20">
8 <name>dehua</name>
9 <age>25</age>
10 </person>
11 </persons>
还需定义个javabean 用于存放解析出来的内容
1 package com.example.xml;
2
3 public class person {
4 private integer id;
5 private string name;
6 private short age;
7
8 public integer getid() {
9 return id;
10 }
11
12 public void setid(integer id) {
13 this.id = id;
14 }
15
16 public string getname() {
17 return name;
18 }
19
20 public void setname(string name) {
21 this.name = name;
22 }
23
24 public short getage() {
25 return age;
26 }
27
28 public void setage(short age) {
29 this.age = age;
30 }
31
32 // @override
33 // public string tostring() {
34 // return "id:" + id + ", name:" + name + ", age:" + age;
35 // }
36 }
1、simple api for xml(sax)
sax是一个解析速度快并且占用内存少的xml解析器,很适合用于android等移动开发其他 设备。
sax解析xml文件采用的是事件驱动开发 ,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的开发过程 中,
sax会判断当前读到的字符是否合法xml语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)开发方法 ,
这些开发方法 (事件)定义在contenthandler接口。
直接看代码:
1 public class xmlcontenthandler extends defaulthandler {
2 private list<person> persons = null;
3 private person currentperson;
4 private string tagname = null;// 当前解析的元素标签
5 private static final string tag = "xmlcontenthandler";
6
7 public list<person> getpersons() {
8 return persons;
9 }
10
11 /*
12 * 接收文档的开始的通知。
13 */
14
15 @override
16 public void startdocument() throws saxexception {
17 persons = new arraylist<person>();
18 log.i(tag, "startdocument");
19 }
20
21 /*
22 * 结束文档的开始的通知。
23 */
24
25 @override
26 public void enddocument() throws saxexception {
27 super.enddocument();
28 log.i(tag, "enddocument");
29 }
30
31 /*
32 * 接收字符数据的通知。
33 */
34
35 @override
36 public void characters(char[] ch, int start, int length)
37 throws saxexception {
38 if (tagname != null) {
39 string data = new string(ch, start, length);
40 if (tagname.equals("name")) {
41 this.currentperson.setname(data);
42 } else if (tagname.equals("age")) {
43 this.currentperson.setage(short.parseshort(data));
44 }
45 }
46 log.i(tag, "characters("+ch.tostring()+","+start+","+length+")");
47
48 }
49
50 /*
51 *
52 * 接收元素开始的通知。
53 * 参数意义如下:
54 * namespaceuri:元素的命名空间
55 * localname :元素的本地名称(不带前缀)
56 * qname :元素的限定名(带前缀)
57 * atts :元素的属性集合
58 */
59
60 @override
61 public void startelement(string namespaceuri, string localname,
62 string qname, attributes atts) throws saxexception {
63
64 if (localname.equals("person")) {
65 currentperson = new person();
66 currentperson.setid(integer.parseint(atts.getvalue("id")));
67 }
68
69 this.tagname = localname;
70 log.i(tag, "startelement("+namespaceuri+","+localname+","+qname+atts+")");
71
72 }
73
74 /*
75 * 接收文档的结尾的通知。
76 * 参数意义如下:
77 * uri :元素的命名空间
78 * localname :元素的本地名称(不带前缀)
79 * name :元素的限定名(带前缀)
80 */
81 @override
82 public void endelement(string uri, string localname, string name)
83 throws saxexception {
84
85 if (localname.equals("person")) {
86 persons.add(currentperson);
87 currentperson = null;
88 }
89
90 this.tagname = null;
91 log.i(tag, "endelement("+uri+","+localname+","+name+")");
92
93 }
94 }
2、document object model(dom)
dom解析xml文件时,会将xml文件的所有内容读取到内存中,然后允许您使用dom api遍历xml树、检索所需的数据。
使用dom操作xml的代码看起来比较直观,并且,在某些方面比基于sax的实现更加简单。但是,因为dom需要将xml文件的所有内容读取到内存中,
所以内存的消耗比较大,特别对于运行android的移
此文来自: 马开东博客 转载请注明出处 网址:http://www.makaidong.com
动设备来说,因为设备的资源比较宝贵,所以建议还是采用sax来解析xml文件,
当然,如果xml文件的内容比较小采用dom是可行的。
1 public class domparsexml {
2
3 public list<person> readxml(inputstream instream) {
4
5 list<person> persons = new arraylist<person>();
6
7 documentbuilderfactory factory = documentbuilderfactory.newinstance();// 获取实例
8
9 try {
10
11 documentbuilder builder = factory.newdocumentbuilder();
12 document dom = builder.parse(instream);
13 element root = dom.getdocumentelement();
14 nodelist items = root.getelementsbytagname("person");// 查找所有person节点
15
16 for (int i = 0; i < items.getlength(); i++) {
17
18 person person = new person();
19
20 // 得到第一个person节点
21 element personnode = (element) items.item(i);
22
23 // 获取person节点的id属性值
24 person.setid(new integer(personnode.getattribute("id")));
25
26 // 获取person节点下的所有子节点(标签之间的空白节点和name/age元素)
27 nodelist childsnodes = personnode.getchildnodes();
28
29 for (int j = 0; j < childsnodes.getlength(); j++) {
30
31 node node = (node) childsnodes.item(j); // 判断是否为元素类型
32 if (node.getnodetype() == node.element_node) {
33 element childnode = (element) node;
34
35 // 判断是否name元素
36 if ("name".equals(childnode.getnodename())) {
37
38 // 获取name元素下text节点,然后从text节点获取数据
39 person.setname(childnode.getfirstchild()
40 .getnodevalue());
41
42 } else if ("age".equals(childnode.getnodename())) {
43 person.setage(new short(childnode.getfirstchild()
44 .getnodevalue()));
45
46 }
47 }
48 }
49 persons.add(person);
50 }
51 instream.close();
52 } catch (exception e) {
53 e.printstacktrace();
54 }
55
56 return persons;
57
58 }
59 }
3、android附带的pull解析器
pull解析和sax解析很相似,都是轻量级的解析,在android的内核中已经嵌入开发 了pull,所以我们不需要再添加第三方jar包来支持pull。
pull解析和sax解析不一样的地方有(1)pull读取xml文件后触发相应的事件调用开发方法 返回的是数字(2)pull可以在程序中控制想解析到哪里就可以停止解析。
1 public class pullparsexml {
2
3 public list<person> readxml(inputstream instream) throws xmlpullparserexception, ioexception{
4
5 list<person> persons = null;
6 person person = null;
7 xmlpullparser parser = xml.newpullparser();
8 parser.setinput(instream, "utf-8");
9
10 int event = parser.geteventtype();//产生第一个事件
11 while(event!=xmlpullparser.end_document){
12 switch(event){
13 case xmlpullparser.start_document://判断当前事件是否是文档开始事件
14 persons = new arraylist<person>();//初始化persons集合
15 break;
16 case xmlpullparser.start_tag://判断当前事件是否是标签元素开始事件
17 if("person".equals(parser.getname())){//判断开始标签元素是否是person
18 person = new person();
19 person.setid(integer.parseint(parser.getattributevalue(0)));//得到person标签的属性值,并设置person的id
20 }
21 if(person!=null){
22 if("name".equals(parser.getname())){//判断开始标签元素是否是name
23 person.setname(parser.nexttext());
24 }else if("age".equals(parser.getname())){//判断开始标签元素是否是price
25 person.setage(short.parseshort(parser.nexttext()));
26 }
27 }
28 break;
29 case xmlpullparser.end_tag://判断当前事件是否是标签元素结束事件
30 if("person".equals(parser.getname())){//判断结束标签元素是否是person
31 persons.add(person);//将person添加到persons集合
32 person = null;
33 }
34 break;
35 }
36 event = parser.next();//进入下一个元素并触发相应事件
37 }//end while
38 return persons;
39
40 }
41 }
运行界面:

绑定按钮触发的事件代码:
1 @override
2 protected void oncreate(bundle savedinstancestate) {
3 super.oncreate(savedinstancestate);
4 setcontentview(r.layout.activity_main);
5 textview = (textview)findviewbyid(r.id.textview);
6 sax_prase = (button)findviewbyid(r.id.sax_prase);
7 dom_parse = (button)findviewbyid(r.id.dom_parse);
8 pull_parse = (button)findviewbyid(r.id.pull_parse);
9
10
11 try {
12 instream = getassets().open("persons.xml");
13 } catch (ioexception e) {
14 // todo auto-generated catch block
15 e.printstacktrace();
16 }
17
18 //绑定按钮监听器
19 sax_prase.setonclicklistener(new onclicklistener() {
20 @override
21 public void onclick(view v) {
22 persons = saxparsexml(instream);
23 for (person person : persons) {
24 log.i(tag, person.getid()+":"+person.getname()+":"+person.getage());
25 }
26 }
27 });
28 //绑定按钮监听器
29 dom_parse.setonclicklistener(new onclicklistener() {
30 @override
31 public void onclick(view v) {
32
33 domparsexml domparsexml = new domparsexml();
34 persons = domparsexml.readxml(instream);
35 for (person person : persons) {
36 log.i(tag, person.getid()+":"+person.getname()+":"+person.getage());
37 }
38 }
39 });
40 pull_parse.setonclicklistener(new onclicklistener() {
41 @override
42 public void onclick(view v) {
43
44 pullparsexml pullparsexml = new pullparsexml();
45 try {
46 persons = pullparsexml.readxml(instream);
47 } catch (xmlpullparserexception e) {
48 // todo auto-generated catch block
49 e.printstacktrace();
50 } catch (ioexception e) {
51 // todo auto-generated catch block
52 e.printstacktrace();
53 }
54 for (person person : persons) {
55 log.i(tag, person.getid()+":"+person.getname()+":"+person.getage());
56 }
57
58 }
59 });
60 }
61
62 private static list<person> saxparsexml(inputstream instream) {
63 // todo auto-generated method stub
64 try {
65 saxparserfactory spf = saxparserfactory.newinstance();
66 saxparser saxparser = spf.newsaxparser(); // 创建解析器
67
68 // 设置解析器的相关特性,http://xml.org/sax/features/namespaces = true
69 // 表示开启命名空间特性,缺省情况设为true,设置使代码更具可读性,但我加进去报错,索性注释掉
70 //saxparser.setproperty("http://xml.org/sax/features/namespaces",true);
71 xmlcontenthandler handler = new xmlcontenthandler();
72
73 saxparser.parse(instream, handler);
74 instream.close();
75
76 return handler.getpersons();
77
78 } catch (exception e) {
79
80 e.printstacktrace();
81
82 }
83
84 return null;
85 }
分别点击三个按钮用不同开发方法 解析出来的结果:

三、总结
对于三种解析xml开发方法 ,各有千秋,倾向于pull解析器,因为sax解析器操作起来太笨重,dom不适合文档较大,内存较小的场景,
唯有pull轻巧灵活,速度快,占用内存小,使用非常顺手,pull解析可以用于很多场合,例如接受google天气,rss新闻等。
| |
http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E7%89%9B/24821.shtml
一、简述
xml语言是跨平台开发,java对xml语言支持得比较好,android系统开发的应用开发层平台是java做的,所以用xml。
xml解析比较简单。xml解析就是将获取到的数据分离出来,基本的网络数据传输,需要使用xml
比如天气预报,从网上获取的是xml文件,通过xml解析可以把天气状态读出来
例:
1 <forecast_date data="2009-07-31" /> 2 <condition data="晴" /> 3 <humidity data="湿度: 65%" />(xml文件不全)
可得到 2009-07-31 晴 湿度:65%
还有一作用是保存你的数据,比如做个旅游网站,你需要把全国各个省、城市名称写到xml文件进行保存,在程序中通过解析读取调用。
android 平台上可用的xml解析有三种
1、simple api for xml(sax)
2、document object model(dom)
3、android附带的pull解析器
二、实例
分别用三种开发方法 解析如下persons.xml文件(文件放在assert目录下)
1 <?xml version="1.0" encoding="utf-8"?> 2 <persons> 3 <person id="23"> 4 <name>liming</name> 5 <age>30</age> 6 </person> 7 <person id="20"> 8 <name>dehua</name> 9 <age>25</age> 10 </person> 11 </persons>
还需定义个javabean 用于存放解析出来的内容
1 package com.example.xml; 2 3 public class person { 4 private integer id; 5 private string name; 6 private short age; 7 8 public integer getid() { 9 return id; 10 } 11 12 public void setid(integer id) { 13 this.id = id; 14 } 15 16 public string getname() { 17 return name; 18 } 19 20 public void setname(string name) { 21 this.name = name; 22 } 23 24 public short getage() { 25 return age; 26 } 27 28 public void setage(short age) { 29 this.age = age; 30 } 31 32 // @override 33 // public string tostring() { 34 // return "id:" + id + ", name:" + name + ", age:" + age; 35 // } 36 }
1、simple api for xml(sax)
sax是一个解析速度快并且占用内存少的xml解析器,很适合用于android等移动开发其他 设备。
sax解析xml文件采用的是事件驱动开发 ,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的开发过程 中,
sax会判断当前读到的字符是否合法xml语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)开发方法 ,
这些开发方法 (事件)定义在contenthandler接口。
直接看代码:
1 public class xmlcontenthandler extends defaulthandler { 2 private list<person> persons = null; 3 private person currentperson; 4 private string tagname = null;// 当前解析的元素标签 5 private static final string tag = "xmlcontenthandler"; 6 7 public list<person> getpersons() { 8 return persons; 9 } 10 11 /* 12 * 接收文档的开始的通知。 13 */ 14 15 @override 16 public void startdocument() throws saxexception { 17 persons = new arraylist<person>(); 18 log.i(tag, "startdocument"); 19 } 20 21 /* 22 * 结束文档的开始的通知。 23 */ 24 25 @override 26 public void enddocument() throws saxexception { 27 super.enddocument(); 28 log.i(tag, "enddocument"); 29 } 30 31 /* 32 * 接收字符数据的通知。 33 */ 34 35 @override 36 public void characters(char[] ch, int start, int length) 37 throws saxexception { 38 if (tagname != null) { 39 string data = new string(ch, start, length); 40 if (tagname.equals("name")) { 41 this.currentperson.setname(data); 42 } else if (tagname.equals("age")) { 43 this.currentperson.setage(short.parseshort(data)); 44 } 45 } 46 log.i(tag, "characters("+ch.tostring()+","+start+","+length+")"); 47 48 } 49 50 /* 51 * 52 * 接收元素开始的通知。 53 * 参数意义如下: 54 * namespaceuri:元素的命名空间 55 * localname :元素的本地名称(不带前缀) 56 * qname :元素的限定名(带前缀) 57 * atts :元素的属性集合 58 */ 59 60 @override 61 public void startelement(string namespaceuri, string localname, 62 string qname, attributes atts) throws saxexception { 63 64 if (localname.equals("person")) { 65 currentperson = new person(); 66 currentperson.setid(integer.parseint(atts.getvalue("id"))); 67 } 68 69 this.tagname = localname; 70 log.i(tag, "startelement("+namespaceuri+","+localname+","+qname+atts+")"); 71 72 } 73 74 /* 75 * 接收文档的结尾的通知。 76 * 参数意义如下: 77 * uri :元素的命名空间 78 * localname :元素的本地名称(不带前缀) 79 * name :元素的限定名(带前缀) 80 */ 81 @override 82 public void endelement(string uri, string localname, string name) 83 throws saxexception { 84 85 if (localname.equals("person")) { 86 persons.add(currentperson); 87 currentperson = null; 88 } 89 90 this.tagname = null; 91 log.i(tag, "endelement("+uri+","+localname+","+name+")"); 92 93 } 94 }
2、document object model(dom)
dom解析xml文件时,会将xml文件的所有内容读取到内存中,然后允许您使用dom api遍历xml树、检索所需的数据。
使用dom操作xml的代码看起来比较直观,并且,在某些方面比基于sax的实现更加简单。但是,因为dom需要将xml文件的所有内容读取到内存中,
所以内存的消耗比较大,特别对于运行android的移
此文来自: 马开东博客 转载请注明出处 网址:http://www.makaidong.com
动设备来说,因为设备的资源比较宝贵,所以建议还是采用sax来解析xml文件,当然,如果xml文件的内容比较小采用dom是可行的。
1 public class domparsexml { 2 3 public list<person> readxml(inputstream instream) { 4 5 list<person> persons = new arraylist<person>(); 6 7 documentbuilderfactory factory = documentbuilderfactory.newinstance();// 获取实例 8 9 try { 10 11 documentbuilder builder = factory.newdocumentbuilder(); 12 document dom = builder.parse(instream); 13 element root = dom.getdocumentelement(); 14 nodelist items = root.getelementsbytagname("person");// 查找所有person节点 15 16 for (int i = 0; i < items.getlength(); i++) { 17 18 person person = new person(); 19 20 // 得到第一个person节点 21 element personnode = (element) items.item(i); 22 23 // 获取person节点的id属性值 24 person.setid(new integer(personnode.getattribute("id"))); 25 26 // 获取person节点下的所有子节点(标签之间的空白节点和name/age元素) 27 nodelist childsnodes = personnode.getchildnodes(); 28 29 for (int j = 0; j < childsnodes.getlength(); j++) { 30 31 node node = (node) childsnodes.item(j); // 判断是否为元素类型 32 if (node.getnodetype() == node.element_node) { 33 element childnode = (element) node; 34 35 // 判断是否name元素 36 if ("name".equals(childnode.getnodename())) { 37 38 // 获取name元素下text节点,然后从text节点获取数据 39 person.setname(childnode.getfirstchild() 40 .getnodevalue()); 41 42 } else if ("age".equals(childnode.getnodename())) { 43 person.setage(new short(childnode.getfirstchild() 44 .getnodevalue())); 45 46 } 47 } 48 } 49 persons.add(person); 50 } 51 instream.close(); 52 } catch (exception e) { 53 e.printstacktrace(); 54 } 55 56 return persons; 57 58 } 59 }
3、android附带的pull解析器
pull解析和sax解析很相似,都是轻量级的解析,在android的内核中已经嵌入开发 了pull,所以我们不需要再添加第三方jar包来支持pull。
pull解析和sax解析不一样的地方有(1)pull读取xml文件后触发相应的事件调用开发方法 返回的是数字(2)pull可以在程序中控制想解析到哪里就可以停止解析。
1 public class pullparsexml { 2 3 public list<person> readxml(inputstream instream) throws xmlpullparserexception, ioexception{ 4 5 list<person> persons = null; 6 person person = null; 7 xmlpullparser parser = xml.newpullparser(); 8 parser.setinput(instream, "utf-8"); 9 10 int event = parser.geteventtype();//产生第一个事件 11 while(event!=xmlpullparser.end_document){ 12 switch(event){ 13 case xmlpullparser.start_document://判断当前事件是否是文档开始事件 14 persons = new arraylist<person>();//初始化persons集合 15 break; 16 case xmlpullparser.start_tag://判断当前事件是否是标签元素开始事件 17 if("person".equals(parser.getname())){//判断开始标签元素是否是person 18 person = new person(); 19 person.setid(integer.parseint(parser.getattributevalue(0)));//得到person标签的属性值,并设置person的id 20 } 21 if(person!=null){ 22 if("name".equals(parser.getname())){//判断开始标签元素是否是name 23 person.setname(parser.nexttext()); 24 }else if("age".equals(parser.getname())){//判断开始标签元素是否是price 25 person.setage(short.parseshort(parser.nexttext())); 26 } 27 } 28 break; 29 case xmlpullparser.end_tag://判断当前事件是否是标签元素结束事件 30 if("person".equals(parser.getname())){//判断结束标签元素是否是person 31 persons.add(person);//将person添加到persons集合 32 person = null; 33 } 34 break; 35 } 36 event = parser.next();//进入下一个元素并触发相应事件 37 }//end while 38 return persons; 39 40 } 41 }
运行界面:
绑定按钮触发的事件代码:
1 @override 2 protected void oncreate(bundle savedinstancestate) { 3 super.oncreate(savedinstancestate); 4 setcontentview(r.layout.activity_main); 5 textview = (textview)findviewbyid(r.id.textview); 6 sax_prase = (button)findviewbyid(r.id.sax_prase); 7 dom_parse = (button)findviewbyid(r.id.dom_parse); 8 pull_parse = (button)findviewbyid(r.id.pull_parse); 9 10 11 try { 12 instream = getassets().open("persons.xml"); 13 } catch (ioexception e) { 14 // todo auto-generated catch block 15 e.printstacktrace(); 16 } 17 18 //绑定按钮监听器 19 sax_prase.setonclicklistener(new onclicklistener() { 20 @override 21 public void onclick(view v) { 22 persons = saxparsexml(instream); 23 for (person person : persons) { 24 log.i(tag, person.getid()+":"+person.getname()+":"+person.getage()); 25 } 26 } 27 }); 28 //绑定按钮监听器 29 dom_parse.setonclicklistener(new onclicklistener() { 30 @override 31 public void onclick(view v) { 32 33 domparsexml domparsexml = new domparsexml(); 34 persons = domparsexml.readxml(instream); 35 for (person person : persons) { 36 log.i(tag, person.getid()+":"+person.getname()+":"+person.getage()); 37 } 38 } 39 }); 40 pull_parse.setonclicklistener(new onclicklistener() { 41 @override 42 public void onclick(view v) { 43 44 pullparsexml pullparsexml = new pullparsexml(); 45 try { 46 persons = pullparsexml.readxml(instream); 47 } catch (xmlpullparserexception e) { 48 // todo auto-generated catch block 49 e.printstacktrace(); 50 } catch (ioexception e) { 51 // todo auto-generated catch block 52 e.printstacktrace(); 53 } 54 for (person person : persons) { 55 log.i(tag, person.getid()+":"+person.getname()+":"+person.getage()); 56 } 57 58 } 59 }); 60 } 61 62 private static list<person> saxparsexml(inputstream instream) { 63 // todo auto-generated method stub 64 try { 65 saxparserfactory spf = saxparserfactory.newinstance(); 66 saxparser saxparser = spf.newsaxparser(); // 创建解析器 67 68 // 设置解析器的相关特性,http://xml.org/sax/features/namespaces = true 69 // 表示开启命名空间特性,缺省情况设为true,设置使代码更具可读性,但我加进去报错,索性注释掉 70 //saxparser.setproperty("http://xml.org/sax/features/namespaces",true); 71 xmlcontenthandler handler = new xmlcontenthandler(); 72 73 saxparser.parse(instream, handler); 74 instream.close(); 75 76 return handler.getpersons(); 77 78 } catch (exception e) { 79 80 e.printstacktrace(); 81 82 } 83 84 return null; 85 }
分别点击三个按钮用不同开发方法 解析出来的结果:
三、总结
对于三种解析xml开发方法 ,各有千秋,倾向于pull解析器,因为sax解析器操作起来太笨重,dom不适合文档较大,内存较小的场景,
唯有pull轻巧灵活,速度快,占用内存小,使用非常顺手,pull解析可以用于很多场合,例如接受google天气,rss新闻等。