android中用xmlpullparser解析xml文件,以及res/raw和assets的不同
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android中用xmlpullparser解析xml文件,以及res/raw和assets的不同相关的知识,希望对你有一定的参考价值。
参考技术A XML:可扩展标记语言
读XML,XML文件的解析
三种解析XML的文件的方式
1. SAX 事件驱动 不是一次性加载到内存
2. DOM 一次加载到内存,性能较差 适合服务器端编程
3. XMLPULL 适应嵌入式设备,占用内存较小 API相对简单
OpenAPI
JSON: 相对于XML格式,更节省空间。
1) 大括号开始结束
2) 内容部分每条数据以“,”分隔
3) 每条数据由键值对构成,key必须是字符串“”
4) 值可以是:String、double、int、long、boolean、
jsonObject、jsonArray
把要解析的XML文件放在assets目录下,这里解释下
res/raw和assets的相同点:
两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
res/raw和assets的不同点:
1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
2.res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹
读取文件资源:
1.读取res/raw下的文件资源,通过以下方式获取输入流来进行写操作
· InputStream is =getResources().openRawResource(R.id.filename);
2.读取assets下的文件资源,通过以下方式获取输入流来进行写操作
· AssetManager am = null;
· am = getAssets();
· InputStream is = am.open("filename");
注意1:Google的android系统处理Assert有个bug,在AssertManager中不能处理单个超过1MB的文件,不然会报异常,raw没这个限制可以放个4MB的Mp3文件没问题。
注意2:assets 文件夹是存放不进行编译加工的原生文件,即该文件夹里面的文件不会像 xml, java 文件被预编译,可以存放一些图片,html,js, css 等文件。
解析如下文件
1
2
3
4
5
6
7
8
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="@+idtton1"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
XmlPullParser pullParser = Xml.newPullParser();//得到XML解析器
AssetManager assetManager = getAssets();//文件保存在assets目录下,得到assetManager管理器
InputStream is;
try
is = assetManager.open("activity_main.xml");//打开文件,得到输入流
pullParser.setInput(is , "utf-8");// String inputEncoding格式
int eventType = pullParser.getEventType();//得到事件类型
while(eventType != XmlPullParser.END_DOCUMENT)//文档的末尾
//遍历内部的内容
String name = pullParser.getName();
if("TextView".equals(name))
String value = pullParser.getAttributeValue(2);//得到属性值(位置)
textView.setText("显示结果为:" + value);
break;/到就返回
eventType = pullParser.next();//读取下一个标签
显示结果为:
XmlPullParser 与 XmlSerializer
XmlSerializer与XmlPullParser的使用实践:
先贴代码:
1.利用eclipse生成一个默认的工程;
2.修改布局文件activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <Button android:id="@+id/btn_product" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="生成XML" /> <Button android:id="@+id/btn_pull" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="解析XML" /> </LinearLayout>
3.MainActivity.java修改
package com.example.testxml; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlSerializer; import android.R.integer; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.util.Log; import android.util.Xml; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { private Button btn_product; private Button btn_pull; private List<Person> personInfo = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_product = (Button) findViewById(R.id.btn_product); btn_pull = (Button) findViewById(R.id.btn_pull); btn_product.setOnClickListener(this); btn_pull.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.btn_product: String exState = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(exState)) { File exDirectory = Environment.getExternalStorageDirectory(); saveToSdCard(exDirectory + "/test.xml"); } else { return; } break; case R.id.btn_pull: String exState1 = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(exState1)) { File exDirectory = Environment.getExternalStorageDirectory(); getXmlInfo(exDirectory + "/test.xml"); for (Person i : personInfo) { Log.i("TAG", i.toString()); } } else { return; } break; } } private void getXmlInfo(String dir) { // TODO Auto-generated method stub try { Person person = null; XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(true); XmlPullParser xpp = factory.newPullParser(); FileInputStream input = new FileInputStream(dir); xpp.setInput(input, "UTF-8"); int eventType = xpp.getEventType(); while (XmlPullParser.END_DOCUMENT != eventType) { switch (eventType) { case XmlPullParser.START_DOCUMENT: personInfo = new ArrayList<Person>(); break; case XmlPullParser.START_TAG: if ("Persons".equals(xpp.getName())) { } else if ("person".equals(xpp.getName())) { person = new Person(); String attri = xpp.getAttributeName(0); // 获取属性名称 if ("id".equals(attri)) { String id = xpp.getAttributeValue(0); // 获取属性名称的值 person.setId(id); } } else if ("name".equals(xpp.getName())) { person.setName(xpp.nextText()); } else if ("age".equals(xpp.getName())) { person.setAge(xpp.nextText()); } else if ("score".equals(xpp.getName())) { //实际就是把xpp.nextText拆分成了两步而已 xpp.next(); if (xpp.getEventType() == XmlPullParser.TEXT) person.setScore(xpp.getText()); } break; case XmlPullParser.END_TAG: if ("person".equals(xpp.getName())) { personInfo.add(person); } break; } eventType = xpp.next(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void saveToSdCard(String dir) { // TODO Auto-generated method stub XmlSerializer xml = Xml.newSerializer(); try { int i; FileOutputStream ouput = new FileOutputStream(dir); xml.setOutput(ouput, "UTF-8"); xml.startDocument(null, true); xml.startTag(null, "Persons"); for (i = 0; i < 10; i++) { xml.startTag(null, "person"); xml.attribute(null, "id", Integer.toString(i)); xml.startTag(null, "name"); xml.text("张" + i); xml.endTag(null, "name"); xml.startTag(null, "age"); xml.text("10" + i); xml.endTag(null, "age"); xml.startTag(null, "score"); xml.text("60" + i * 2); xml.endTag(null, "score"); xml.endTag(null, "person"); } xml.endTag(null, "Persons"); xml.endDocument(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
4.Person.java
package com.example.testxml; public class Person { private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } private String name; private String age; private String score; public Person() { name = null; age = null; score = null; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getScore() { return score; } public void setScore(String score) { this.score = score; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", score=" + score + "]"; } }
实践过程中遇到的问题:
1.XmlPullParser解析器的内容获取:
XmlPullParser.START_DOCUMENT :XML解析的开始标志<?xml version="1.0" encoding="UTF-8" standalone="true"?>
XmlPullParser.START_TAG :节点标签 <Persons>
XmlPullParser.END_TAG: 节点结束标签</Persons>
XmlPullParser.TEXT :节点之间内容的标签 <age>100</age>也就是100这个内容值;具体使用详见上面代码;
XmlPullParser.END_DOCUMENT: XML解析结束标志</Persons>“ ”,引号之间存在一个结束的内容;
2.ArrayList当中内容存储的方式:
List<Person> personInfo = new ArrayList<Person>()
通过personInfo.add(person)去添加内容到数组列表时,person添加到数组并非像C当中一样将内容拷贝到数组列表,而类似于指针建立了一个指向关系;
因此如果每次添加的person都是同一个,那么数组列表中的内容值会被替换成最后添加的内容;
以上是关于android中用xmlpullparser解析xml文件,以及res/raw和assets的不同的主要内容,如果未能解决你的问题,请参考以下文章
如何使用xmlpullparser解析android中的汉字
Android:DOM vs SAX vs XMLPullParser 解析?