数码庄园的网站建设公司,人工智能培训心得体会,metro风格网站开发,wordpress ppt插件XmlResourceParser继承了2个接口#xff1a;AttributeSet和XmlPullParser。其中XmlPullParser定义了Android SAX框架。跟Java 的SAX API相比#xff0c;XmlPullParser令人难以置信地简单。 一、使用XmlResourceParser读取资源束中的xml 资源束是应用程序编译后的应用程序包… 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或者SchemaEclipse会提示一个警告不用理会它。 现在我们需要用 XmlResourceParser 来读取xml文件并转换为KVPkey value pairs对象。 新建一个类 KVPsFromXml public class KVPsFromXml { private Context ctx ; public KVPsFromXml(Context c) { ctx c; } public MapString, String TqqkFromXml(String filename) { MapString, String map new HashMapString, 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 keyxml.getAttributeValue( null , name ); String valuexml.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 MapString, String TqqkFromXml(InputStream in,String encode){ MapString, String map new HashMapString, 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 keyxpp.getAttributeValue( null , name ); String valuexpp.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 VectorMapObject,Object getAttributeSet(String name){ VectorMapObject,Object vector new VectorMapObject,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 asXml.asAttributeSet (parser); int nas.getAttributeCount(); MapObject,Object map new HashMapObject,Object(); while (n0){ 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 ); VectorMapObject,Object attrsxml.getAttributeSet( tqqk ); for (MapObject,Object as : attrs){ Log.i ( map ,as.toString()); } 当然Map 距离 Object 已经不远了要将Map映射为对象只需要使用java的反射机制。 转载于:https://www.cnblogs.com/encounter/archive/2011/05/23/2188489.html