Android SAX API: XmlResourceParser及其扩展应用
2011-05-23 15:16
330 查看
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的反射机制。
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 SAX API: XmlResourceParser及其扩展应用
- Android SAX API: XmlResourceParser及其扩展应用
- Android用XmlResourceParser读取XML资源
- Android XmlPullParser的简单应用
- android 使用XmlResourceParser 解析XML
- android 使用XmlResourceParser 解析XML
- Android XmlResourceParser出错解决办法
- android- FileProvider崩溃 - NPE试图调用一个空字符串XmlResourceParser(FileProvider crash - npe attempting to invoke XmlResourceParser on a null String)
- android XmlPullParser的简单应用
- android中代码混淆android.content.res.XmlResourceParser extends or implements program class org.
- Android解析XML应用(一) XmlPullParser工具解析
- Android XmlResourceParser解析Xm文件实例
- Android - XmlPullParser的简单应用
- android开发之XmlResourceParser
- android.content.res.XmlResourceParser错误
- android 使用XmlResourceParser 解析XML
- 新浪微博混淆打包报错java.lang.NoSuchMethodError: android.util.Xml.newPullParser
- Android Toolbar头部及其扩展
- Android应用清单文件:AndroidManifest.xml
- python解释器实现及其嵌入式应用:内部模块定义及扩展