Android之旅十四 android中的xml檔案解析

來源:互聯網
上載者:User

標籤:android   des   style   blog   class   code   

   在我們做有關android項目的時候,肯定會涉及到對xml檔案的解析操作,下面給大家介紹一下xml檔案的解析,包含DOM、SAX、Pull以及以前我們用到的DOM4J和JDOM:

   要解析的XML檔案:person.xml

<?xml version="1.0" encoding="UTF-8"?><persons><person id="001"><name>zhangsan</name><age>25</age></person><person id="002"><name>lisi</name><age>23</age></person></persons>

   建立person實體類:

package cn.itcast.domain;public class Person {private Integer id;private String name;private Short age;public Person(){}public Person(Integer id, String name, Short age) {this.id = id;this.name = name;this.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 Short getAge() {return age;}public void setAge(Short age) {this.age = age;}@Overridepublic String toString() {return "Person [age=" + age + ", id=" + id + ", name=" + name + "]";}}


1、DOM解析XML:DOM解析是將XML檔案全部載入,組裝成一顆dom樹,然後通過節點以及節點之間的關係來解析xml檔案

public static List<Person> getPersons(InputStream inStream) throws Throwable{List<Person> persons = new ArrayList<Person>();//建立解析器工廠DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//建立解析器DocumentBuilder builder = factory.newDocumentBuilder();//建立文檔樹模型,所有的Node都以一定的順序包含在Document對象之內,//排列成一個樹狀結構,以後對XML文檔的所有操作都與解析器無關Document documnet = builder.parse(inStream);//擷取根項目Element root = documnet.getDocumentElement();//獲得根項目下的person節點列表NodeList personNodes = root.getElementsByTagName("person");for(int i=0 ; i < personNodes.getLength(); i++){Person person = new Person();//獲得節點中的元素Element personElement = (Element)personNodes.item(i);//獲得person中id屬性person.setId(new Integer(personElement.getAttribute("id")));//獲得person節點下的子節點NodeList personChilds = personElement.getChildNodes();for(int y=0 ; y < personChilds.getLength(); y++){if(personChilds.item(y).getNodeType()==Node.ELEMENT_NODE){//判斷當前節點是否是元素類型節點Element childElement = (Element)personChilds.item(y);if("name".equals(childElement.getNodeName())){//獲得相應元素的值person.setName(childElement.getFirstChild().getNodeValue());}else if("age".equals(childElement.getNodeName())){person.setAge(new Short(childElement.getFirstChild().getNodeValue()));}}}persons.add(person);}return persons;}

2、SAX解析XML:順序讀取XML檔案,不需要一次全部裝載整個檔案,由於行動裝置的記憶體資源有限,SAX的順序讀取方式更適合移動開發

public List<Person> getPersons(InputStream inStream) throws Throwable{//建立SAXParserFactorySAXParserFactory factory = SAXParserFactory.newInstance();    //建立SAX解析器SAXParser parser = factory.newSAXParser();//建立XML解析處理器PersonParser personParser = new PersonParser();//將XML解析處理器分配給解析器,對文檔進行解析,將每個事件發送給處理器parser.parse(inStream, personParser);inStream.close();return personParser.getPersons();}//定義解析處理器private final class PersonParser extends DefaultHandler{private List<Person> persons = null;//將解析的資料放在List集合中private String tag = null;//定義一個全域變數的標籤名稱private Person person = null;public List<Person> getPersons() {return persons;}//解析Document@Overridepublic void startDocument() throws SAXException {//解析<persons>部分persons = new ArrayList<Person>();}@Overridepublic void endDocument() throws SAXException {System.out.println("end parse xml");}/** * 解析Element * namespaceURI 命名空間 * localName 不帶首碼部分<person id="001">--->person * qName 帶首碼部分<abc:person id="001">---->abc:worker * attributes  屬性集合  <abc:person id="001">---->id="001".... */@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {//解析<person id="001">部分if("person".equals(localName)){person = new Person();person.setId(new Integer(attributes.getValue(0)));}tag = localName;}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {//解析其中的文本<name>zhangsan</name>-->zhangsanif(tag!=null){String data = new String(ch, start, length);//擷取文本節點的資料if("name".equals(tag)){person.setName(data);}else if("age".equals(tag)){person.setAge(new Short(data));}}}//解析結束元素@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {if("person".equals(localName)){persons.add(person);person = null;}tag = null;}}

3、pull解析XML:pull解析和SAX解析很相似,都是輕量級的解析,在android核心中已經嵌入了pull,所以我們不需要再添加第三方jar包來支援pull

/** * 使用pull解析XML文檔 * @param inStream * @return * @throws Throwable */public static List<Person> getPersons(InputStream inStream) throws Throwable{List<Person> persons = null;Person person = null;XmlPullParser parser = Xml.newPullParser();parser.setInput(inStream, "UTF-8");int eventType = parser.getEventType();//產生第一個事件while(eventType!=XmlPullParser.END_DOCUMENT){//只要不是文檔結束事件switch (eventType) {case XmlPullParser.START_DOCUMENT://判斷當前事件是否是文檔開始事件persons = new ArrayList<Person>();//初始化Person集合break;case XmlPullParser.START_TAG://判斷當前事件是否是標籤元素開始事件String name = parser.getName();//擷取解析器當前指向的元素的名稱if("person".equals(name)){person = new Person();//得到相應的標籤的屬性值person.setId(new Integer(parser.getAttributeValue(0)));}if(person!=null){if("name".equals(name)){//擷取解析器當前指向元素的下一個文本節點的值person.setName(parser.nextText());}if("age".equals(name)){person.setAge(new Short(parser.nextText()));}}break;case XmlPullParser.END_TAG://判斷當前事件是否是標籤元素結束事件if("person".equals(parser.getName())){persons.add(person);person = null;}break;}//進入下一元素並觸發相應事件eventType = parser.next();}return persons;}
採用pull解析器建立一個xml文檔:

/** * 使用pull解析器建立一個xml文檔 * @param persons * @param writer * @throws Throwable */public static void save(List<Person> persons, Writer writer) throws Throwable{XmlSerializer serializer = Xml.newSerializer();serializer.setOutput(writer);serializer.startDocument("UTF-8", true);serializer.startTag(null, "persons");for(Person person : persons){serializer.startTag(null, "person");serializer.attribute(null, "id", person.getId().toString());serializer.startTag(null, "name");serializer.text(person.getName());serializer.endTag(null, "name");serializer.startTag(null, "age");serializer.text(person.getAge().toString());serializer.endTag(null, "age");serializer.endTag(null, "person");}serializer.endTag(null, "persons");serializer.endDocument();writer.flush();writer.close();}
在android項目中通過Junit對各方法進行測試:

注意在使用junit的時候,需要在AndroidMainifest.xml中加入:

<uses-library android:name="android.test.runner" /><instrumentation android:name="android.test.InstrumentationTestRunner"  android:targetPackage="com.xin.activity" android:label="Tests for My App" />
編寫我們的java測試類別:

public class PersonServiceTest extends AndroidTestCase {private static final String TAG = "PersonServiceTest";public void testSAXGetPersons() throws Throwable{SAXPersonService service = new SAXPersonService();InputStream inStream = getClass().getClassLoader().getResourceAsStream("person.xml");List<Person> persons = service.getPersons(inStream);for(Person person : persons){Log.i(TAG, person.toString());    }}public void testDomGetPersons() throws Throwable{InputStream inStream = getClass().getClassLoader().getResourceAsStream("person.xml");List<Person> persons = DOMPersonService.getPersons(inStream);for(Person person : persons){Log.i(TAG, person.toString());}}public void testPullGetPersons() throws Throwable{InputStream inStream = getClass().getClassLoader().getResourceAsStream("person.xml");List<Person> persons = PULLPersonService.getPersons(inStream);for(Person person : persons){Log.i(TAG, person.toString());}}}

運行輸出即可得到我們想要的結果!

幾種方法比較:

 SAX:一行一行讀取,效率高,讀取到相應需要的資料後不再往下操作,操作複雜,適合行動裝置
 DOM:操作簡單,一開始載入一個DOM樹,當XML檔案相對比計較大的時候影響效率,速度慢

 * Pull解析和Sax解析不一樣的地方有
 * (1)pull讀取xml檔案後觸發相應的事件調用方法返回的是數字
 * (2)pull可以在程式中控制想解析到哪裡就可以停止解析

其實pull解析xml不僅適用於android,在我們的javase中也可以使用pull解析器來解析xml檔案,不過需要匯入相應的jar包:

kxml2-2.3.0.jar,:http://kxml.sourceforge.net/ 

xmlpull_1_1_3_4c.jar  :http://www.xmlpull.org/  

以前我們還使用了DOM4J和JDOM來解析xml,可以參見我的部落格,不過需要匯入相應的支援jar包:

DOM4J解析XML:http://blog.csdn.net/harderxin/article/details/7285770

JDOM解析XML:http://blog.csdn.net/harderxin/article/details/7285754

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.