1、该项目主要有下面的两个作用
(1)将xml文件解析成对象的List对象,xml文件可以来自手机本地,也可以来自服务器返回的xml数据
(2)强list对象保存成xml文件,xml保存到手机的内存卡上
Android项目也是采用mvc的框架
在手机的存储空间中保存wy目录下了存在person.xml文件
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?> <Persons> <person id="23"> <name>wee</name> <age>21</age> </person> <person id="24"> <name>wee4</name> <age>24</age> </person> <person id="23"> <name>wee5</name> <age>27</age> </person> </Persons>
我们要对这个xml文件进行解析
我们要看解析的业务类:
package contract.test.service; import android.content.Context; import android.util.Log; import android.util.Xml; import android.widget.Toast; import org.xml.sax.helpers.XMLReaderFactory; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import contract.test.domain.Person; public class XmlPullParse { private Context context; private List<Person> persons = null; Person person = null; public XmlPullParse(Context context) { this.context = context; } public List<Person> xmlPullParse(InputStream xml) throws Exception { /* *//*兴建一个pull解析器*//* XmlPullParser xmlPullParse = XmlPullParserFactory.newInstance().newPullParser(); //设置解析器的输入流及其解析格式 xmlPullParse.setInput(xml, "UTF-8"); Log.i("weiyuan", "23232223"); int envetType = xmlPullParse.getEventType(); Toast.makeText(context, "文件打开失败或者sdcard写保护!", Toast.LENGTH_LONG).show(); while (envetType != xmlPullParse.END_DOCUMENT) { *//*解析到了文档的开始:<?xml version="1.0" encoding="UTF-8"?> *//* if (envetType == xmlPullParse.START_DOCUMENT) { persons = new ArrayList<Person>(); } *//* 元素节点开始*//* if (envetType == xmlPullParse.START_TAG) { if ("person".equals(xmlPullParse.getName())) { person = new Person(); int id = new Integer(xmlPullParse.getAttributeName(0)); person.setId(id); } if ("name".equals(xmlPullParse.getName())) { String name = xmlPullParse.nextText(); person.setName(name); } if ("age".equals(xmlPullParse.getName())) { int age = new Integer(xmlPullParse.nextText()); person.setAge(age); } } if(envetType==xmlPullParse.END_TAG) { if("person".equals(xmlPullParse.getName())) { persons.add(person); person = null; } } envetType = xmlPullParse.next(); } Toast.makeText(context, "535335!", Toast.LENGTH_LONG).show(); return persons; }*/ List<Person> persons = null; Person person = null; XmlPullParser parser = Xml.newPullParser();//得到解析器 parser.setInput(xml, "UTF-8");//xml编码的utf-8格式 int eventType = parser.getEventType();//产生第一个事件 while(eventType!=XmlPullParser.END_DOCUMENT){//只要不是文档结束事件 switch (eventType) { case XmlPullParser.START_DOCUMENT: persons = new ArrayList<Person>(); break; case XmlPullParser.START_TAG: String name = parser.getName();//获取解析器当前指向的元素的名称 if("person".equals(name)){ person = new Person(); person.setId(new Integer(parser.getAttributeValue(0)));//这里0表示当前元素节点只有一个属性值,获得第二个属性值可用 //parser.getAttributeValue(1) } if(person!=null){ if("name".equals(name)){ person.setName(parser.nextText());//获取解析器当前指向元素的下一个文本节点的值 } if("age".equals(name)){ person.setAge(new Integer(parser.nextText())); } } break; case XmlPullParser.END_TAG: if("person".equals(parser.getName())){ persons.add(person); person = null; } break; } eventType = parser.next(); } return persons; } /*保存数据到xml中,保存到sd卡的当前目录下的123.xml中*/ public void saveToXml(OutputStream output,List<Person>persons) throws XmlPullParserException, IOException { //建立输出破解器 XmlSerializer xmlSerializer = XmlPullParserFactory.newInstance().newSerializer(); xmlSerializer.setOutput(output,"UTF-8"); xmlSerializer.startDocument("UTF-8",true); xmlSerializer.startTag(null,"Persons"); for(Person person:persons) { xmlSerializer.startTag(null,"person"); xmlSerializer.attribute(null,"id", person.getId().toString()); xmlSerializer.startTag(null,"name"); xmlSerializer.text(person.getName()); xmlSerializer.endTag(null,"name"); xmlSerializer.startTag(null,"age"); xmlSerializer.text(person.getAge().toString()); xmlSerializer.endTag(null,"age"); xmlSerializer.endTag(null,"person"); } xmlSerializer.endTag(null,"Persons"); xmlSerializer.endDocument(); output.flush(); output.close(); } }
我们来看下activity的代码:
package contract.test.xmlpullparse; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import contract.test.domain.Person; import contract.test.service.XmlPullParse; public class MyActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); /*从xml中解析数据*/ if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { Log.i("weiyuan", Environment.getExternalStorageDirectory().getAbsolutePath().toString() + File.separator + "weiyuan"); /* File file = new File(Environment.getExternalStorageDirectory().toString() +File.separator+"123.xml");*/ /*File file = new File(Environment.getExternalStorageDirectory().toString() +"/weiyuan/person.xml" );*/ //初始化File /*几点注意事项 * 1 我是在sd当前目录下自己手动建立了一个wy的文件夹,该该文件夹下新建了一个person.xml的xml文件 * 2 要访问该文件夹下的person.xml文件必须保证高文件夹和该文件是可读写的,一般自己在sd卡上手动建立的文件是 * 受保护的自己要该为不受保护的 * * <元素 元素属性=xxx> 可以存在多个属性 <元素2> asdasd </元素2> </元素>*/ /*其中asdasd是文本节点,nextText()函数就是获得asdasd的值*/ String path=Environment.getExternalStorageDirectory().toString() +File.separator +"wy" +File.separator +"person.xml"; File file=new File(path); if (file.exists()) { Toast.makeText(getApplicationContext(), "文件夹存在", Toast.LENGTH_LONG).show(); Log.i("weiyuan", Environment.getExternalStorageDirectory().toString() + File.separator + "weiyuan"); } else {Toast.makeText(getApplicationContext(), "文件夹不存在", Toast.LENGTH_LONG).show(); try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } Toast.makeText(getApplicationContext(), "xml文件不存在", Toast.LENGTH_LONG).show(); Log.i("weiyuan", Environment.getExternalStorageDirectory().toString() ); } try { InputStream input = new FileInputStream(file); /*FileInputStream input = new FileInputStream(file);这也是正确的*/ XmlPullParse xmlPullParse = new XmlPullParse(getApplicationContext()); try { List<Person> persons = xmlPullParse.xmlPullParse(input); for (Person person :persons) { Log.i("weiyuan",person.toString()); } Toast.makeText(getApplicationContext(), "文件解析成功!", Toast.LENGTH_LONG).show(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "文件解析失败", Toast.LENGTH_LONG).show(); } } catch (FileNotFoundException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "文件输入流失败!", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(getApplicationContext(), "文件打开失败或者sdcard写保护!", Toast.LENGTH_LONG).show(); } /*将数据保存xml文件中*/ if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File file = new File(Environment.getExternalStorageDirectory().toString()+File.separator+"123.xml"); try { OutputStream outputStream = new FileOutputStream(file); XmlPullParse xmlPullParse = new XmlPullParse(getApplicationContext()); List<Person> persons = new ArrayList<Person>(); persons.add(new Person(23,"wee",21)); persons.add(new Person(24,"wee4",24)); persons.add(new Person(23,"wee5",27)); try { xmlPullParse.saveToXml(outputStream,persons); Toast.makeText(getApplicationContext(), "数据保存到123.xml中成功!", Toast.LENGTH_LONG).show(); } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } } else { Toast.makeText(getApplicationContext(), "文件打开失败或者sdcard写保护!", Toast.LENGTH_LONG).show(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.my, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
person类对象的代码是:
package contract.test.domain; public class Person { private Integer id ; //int 和Integer的最大区别,Integer是类,该类具有透toString方法,可以转换为字符串 private String name ; private Integer age; public Person(Integer id, String name, Integer age) { this.id = id; this.name = name; this.age = age; } public Person() { } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
注意一定不要忘记了sd卡的使用权限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="contract.test.xmlpullparse" > <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MyActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <!-- 在SDCard中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 往SDCard写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> </manifest>