編輯:Android開發實例
前言
之前有講過在Android下如何解析XML文件的內容,這篇博客講講如何把一個對象序列化為XML格式,有時候一些項目中需要傳遞一些XML格式的數據。而對於如何解析XML,不了解的朋友可以看看其他三篇:http://www.fengfly.com/plus/view-213372-1.html、http://www.fengfly.com/plus/view-213373-1.html、http://www.fengfly.com/plus/view-213374-1.html。
什麼是XML?
首先我們先了解一下什麼是XML。XML,可擴展標記語言 (Extensible Markup Language) ,用於標記電子文件使其具有結構性的標記語言,可以用來標記數據、定義數據類型,是一種允許用戶對自己的標記語言進行定義的源語言,這是百度百科的解釋。而XML是一種在Internet中傳輸數據的常見格式,它與HTML一樣,都是SGML(標准通用標記語言),無論你是需要通過Internet訪問數據,或者發送數據給Web服務,都可能需要用到XML的知識。恰恰Android應用程序需要和網絡交互,否則只是一款單機的無互動的應用程序,所以很可能在Android應用程序開發的過程中使用到XML。
由於XML的擴展性強,致使它需要有穩定的基礎規則來支持擴展,該語法規則需要注意的是:
XML序列化
當獲取到一段數據後,如果需要把它序列化成XML的格式,通常有兩種辦法:
使用拼接字符串的方式很簡單,就是個體力活,把需要序列化的對象,依照一定的格式序列化即可。下面通過一個示例講解來演示如何拼接字符串,在示例中模擬聯系人數據,然後對其進行序列化成XML,最後保存在SD卡上。
- private void backupToContact1(){
- StringBuilder sbuilder=new StringBuilder();
- // 設置XML的數據頭
- sbuilder.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
- sbuilder.append("<contacts>");
- // 遍歷聯系人信息
- for(Contact contact:Contacts){
- if(contact!=null){
- sbuilder.append("<contact id='"+contact.getId()+"'>");
- sbuilder.append("<name>");
- sbuilder.append(contact.getName());
- sbuilder.append("</name>");
- sbuilder.append("<number>");
- sbuilder.append(contact.getNumber());
- sbuilder.append("</number>");
- sbuilder.append("<address>");
- sbuilder.append(contact.getAddress());
- sbuilder.append("</address>");
- sbuilder.append("</contact>");
- }
- }
- sbuilder.append("</contacts>");
- try {
- // 在SD卡上創建一個xml文件
- File file=new File(Environment.getExternalStorageDirectory(),"backup1.xml");
- FileOutputStream fos=new FileOutputStream(file);
- // 把序列化的數據寫入到XML文件中
- fos.write(sbuilder.toString().getBytes());
- fos.close();
- Toast.makeText(MainActivity.this, "備份成功", 0).show();
- } catch (IOException e) {
- Toast.makeText(MainActivity.this, "備份失敗", 0).show();
- e.printStackTrace();
- }
- }
執行完之後,可以把SD卡上的XML文件導出到電腦上,查看其內容。
對於拼接字符串而言,可以看出,很容易出錯,尤其是每個標簽內如果還存在屬性值就更需要細心了。而且如果其內容存在特殊的符號,如“<、>”等,就會導致XML序列化後的XML文件出錯,而使用XmlSerializer來序列化XML文件就不存在這些問題。
下面介紹第二種方式,通過XmlSerializer類來序列化XML。那先了解一下XmlSerializer,XmlSerializer主要是是以數據流的形式序列化XML,而它是一個接口類型,無法直接實例化,需要通過一個靜態方法Xml.newSerializer()獲取對象。
以下是一些常用方法:
上面已經介紹過了XmlSerializer的常用方法,下面通過一個示例來演示XmlSerializer的使用。在示例中實現的功能和上面拼接字符串序列化XML一致,都是序列化模擬的聯系人信息,然後以XML的格式保存在SD卡上。
- private void backupToContact2(){
- try {
- // 在SD卡上創建一個文件
- File file=new File(Environment.getExternalStorageDirectory(),"backup2.xml");
- FileOutputStream fos=new FileOutputStream(file);
- // 獲取一個XmlSerializer
- XmlSerializer serializer = Xml.newSerializer();
- // 設置XML的輸出流以及編碼格式
- serializer.setOutput(fos,"utf-8");
- // 設置文檔的開頭,以及編碼格式
- serializer.startDocument("utf-8", true);
- // 開始標簽
- serializer.startTag(null, "contacts");
- for(Contact contact:Contacts){
- serializer.startTag(null, "contact");
- // 設置contact標簽的id屬性
- serializer.attribute(null, "id", contact.getId()+"");
- serializer.startTag(null, "name");
- serializer.text(contact.getName());
- serializer.endTag(null, "name");
- serializer.startTag(null, "number");
- serializer.text(contact.getNumber());
- serializer.endTag(null, "number");
- serializer.startTag(null, "address");
- serializer.text(contact.getAddress());
- serializer.endTag(null, "address");
- serializer.endTag(null, "contact");
- }
- // 一個結束標簽
- serializer.endTag(null, "contacts");
- // 標記文檔的結束
- serializer.endDocument();
- // 關閉輸出流
- fos.close();
- Toast.makeText(MainActivity.this, "備份成功", 0).show();
- } catch (Exception e) {
- e.printStackTrace();
- Toast.makeText(MainActivity.this, "備份失敗", 0).show();
- }
- }
保存成功之後,可以通過File Explorer導出XML文件查看其內容,上面兩個示例序列化的XML文件一致,如下:
- <?xml version="1.0" encoding="utf-8"?>
- <contacts>
- <contact id="0">
- <name>Damon0</name>
- <number>18600000000</number>
- <address>beijing0</address>
- </contact>
- <contact id="1">
- <name>Damon1</name>
- <number>18600000001</number>
- <address>beijing1</address>
- </contact>
- <contact id="2">
- <name>Damon2</name>
- <number>18600000002</number>
- <address>beijing2</address>
- </contact>
- <contact id="3">
- <name>Damon3</name>
- <number>18600000003</number>
- <address>beijing3</address>
- </contact>
- <contact id="4">
- <name>Damon4</name>
- <number>18600000004</number>
- <address>beijing4</address>
- </contact>
- <contact id="5">
- <name>Damon5</name>
- <number>18600000005</number>
- <address>beijing5</address>
- </contact>
- <contact id="6">
- <name>Damon6</name>
- <number>18600000006</number>
- <address>beijing6</address>
- </contact>
- <contact id="7">
- <name>Damon7</name>
- <number>18600000007</number>
- <address>beijing7</address>
- </contact>
- <contact id="8">
- <name>Damon8</name>
- <number>18600000008</number>
- <address>beijing8</address>
- </contact>
- <contact id="9">
- <name>Damon9</name>
- <number>18600000009</number>
- <address>beijing9</address>
- </contact>
- </contacts>
在示例中,訪問了SD卡,所以需要在清單文件中加入SD卡寫入權限:
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
源碼下載
總結
因為拼接字符串的方式比較不直觀,容易出錯,量大了需要很細心才行,基本上是個體力活,而且如果內容存在對於一些對於XML格式數據有特殊意義的符號,會導致拼接後的XML數據無法正常被解析。一般情況下,推薦使用XmlSerializer來序列化XML數據,使用XmlSerializer來序列化XML不存在這方面的問題,對於一些特殊符號,它會自動對其進行轉義。
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我
在Android程序中很多客戶端軟件和浏覽器軟件都喜歡用Tab分頁標簽來搭建界面框架。讀者也許會馬上想到使用TabHost 與 TabActivity的組合,其實
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我
Person實體類代碼如下:package com.ljq.domain; public class Person { pri