這一章我們來學習Android中的XML解析器,Android中內建了三個XML解析器,有PULL,SAX,DOM解析器,其中PULL跟SAX都是以事件作為驅動導向的解析器,優點是佔用記憶體小,處理速度快,DOM是將整個XML放入記憶體中再解析,處理速度要稍差一些,但DOM也有自己的優點,可以在解析的時候適當增加節點.OK,我們先來看一下我們要解析的xml檔案
<?xml version="1.0" encoding="UTF-8"?><persons><person id = "1"><status>大徙弟</status><name>孫悟空</name><tool>金箍棒</tool><number>殺死了50隻妖怪</number></person><person id = "2"><status>二徙弟</status><name>豬八戒</name><tool>九齒釘耙 </tool><number>殺死了40隻妖怪</number></person><person id = "3"><status>三徙弟</status><name>沙和尚</name><tool>降妖寶杖</tool><number>殺死了30隻妖怪</number></person></persons>
這裡面定義了一些個人的資訊和其他具體資訊,好了,存入模擬器的SD目錄下,接下來,我們先定義JavaBean,Person.java
public class Person{private String id;private String status;private String name;private String tool;private String number;public String getId(){return id;}public void setId(String id){this.id = id;}public String getStatus(){return status;}public void setStatus(String status){this.status = status;}public String getName(){return name;}public void setName(String name){this.name = name;}public String getTool(){return tool;}public void setTool(String tool){this.tool = tool;}public String getNumber(){return number;}public void setNumber(String number){this.number = number;}@Overridepublic String toString(){return "Person [id=" + id + ", status=" + status + ", name=" + name+ ", tool=" + tool + ", number=" + number + "]";}}
對應上面xml的檔案中的資料,接下來就是重點嘍,要好好學哦,呵呵,PULL解析類PullHandler.java
import java.io.InputStream;import java.util.ArrayList;import java.util.List;import org.xmlpull.v1.XmlPullParser;import android.util.Xml;public class PullHandler{private InputStream input;private List<Person> persons;private Person person;public PullHandler(){}public void setInput(InputStream input){this.input = input;}public PullHandler(InputStream input){this.input = input;}public List<Person> getPersons(){try{XmlPullParser parser = Xml.newPullParser();parser.setInput(input, "UTF-8");int eventType = parser.getEventType();while (eventType != XmlPullParser.END_DOCUMENT){switch (eventType){//XmlPullParser.START_DOCUMENT表示開始文檔事件case XmlPullParser.START_DOCUMENT:persons = new ArrayList<Person>();break;// XmlPullParser.START_TAG: 開始標籤case XmlPullParser.START_TAG://parser.getName()擷取節點的名稱String tag = parser.getName();if ("person".equals(tag)){person = new Person();//parser.getAttributeName(0)取得<person id="1">中的第一個屬性值String id = parser.getAttributeValue(0);person.setId(id);}if (null != person){if ("status".equals(tag)){//parser.nextText();擷取下一個text類型的節點person.setStatus(parser.nextText());}if ("name".equals(tag)){person.setName(parser.nextText());}if ("tool".equals(tag)){person.setTool(parser.nextText());}if ("number".equals(tag)){person.setNumber(parser.nextText());}}break;// XmlPullParser.END_TAG:結束標籤case XmlPullParser.END_TAG:if ("person".equals(parser.getName())){persons.add(person);person = null;}break;}//event=parser.next();繼續下一個元素eventType = parser.next();}input.close();return persons;} catch (Exception e){e.printStackTrace();}return null;}}
OK,解析類寫完了,測試一下吧,用上一節課的單元測試試一下呢,對於每個小方法做單元測試很重要,這要能及時解決出現的問題,呵呵,我快像唐僧一樣了,阿彌陀佛,要是不明日章元測試的話,就看一下
Android[中級教程]第四章 單元測試AndroidTestCase
import java.io.File;import java.io.FileInputStream;import java.util.List;import android.os.Environment;import android.test.AndroidTestCase;public class PullHandlerTest extends AndroidTestCase{public void testGetPersons(){//取得當前SD目錄下的檔案路徑File SD_Files = Environment.getExternalStorageDirectory();//取得persons.xml檔案的路徑,這裡我是存在sdcard/persons.xmlString file_path = SD_Files.getName() + File.separator + "persons.xml";try{FileInputStream fis = new FileInputStream(new File(file_path));PullHandler pullHandler = new PullHandler(fis);List<Person> persons = pullHandler.getPersons();//輸出persons中的資料System.out.println(persons);} catch (Exception e){// TODO Auto-generated catch blocke.printStackTrace();}}}
測試類別寫完了,測試一下吧,OK,接下來就是定義main.xml了
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><TextView android:textAppearance="?android:attr/textAppearanceMedium"android:layout_width="wrap_content" android:text="唐僧的三個徙弟"android:layout_height="wrap_content" android:id="@+id/textView1"android:paddingLeft="10dip" android:paddingBottom="10dip"></TextView><ListView android:id="@+id/xml_list" android:layout_height="wrap_content"android:layout_width="match_parent"></ListView></LinearLayout>
定義了一個ListView和一個TextView,ListView是準備顯示xml中的資料的
再定義一個list_item.xml是每一行要顯示資料的樣式
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayout android:layout_height="wrap_content"android:id="@+id/linearLayout1" android:layout_width="match_parent"><TextView android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"android:layout_width="wrap_content" android:text="ID: "android:paddingLeft="10dp"></TextView><TextView android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"android:layout_width="wrap_content" android:text="TextView"android:id="@+id/id"></TextView><TextView android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceMedium"android:layout_width="wrap_content" android:text="TextView"android:id="@+id/name" android:paddingLeft="30dp"></TextView></LinearLayout><LinearLayout android:layout_height="wrap_content"android:id="@+id/linearLayout2" android:layout_width="match_parent"><TextView android:layout_height="wrap_content"android:layout_width="wrap_content" android:text="殺死了"android:paddingLeft="10dp"></TextView><TextView android:text="TextView" android:id="@+id/number"android:layout_width="wrap_content" android:layout_height="wrap_content"android:textColor="#FF0000"></TextView><TextView android:text="只妖怪" android:layout_width="wrap_content"android:layout_height="wrap_content"></TextView></LinearLayout></LinearLayout>
好了,都定義完了,最後就是我們的Activity了
import java.io.File;import java.io.FileInputStream;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.widget.ListView;import android.widget.SimpleAdapter;public class PullActivity extends Activity{private ListView listView;private SimpleAdapter adapter;@Overrideprotected void onCreate(Bundle savedInstanceState){// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.xml_handler);listView = (ListView)findViewById(R.id.xml_list);try{//自完義適配方法getAdapter();} catch (Exception e){e.printStackTrace();}listView.setAdapter(adapter);}//自訂適配方法private void getAdapter() throws Exception{List<Map<String, String>> lists = new ArrayList<Map<String, String>>();//這一部分就是剛才我們做測試用的部分File SD_Files = Environment.getExternalStorageDirectory();String file_path = SD_Files.getName() + File.separator + "persons.xml";FileInputStream input = new FileInputStream(new File(file_path));PullHandler pullHandler = new PullHandler(input);List<Person> persons = pullHandler.getPersons();//將persons中的資料轉換到ArrayList<Map<String, String>>中,因為SimpleAdapter要用這個類型的資料進行適配Map<String, String> map;for(Person p : persons){map = new HashMap<String, String>();map.put("id", p.getId());map.put("status", p.getStatus());map.put("name", p.getName());map.put("tool", p.getTool());map.put("number", p.getNumber());lists.add(map);}//HashMap<String, String>中的keyString[] from = {"id", "status", "name", "tool", "number"};//list_item.xml中對應的控制項IDint[] to = {R.id.item_id, R.id.item_status, R.id.item_name, R.id.item_tool, R.id.item_number};adapter = new SimpleAdapter(this, lists, R.layout.handler_list_item, from, to);}}
好了,最後就是了
這一章有點長,希望同學們都看完,因為接下來的SAX解析和DOM解析,我們還需要用到這裡面的模板,謝謝