- 浏览: 28795 次
- 性别:
- 来自: 北京
最新评论
-
xiaojianhx:
Environment 是哪个包里面的?我开发4.0,用不了这 ...
Android 检测SD卡应用 -
qianlei541:
不错不错不错
android软键盘enter键的替换与事件监听 -
ihopethatwell:
到处都是转载的,楼主,你这个图片这个调用能贴上?
android yuv摄像 -
mikite:
mark,看看
Android中的动画研究 -
anyang763:
多谢lz分享,学习了!
android系统调用
Android SAX API: XmlResourceParser及其扩展应用
分类: Android 2011-05-23 15:16 253人阅读 评论(0) 收藏 举报
XmlResourceParser继承了2个接口:AttributeSet和XmlPullParser。其中XmlPullParser定义了Android SAX框架。跟Java 的SAX API相比,XmlPullParser令人难以置信地简单。
一、使用XmlResourceParser读取资源束中的xml
资源束是应用程序编译后的应用程序包的别称。如果我们有一个xml文件是放在应用程序包内并随编译后的包一起发布的,那么使用XmlResourceParser读取xml非常简单。
首先在res目录下新建目录xml。在xml目录中新建xml文件,例如tqqk.xml:
<? xml version = "1.0" encoding = "utf-8" ?>
< tqqk >
< item name = " 晴 " id = "78" />
< item name = " 多云 " id = "80" />
< item name = " 阴 " id = "79" />
< item name = " 小(阵)雨 " id = "4" />
< item name = " 中雨 " id = "5" />
< item name = " 大雨 " id = "802" />
< item name = " 大到暴雨 " id = "7" />
< item name = " 雷阵雨 " id = "181" />
< item name = " 雨夹雪 " id = "84" />
< item name = " 小雪 " id = "10" />
< item name = " 中雪 " id = "11" />
< item name = " 大到暴雪 " id = "83" />
< item name = " 冰雹 " id = "13" />
< item name = " 雾 " id = "14" />
< item name = " 多云转晴 " id = "85" />
< item name = " 阴湿 " id = "182" />
< item name = " 闷热 " id = "202" />
</ tqqk >
这是一个天气情况列表,每个item元素有两个属性:name和id。也就是说我们给每种天气定义一个名字和id。
由于我们的这个xml文档中并没有定义DTD或者Schema,Eclipse会提示一个警告,不用理会它。
现在我们需要用 XmlResourceParser 来读取xml文件并转换为KVP(key value pairs)对象。
新建一个类 KVPsFromXml:
public class KVPsFromXml {
private Context ctx ;
public KVPsFromXml(Context c) {
ctx = c;
}
public Map<String, String> TqqkFromXml(String filename) {
Map<String, String> map = new HashMap<String, String>();
// 获得处理 android 。 xml 文件的 XmlResourceParser 对象
XmlResourceParser xml = ctx .getResources().getXml(
getResIDFromXmlFile(filename));
try {
// 切换到下一个状态,并获得当前状态的类型
int eventType = xml.next();
while ( true ) {
// 文档开始状态
if (eventType == XmlPullParser. START_DOCUMENT ) {
}
// 标签开始状态
else if (eventType == XmlPullParser. START_TAG ) {
// 将标签名称和当前标签的深度(根节点的 depth 是 1 ,第 2 层节点的 depth 是 2 ,类推)
switch (xml.getDepth()){
case 1:
break ;
case 2:
// 取 item 的 name 和 id 属性,并放入 map 中
String key=xml.getAttributeValue( null , "name" );
String value=xml.getAttributeValue( null , "id" );
map.put(key, value);
break ;
}
// 获得当前标签的属性个数
// int count = xml.getAttributeCount();
// 将所有属性的名称和属性值添加到 StringBuffer 对象中
// for (int i = 0; i < count; i++) {
// sb.append(xml.getAttributeName(i)
// + "xml.getAttributeValue(i)");
// }
}
// 标签结束状态
else if (eventType == XmlPullParser. END_TAG ) {
}
// 读取标签内容状态
else if (eventType == XmlPullParser. TEXT ) {
}
// 文档结束状态
else if (eventType == XmlPullParser. END_DOCUMENT ) {
// 文档分析结束后,退出 while 循环
break ;
}
// 切换到下一个状态,并获得当前状态的类型
eventType = xml.next();
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
public int getResIDFromXmlFile(String file) {
int ret = 0;
@SuppressWarnings ( "rawtypes" )
Class c = null ;
try {
c = Class.forName ( "ydtf.ydqx.R$xml" );
Field field = c.getDeclaredField(file);
if (field != null )
ret = field.getInt(c);
} catch (Exception ex) {
ex.printStackTrace();
}
return ret;
}
}
该类的构造函数需要传递一个Context参数,即把使用这个类的Activity引用传递给它。因为Activity有一个很便利的方法getResource可以访问并加载 R 对象中的类(资源)。由于 XmlPullParser接口定义了Android SAX的 XMLPULL V1 API ( 请参考http://www.xmlpull.org ) ,我们可以使用SAX解析中的4个事件:
START_TAG,TEXT,END_TAG,END_DOCUMENT(这跟Java SAX中的4个事件是对应的)。因此在接下来的while循环中,我们针对4个事件进行了分别的处理,从而读取xml中的各个元素及其属性,并组装成KVP(键值对)放入Map中。
ctx .getResources().getXml().getResIDFromXmlFile()) 方法可以获得一个 XmlResourceParser 对象。但是 getResIDFromXmlFile 方法要求提供一个int型的资源id(即R.java中定义的各种16进制数)为参数。
由于res文件夹中的各种资源被映射入R.java的类及字段——具体说,res目录下的子目录映射为R.java中的内部类,子目录中的文件被映射为内部类的字段。因此,xml目录下的tqqk.xml会被映射为R.java中的xml类的tqqk字段。用java表述则是“包名.R.$xml.tqqk”。通过java.reflect包,我们可以得到这个xml文件的资源id。
接下来,我们在Activity中取得xml解析的结果--Map对象:
public void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout. ydqxlogin );
// read the xml file:tqqk.xml
KVPsFromXml xml= new KVPsFromXml( this );
tqqk_map =xml.TqqkFromXml( "tqqk" );
Log.i ( "tqqk_map" , tqqk_map + "" );
}
我们可以在LogCat中看到打印出来的结果:
{é ·ç =202, å¤§å °æ ´é ¨=7, é ´æ¹¿=182, å¤§å °æ ´é ª=83, å °é ¹=13, ä¸é ¨=5, é ·é µé ¨=181, ä¸é ª=11, é ¨å¤¹é ª=84, å¤§é ¨=802, é ´=79, é ¾=14, å¤ äº =80, å° é ª=10, æ ´=78, å° ï¼ é µï¼ é ¨=4, å¤ äº è½¬æ ´=85}
由于name使用了中文,所以出现了乱码。如果我们用adb logcat命令的话,则可以显示中文:
{大雨=802, 冰雹=13, 雷阵雨=181, 阴湿=182, 晴=78, 阴=79, 闷热=202, 多云=80, 雨夹雪=84, 小(阵)雨=4, 中雨=5, 小雪=10, 大到暴雨=7, 中雪=11, 雾=14, 多云转晴=85, 大到暴雪=83}
二、直接从资源束之外读取xml
有时候,xml并不总是随资源束一起编译,比如说从网络流中获取的xml。
那么我们可以直接使用XmlPullParser接口。
修改KVPsFromXml类的 TqqkFromXml 方法代码:
public Map<String, String> TqqkFromXml(InputStream in,String encode){
Map<String, String> map = new HashMap<String, String>();
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance ();
factory.setNamespaceAware( true );
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(in,encode);
// 切换到下一个状态,并获得当前状态的类型
int eventType = xpp.getEventType();
while ( true ) {
// 文档开始状态
if (eventType == XmlPullParser. START_DOCUMENT ) {
}
// 标签开始状态
else if (eventType == XmlPullParser. START_TAG ) {
// 将标签名称和当前标签的深度(根节点的 depth 是 1 ,第 2 层节点的 depth 是 2 ,类推)
switch (xpp.getDepth()){
case 1:
break ;
case 2:
// 取 item 的 name 和 id 属性,并放入 map 中
String key=xpp.getAttributeValue( null , "name" );
String value=xpp.getAttributeValue( null , "id" );
map.put(key, value);
break ;
}
// 获得当前标签的属性个数
// int count = xml.getAttributeCount();
// 将所有属性的名称和属性值添加到 StringBuffer 对象中
// for (int i = 0; i < count; i++) {
// sb.append(xml.getAttributeName(i)
// + "xml.getAttributeValue(i)");
// }
}
// 标签结束状态
else if (eventType == XmlPullParser. END_TAG ) {
}
// 读取标签内容状态
else if (eventType == XmlPullParser. TEXT ) {
}
// 文档结束状态
else if (eventType == XmlPullParser. END_DOCUMENT ) {
// 文档分析结束后,退出 while 循环
break ;
}
// 切换到下一个状态,并获得当前状态的类型
eventType = xpp.next();
}
} catch (Exception e){
e.printStackTrace();
}
return map;
}
修改Activity调用代码:
String sXml = "<tqqk>" + "<item name=/" 晴 /" id=/"78/"/>"
+ "<item name=/" 多云 /" id=/"80/"/>"
+ "<item name=/" 阴 /" id=/"79/"/>"
+ "<item name=/" 小(阵)雨 /" id=/"4/"/>"
+ "<item name=/" 中雨 /" id=/"5/"/>"
+ "<item name=/" 大雨 /" id=/"802/"/>"
+ "<item name=/" 大到暴雨 /" id=/"7/"/>"
+ "<item name=/" 雷阵雨 /" id=/"181/"/>"
+ "<item name=/" 雨夹雪 /" id=/"84/"/>"
+ "<item name=/" 小雪 /" id=/"10/"/>"
+ "<item name=/" 中雪 /" id=/"11/"/>"
+ "<item name=/" 大到暴雪 /" id=/"83/"/>"
+ "<item name=/" 冰雹 /" id=/"13/"/>"
+ "<item name=/" 雾 /" id=/"14/"/>"
+ "<item name=/" 多云转晴 /" id=/"85/"/>"
+ "<item name=/" 阴湿 /" id=/"182/"/>"
+ "<item name=/" 闷热 /" id=/"202/"/>" + "</tqqk>" ;
ByteArrayInputStream stream = new ByteArrayInputStream(sXml.getBytes());
KVPsFromXml xml = new KVPsFromXml( this );
tqqk_map = xml.TqqkFromXml(stream, null );
Log.i ( "tqqk_map" , tqqk_map + "" );
现在我们构建了一个字符流传递给 TqqkFromXml 方法(第二个参数字符编码设定为null,因为java内部字符编码未发生任何改变),它仍然可以为我们读取xml的内容:
{大雨=802, 冰雹=13, 雷阵雨=181, 阴湿=182, 晴=78, 阴=79, 闷热=202, 多云=80, 雨夹雪=84, 小(阵)雨=4, 中雨=5, 小雪=10, 大到暴雨=7, 中雪=11, 雾=14, 多云转晴=85, 大到暴雪=83}
当然,这里我偷了个懒,没有使用网络流读取xml,但结果不会有任何区别。
三、AttributeSet
XmlResourceParser还继承了AttributeSet接口。一个AttributeSet接口对象代表了一个Xml元素,它可以把该元素的所有属性用统一的方法进行访问。正如以下代码所示:
public Vector<Map<Object,Object>> getAttributeSet(String name){
Vector<Map<Object,Object>> vector= new Vector<Map<Object,Object>>();
// 获得处理 android 。 xml 文件的 XmlResourceParser 对象
XmlResourceParser parser = ctx .getResources().getXml(
getResIDFromXmlFile(name));
int state = 0;
do {
// AttributeSet as;
try {
state = parser.next();
if (state == XmlPullParser. START_TAG && parser.getName().equals( "item" )) {
AttributeSet as=Xml.asAttributeSet (parser);
int n=as.getAttributeCount();
Map<Object,Object> map= new HashMap<Object,Object>();
while (n>0){
n--;
map.put(as.getAttributeName(n),as.getAttributeValue(n));
}
if (map!= null ) vector.add(map);
}
} catch (XmlPullParserException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
} while (state != XmlPullParser. END_DOCUMENT );
return vector;
}
如你所见,AttributeSet接口实际上是一个抽象的对象,它并没有定义实例变量或字段,它只定义了一系列的访问Xml元素属性的方法,因此我们无法直接保存AttributeSet对象到集合中。最终我们把它复制到 Map 对象并放入集合中(因为我们的xml文件中有多个元素)。
接下来我们打印这些xml元素:
KVPsFromXml xml = new KVPsFromXml( this );
Vector<Map<Object,Object>> attrs=xml.getAttributeSet( "tqqk" );
for (Map<Object,Object> as : attrs){
Log.i ( "map" ,as.toString());
}
当然,Map 距离 Object 已经不远了,要将Map映射为对象只需要使用java的反射机制。
发表评论
-
android 的 Linkify
2011-12-29 09:03 1198Linkify是一个辅助类,通过RegEx样式匹配,自动地在T ... -
Android教程之AndroidManifest.xml文件详介绍及解析
2011-12-21 16:58 0一、关于AndroidManifest.xml Android ... -
obj文件应用
2011-12-20 09:27 0OBJ文件格式(转http://www.ategpu.com/ ... -
Android 应用程序多Activity跳转之后退出整个程序
2011-12-13 11:48 891http://txlong-onz.iteye.com/blo ... -
Android 检测SD卡应用
2011-12-13 10:21 7117if (Environment.getExternalStor ... -
android yuv摄像
2011-12-13 09:26 2936http://eyehere.net/2011/android ... -
Android拍摄视频流的格式转换(YUV --- RGB)
2011-12-13 08:56 1887Android允许用户实时捕获摄像头的视频流,这在利用摄像头的 ... -
android软键盘enter键的替换与事件监听
2011-12-12 09:03 3545软件盘的界面替换只有一个属性android:imeOption ... -
android listView
2011-12-06 09:11 0一、 1 listview中在设置了背景之后,会发生listv ... -
Android 即时通讯 XMPP
2011-12-05 09:47 0http://www.cnblogs.com/charley_ ... -
搭建XMPP协议,实现自主推送消息到手机
2011-12-05 09:46 0http://www.devdiv.com/article-2 ... -
xmpp协议实现消息推送
2011-12-05 09:43 0http://www.cnblogs.com/luxiaofe ... -
Android推送方式比较
2011-12-05 09:32 0http://blog.csdn.net/xyz_lmn/ar ... -
Android教程之AndroidManifest.xml文件详介绍及解析
2011-12-02 09:25 0Android教程之AndroidManifest.xml文 ... -
Android用GSon处理Json数据
2011-12-02 08:57 4http://www.cnblogs.com/VinC/arc ... -
Android访问WCF服务---服务端开发
2011-12-02 08:45 0Android访问WCF服务(上篇)-服务端开发 本章目的: ... -
高效率下载图片——防止内存溢出
2011-12-01 12:06 0在应用中经常需要下载很多的图片,因此,写好图片下载部分的代码非 ... -
ScrollListener
2011-12-01 12:00 0new OnScrollListener() { bo ... -
Android虚拟机(DVM)内存分配——内存溢出问题
2011-12-01 11:57 0大家都知道Android的上层应用是基于 Dalvik Vir ... -
bitmap溢出处理
2011-12-01 11:40 0当从SD卡中获取图片时,如果图片太大,加载会出现溢出异常。因此 ...
相关推荐
在Android开发中,有三种主要的XML解析方法:SAX(Simple API for XML)、DOM(Document Object Model)和Pull解析。 3. SAX解析: - SAX是一种事件驱动的解析器,它逐行读取XML文档,遇到元素、属性等时触发相应...
本文将深入探讨如何在Android环境中使用SAX(Simple API for XML)解析XML文件。SAX是一种事件驱动的解析器,它在读取XML文档时触发一系列事件,开发者可以注册事件处理器来处理这些事件,从而实现对XML数据的高效、...
下面是一个SAX解析XML的示例(有点长,因为详细注解了SAX事件处理的所有方法),SAX API中主要有四种处理事件的接口,它们分别是ContentHandler,DTDHandler, EntityResolver 和 ErrorHandler 。下面的例子可能...
在Android开发中,XML(可扩展标记语言)是一种常见的数据交换格式,用于存储和传输结构化数据。SAX(Simple API for XML)是处理XML的一种事件驱动的解析方法,它以流式的方式逐行读取XML文档,适用于处理大型XML...
本篇将详细讲解Android中三种主要的XML解析方式:SAX(Simple API for XML)、DOM(Document Object Model)和Pull解析器,并通过案例来帮助理解它们的工作原理和应用场景。 ### 1. SAX解析器 SAX(Simple API for...
在提供的压缩包文件中,可能包含了一个名为`MenuDemo1`的示例,展示了如何在Android应用中创建XML菜单,以及一个名为`SAXMake`的示例,演示了使用SAX生成XML文件的具体实现。通过研究这些示例,开发者可以更好地理解...
综上所述,"android_sax_xml.zip"提供的示例旨在展示如何在Android环境中使用SAX解析XML,这对于理解XML解析的底层机制和优化移动应用的性能至关重要。通过学习和实践这个示例,开发者可以更好地处理服务器返回的XML...
SAX(Simple API for XML)是一种事件驱动的解析器,它在读取XML文档时触发一系列事件,如开始元素、结束元素、字符数据等。开发者通过实现SAX解析器的回调接口,来处理这些事件,从而解析XML。这种方式非常适用于...
通过以上步骤,开发者可以在Android应用中有效地利用SAX解析器处理网络获取的XML数据,提高应用性能并降低内存消耗。理解SAX的工作原理和使用方式对于进行高效的XML数据处理至关重要。在实际项目中,可以根据需求...
在Android开发中,XML(可扩展标记语言)是一种常见的数据交换格式,用于存储和传输结构化数据。SAX(Simple API for XML)是处理XML的一种事件驱动模型,它以流式方式读取XML文档,适合处理大型XML文件,因为它不...
SAX(Simple API for XML)是一种事件驱动的解析方式,它允许开发者逐个处理XML文档的元素,而不是一次性加载整个文档到内存中,因此对于大体积的XML文件,SAX解析具有高效、节省内存的优点。而Pull解析器是Android...
SAX(Simple API for XML)解析器是一种事件驱动的XML解析方式,它以流式处理XML文档,对内存占用较少,特别适合处理大体积的XML文件。与DOM(Document Object Model)解析不同,DOM会将整个XML文档加载到内存中形成...
SAX(Simple API for XML)是XML解析器的一种,它采用事件驱动的方式处理XML文档,非常适合处理大型XML文件,因为它不会一次性加载整个文档到内存中,从而节省了资源。本篇将详细讲解如何在Android环境中使用SAX解析...
本文将深入探讨如何在Android平台上利用SAX(Simple API for XML)解析器来读取和写入XML数据,以及如何利用XML进行后台交互。 SAX是一种事件驱动的XML解析方式,与DOM(Document Object Model)不同,它不需要一次...
Android特有的Pull解析器类似于SAX,也是事件驱动的,但API设计更简洁,易于使用。它提供了一种向前读取的模型,开发者通过调用next()方法获取下一个事件,直到解析完成。Pull解析器适合移动设备,因为它节省内存且...
SAX(Simple API for XML)是XML解析器的一种,它采用事件驱动模型,以流式的方式处理XML文档,对内存的占用较小,适合处理大型XML文件。本示例"android sax解析xml模板源码"提供了一个使用SAX解析XML的实例,方便...
SAX(Simple API for XML)是一种轻量级、事件驱动的XML解析器,适用于处理大型XML文档。相较于DOM解析,SAX解析器不会一次性加载整个XML文档到内存,而是逐行读取,因此更节省内存资源,适合于内存有限的移动设备。...
本篇文章将详细探讨Android中的SAX(Simple API for XML)解析方式,并提供一个简单的SAX XML解析Demo。 SAX解析是基于事件驱动的解析模型,它不会一次性加载整个XML文档到内存,而是逐行读取,当遇到特定的XML元素...
本篇文章将深入探讨三种在Android中解析XML的方法:DOM(文档对象模型)、Pull(拉取解析器)和SAX(简单API for XML),并且会特别强调如何识别文件编码。 首先,DOM解析是将整个XML文件加载到内存中形成一个树形...
在处理大型或复杂数据时,为了提高性能和节省内存,我们通常选择SAX(Simple API for XML)解析器,而不是DOM(Document Object Model)解析器。SAX是基于事件驱动的解析方式,它逐行读取XML文件,只在需要时处理...