在 Android 3.0 平臺上創建和解析 XML
簡介
作為最常用的智能手機平臺,Android 可同時用于智能手機和移動平板電腦。Motorola XOOM 就是一個 Android 平板電腦。在本文中,您可以學習如何在 Android 設備上創建和解析 XML 文檔。要輸出 XML,您可以使用標準的 javax.xml.transform.Transformer
類。要在 Android 上解析 XML,您可以使用 DOM 與 SAX 解析器。org.xmlpull.v1.XmlPullParser pull 解析器也可以用于解析 XML。本文中的示例使用了 Android Platform 3.0 來處理 XML。
組建環境
為了使用本文中給出的示例,您需要安裝和配置以下軟件。請參見"參考資料"中的相關鏈接。
常用縮寫詞
- ADT: Android Development Tools,Android 開發工具
- API: Application programming interface,應用程序編程接口
- AVD: Android Virtual Device,Android 虛擬設備
- DOM: Document object model,文檔對象模型
- IDE: Integrated Development Environment,集成開發環境
- JSON: JavaScript Object Notation,JavaScript 對象表示法
- SAX: Simple API for XML,XML 簡易 API
- SDK: Software Development Kit,軟件開發包
- UI: User Interface,用戶界面
- XML: Extensible Markup Language,可擴展標記語言
- 安裝 Eclipse IDE。
- 安裝針對 Eclipse 的 Android Development Tools (ADT)插件,它提供一組在 Eclipse 中開發 Android 應用程序的擴展。
- 下載并安裝 Android SDK Platform,它提供用于開發 Android 應用程序的工具。
- 選擇 Window > Android SDK 和 AVD Manager,在 Eclipse 中啟動 Android SDK 和 AVD Manager。
- 在 Android SDK 和 AVD Manager 中創建一個 Android Virtual Device (AVD),它是 Android 的模擬器。
請為 AVD 選擇 Platform 3.0 和 API 11。
創建一份 XML 文檔
在這一節中,您將在 Android 上創建一份 XML 文檔。第一步是創建一個 Android 項目。
- 在 Eclipse IDE 中選擇 File > New。在 New 對話框中,選擇 Android > Android Project。然后單擊 Next。
- 在 New Android Project 窗口中,如 圖 1中所示,指定:
- 項目名稱:
CreatingXML
- “構建目標” 復選框:Android Platform 3.0 和 API 11
- 屬性:
- 應用程序名稱:
CreatingXML
- 包名稱 :
android.xml
- 選擇創建活動:活動類 (
CreatingXML
)。一個活動代表一次用戶交互。該類擴展了Activity
類,為 UI 創建了一個窗口。 - 最低 SDK 版本:11
- 應用程序名稱:
圖 1. 為平臺 3.0 創建一個 Android 項目
- 項目名稱:
- 單擊 Next。
- 單擊 Finish。這樣就創建好了一個用于創建 XML 文檔的 Android 項目。Android 項目包含以下這些文件:
- 一個活動類
CreatingXML
,它擴展了 Activity 類。 - res/layout/main.xml 文件,它指定了 Android UI 組件的布局。
- AndroidManifest.xml 文件,它包含應用程序配置,比如包名稱,啟動 Android 應用程序時啟動的主要活動、應用程序組件、進程以及最低的 API 級別。
- 一個活動類
圖 2 顯示了 Android 項目 CreatingXML 的目錄結構。
圖 2. 用于創建 XML 文檔的 Android 項目
在 res/layout/main.xml 文件中,指定 Android UI 組件的布局。創建一個 LinearLayout
,并將 android:orientation
設置為 vertical
。在這個例子中,您將以文本消息的形式顯示 XML 文檔。添加一個 id 為 xmlresult
的 TextView
元素,以顯示 XML 文檔,如 清單 1 中所示。
清單 1. 布局文件 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="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/xmlresult" android:layout_width="fill_parent" android:layout_height="wrap_content"/> </LinearLayout>
在 AndroidManifest.xml 文件中,指定 Activity
運行 CreatingXML
。使用 uses-sdk
元素 11 指定最低的 Android 版本。使用活動元素與子元素指定活動 intent-filter
和 action
。清單 2 顯示了該文件。
清單 2. 配置文件 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.xml" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="11"/> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".CreatingXML" 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> </manifest>
現在,您將在活動類 CreatingXML
中創建一份 XML 文檔,該類擴展了 Activity
類。因為示例使用 javax.xml.parsers.DocumentBuilder
來創建 XML 文檔,需要導入以下內容。
javax.xml.parsers.DocumentBuilder
類javax.xml.parsers.DocumentBuilderFactory
類org.w3c.dom
包javax.xml.transform.TransformerFactory
類javax.xml.transform.Transformer
類javax.xml.transform.dom.DOMSource
類javax.xml.transform.stream.StreamResult
類
啟動該活動時將調用 onCreate(Bundle savedInstanceState)
方法。在 onCreate
方法中,可以使用 setContentView
方法設置 UI,并使用 setContentView(R.layout.main);
設置布局資源。
在 main.xml 文件中使用 findViewById
方法定義 Android 小部件 TextView
對象(其 id 為 xmlresult
),如下所示: TextView xmlResult = (TextView) findViewById(R.id.xmlresult);
。
使用靜態方法 newInstance()
創建 DocumentBuilderFactory
對象的一個實例。使用 DocumentBuilderFactory
類的 newDocumentBuilder()
方法創建一個 DocumentBuilder
對象,如 清單 3 中所示。
清單 3. 創建一個 DocumentBuilder
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
XML 文檔由 DOM 結構表示。使用 DocumentBuilder
類的 newDocument()
方法創建一個新的 Document
對象:Document document = documentBuilder.newDocument();
。
使用 createElement()
方法可創建 Document 對象的根元素 "catalog"
: Element rootElement = document.createElement("catalog");
。
正如 清單 4 中所示,可以使用 setAttribute
方法設置根元素上的 publisher
和 journal
屬性。
清單 4. 設置根元素屬性
rootElement.setAttribute("journal", "Oracle Magazine"); rootElement.setAttribute("publisher", "Oracle Publishing");
使用 appendChild()
方法將根元素附加到 Document
對象:document.appendChild(rootElement);
。
使用 createElement()
方法創建一個 "article"
元素。使用 appendChild()
方法將該元素附加到根元素,如 清單 5 中所示。
清單 5. 創建一個 "article" 元素
Element articleElement = document.createElement("article"); rootElement.appendChild(articleElement);
如 清單 6 中所示,向 "article"
元素添加一個 "edition"
元素。
清單 6. 添加 "edition" 元素
Element editionElement = document.createElement("edition"); articleElement.appendChild(editionElement);
使用 createTextNode()
方法向 "edition"
元素添加一個文本節點。將文本節點的值設置為 "Sept-Oct 2005",如下所示:editionElement.appendChild(document.createTextNode("Sept-Oct 2005"));
.
類似地,創建一個 "title"
元素并將它添加給 "article"
元素。如 清單 7 中所示,向 "title"
元素添加一個文本節點,并將其值設為 "Creating Search Pages"
。
清單 7. 創建一個文本節點
Element titleElement = document.createElement("title"); articleElement.appendChild(titleElement); titleElement.appendChild(document.createTextNode("Creating Search Pages"));
向 "article"
元素添加一個 "author"
元素。向 "author"
元素添加一個文本節點,并將其值設為 "Steve Muench"
,如 清單 8 中所示。
清單 8. 添加 "author" 元素
authorElement = document.createElement("author"); articleElement.appendChild(authorElement); authorElement.appendChild(document.createTextNode("Steve Muench"));
向根元素添加另一個 "article"
元素。您可以使用與非 Android 應用程序相同的方式來創建 XML 文檔 DOM 結構。這個示例將執行以下操作:
- 將 DOM
Document
對象輸出到一個ByteArrayOutputStream
中 - 以字符串的形式從
OutputStream
獲取 XML 文檔 - 設置 Android 上的
TextView
小部件上的字符串
使用靜態方法 newInstance()
創建一個 TransformerFactory
對象。如 清單 9中所示,使用 factory
對象的 newTransformer()
方法創建一個 Transformer
對象。
清單 9. 創建一個轉換器對象
TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer();
創建一個 java.util.Properties
對象,并設置以下輸出屬性:
- 縮進 (
INDENT
) - 輸出格式 (
METHOD
) - XML 聲明 (
OMIT_XML_DECLARATION
) - XML 版本 (
VERSION
) - XML 文檔的編碼方式 (
ENCODING
)
要轉換 DOM 結構,則需要使用 Source
對象與 Result
對象。從 Document
對象創建一個 DOMSource
對象。為了獲得輸出,我們將從 ByteArrayOutputStream
創建一個 ByteArrayOutputStream
對象和一個 StreamResult
對象,如 清單 10 中所示。
清單 10. 轉換 DOM 結構
DOMSource domSource = new DOMSource(document.getDocumentElement()); OutputStream output = new ByteArrayOutputStream(); StreamResult result = new StreamResult(output);
使用 Transformer
對象的 transform()
方法轉換 Document
對象,如下所示:transformer.transform(domSource, result);
。
從 ByteArrayOutputStream
對象獲取 String
對象,并設置 TextView
小部件 xmlResult
上的 String
。
清單 11. 獲取與設置字符串
String xmlString = output.toString(); xmlResult.setText(xmlString);
清單 12 顯示了 Activity
類 CreatingXML
。
清單 12. Activity 類 CreatingXML
package android.xml; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.transform.TransformerFactory; import javax.xml.transform.Transformer; import java.util.Properties; import javax.xml.transform.OutputKeys; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.OutputStream; import java.io.ByteArrayOutputStream; import javax.xml.transform.dom.DOMSource; public class CreatingXML extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView xmlResult = (TextView) findViewById(R.id.xmlresult); try { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory .newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory .newDocumentBuilder(); Document document = documentBuilder.newDocument(); Element rootElement = document.createElement("catalog"); rootElement.setAttribute("journal", "Oracle Magazine"); rootElement.setAttribute("publisher", "Oracle Publishing"); document.appendChild(rootElement); Element articleElement = document.createElement("article"); rootElement.appendChild(articleElement); Element editionElement = document.createElement("edition"); articleElement.appendChild(editionElement); editionElement. appendChild(document.createTextNode("Sept-Oct 2005")); Element titleElement = document.createElement("title"); articleElement.appendChild(titleElement); titleElement.appendChild(document .createTextNode("Creating Search Pages")); Element authorElement = document.createElement("author"); articleElement.appendChild(authorElement); authorElement. appendChild(document.createTextNode("Steve Muench")); articleElement = document.createElement("article"); rootElement.appendChild(articleElement); editionElement = document.createElement("edition"); articleElement.appendChild(editionElement); editionElement.appendChild(document .createTextNode("November - December 2010")); titleElement = document.createElement("title"); articleElement.appendChild(titleElement); titleElement.appendChild(document .createTextNode("Agile Enterprise Architecture")); authorElement = document.createElement("author"); articleElement.appendChild(authorElement); authorElement.appendChild(document.createTextNode("Bob Rhubart")); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); Properties outFormat = new Properties(); outFormat.setProperty(OutputKeys.INDENT, "yes"); outFormat.setProperty(OutputKeys.METHOD, "xml"); outFormat.setProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); outFormat.setProperty(OutputKeys.VERSION, "1.0"); outFormat.setProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperties(outFormat); DOMSource domSource = new DOMSource(document.getDocumentElement()); OutputStream output = new ByteArrayOutputStream(); StreamResult result = new StreamResult(output); String xmlString = output.toString(); xmlResult.setText(xmlString); } catch (ParserConfigurationException e) { } catch (TransformerConfigurationException e) { } catch (TransformerException e) { } } }
現在您可以運行 Android 應用程序了。右鍵單擊 CreatingXML 應用程序節點并選擇 Run As > Android Application,如 圖 3中所示。
圖 3. 運行 Android 應用程序
Android AVD 啟動,而 Android 應用程序部署在 AVD 上,如 圖 4 中所示。
圖 4. 安裝在 Android 設備上的應用程序
單擊 CreatingXML 應用程序圖標。啟動應用程序活動,在 Android 設備上將創建和顯示 XML 文檔,如 圖 5 中所示。
圖 5. 在 Android 設備上創建并顯示一份 XML 文檔
解析 XML 文檔
本節介紹如何解析 XML 文檔。您可以使用標準的 DOM 與 SAX 解析器或其他解析器。在使用了 org.xmlpull.v1.XmlPullParser 的示例中,將要解析 XML 文檔 catalog.xml,如 清單 13 中所示。
清單 13. catalog.xml
<?xml version = '1.0' encoding = 'UTF-8'?> <catalog journal="Oracle Magazine" publisher="Oracle Publishing"> <article> <edition>Sept-Oct 2005</edition> <title>Creating Search Pages</title> <author>Steve Muench</author> </article> <article> <edition>November - December 2010</edition> <title>Agile Enterprise Architecture</title> <author>Bob Rhubart</author> </article> </catalog>
和前一節 創建一份 XML 文檔 中一樣,您需要創建一個 Android 項目來解析 XML 文檔。
- 在 Eclipse IDE 中選擇 File > New。在 New 對話框中,選擇 Android > Android Project。然后單擊 Next。
- 在 New Android Project 窗口中,如 圖 6中一樣指定:
- 項目名稱:
ParsingXML
- “構建目標” 復選框:Android Platform 3.0 與 API 11。
- 屬性:
- 應用程序名稱:
ParsingXML
- 包名稱:
android.xml
- 選擇 “創建活動”:Activity 類 (
ParsingXML
) - 最低 SDK 版本:11
- 應用程序名稱:
圖 6. 創建一個 Android 項目來解析 XML 文檔
- 項目名稱:
- 單擊 Finish。
這樣就創建好了一個 Android 項目,它包含以下內容:
- 一個
Activity
類ParsingXML
- 一個 res/layout/main.xml 布局文件
- 一個 AndroidManifest.xml 應用程序配置文件
- 一個
解析 XML 文檔并使用標簽輸出元素值,將標簽與元素文本節點值輸出到 TextView
小部件上。
- 在 main.xml 文件中,為每個標簽和元素文本節點值添加一個
TextView
小部件。 - 創建一個
LinearLayout
并將android:orientation
設置為"vertical"
。 - 添加具有以下 id 的
TextView
元素:"journal_label"
"journal"
"publisher_label"
"publisher"
"edition1_label"
"edition1"
"title1_label"
"title1"
"author1_label"
"author1"
"edition2_label"
"title2_label"
"title2"
"author2_label"
"author2"
清單 14 顯示了 main.xml 文件。
清單 14. 布局文件 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="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/journal_label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Journal:"/> <TextView android:id="@+id/journal" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:id="@+id/publisher_label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Publisher:"/> <TextView android:id="@+id/publisher" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:id="@+id/edition1_label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Edition:"/> <TextView android:id="@+id/edition1" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:layout_width="fill_parent" android:id="@+id/title1_label" android:layout_height="wrap_content" android:text="Title:"/> <TextView android:id="@+id/title1" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:layout_width="fill_parent" android:id="@+id/author1_label" android:layout_height="wrap_content" android:text="Author:"/> <TextView android:id="@+id/author1" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:id="@+id/edition2_label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Edition:"/> <TextView android:id="@+id/edition2" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:layout_width="fill_parent" android:id="@+id/title2_label" android:layout_height="wrap_content" android:text="Title:"/> <TextView android:id="@+id/title2" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:layout_width="fill_parent" android:id="@+id/author2_label" android:layout_height="wrap_content" android:text="Author:"/> <TextView android:id="@+id/author2" android:singleLine="true" android:layout_width="fill_parent" android:layout_height="wrap_content"/> </LinearLayout>
在 AndroidManifest.xml 文件中指定以下內容:
- 要運行的
activity
,指定為ParsingXML
- 使用
uses-sdk
元素將最低的 Android 版本指定為 11 - 使用活動元素與子元素指定
activity
、intent-filter
與action
清單 15 顯示了最后獲得的 AndroidManifest.xml 文件:
清單 15. 配置文件 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.xml" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="11"/> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ParsingXML" 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> </manifest>
為了解析 XML 文檔源,該示例使用了 android.content.res.XmlResourceParser,它擴展了 XmlPullParser 接口。您需要在 res 目錄中為 XML 文檔創建一個目錄。
- 在 res 目錄中創建一個名為 xml 的目錄,然后將 XML 文檔復制到 res/xml 目錄中。
- 在
ParsingXML
活動類中,導入 android.content.res.XmlResourceParser 和 org.xmlpull.v1.XmlPullParser 接口。啟動活動時調用了
onCreate(Bundle savedInstanceState)
方法。 - 在
onCreate
方法中,使用setContentView
方法和布局資源設置 UI,比如:setContentView(R.layout.main);
- 使用
findViewById
方法與小部件 id 獲取 main.xml 文件中定義的 AndroidTextView
小部件,如 清單 16中所示。
清單 16. 獲取 TextView 小部件
TextView journal = (TextView) findViewById(R.id.journal); TextView publisher = (TextView) findViewById(R.id.publisher); TextView edition1 = (TextView) findViewById(R.id.edition1); TextView title1 = (TextView) findViewById(R.id.title1); TextView author1 = (TextView) findViewById(R.id.author1); TextView edition2 = (TextView) findViewById(R.id.edition2); TextView title2 = (TextView) findViewById(R.id.title2); TextView author2 = (TextView) findViewById(R.id.author2);
從 res/xml 目錄下的 catalog.xml 文檔創建一個 XmlResourceParser
對象,代碼如下:XmlResourceParser xpp = getResources().getXml(R.xml.catalog);
。
您將使用 XmlResourceParser
來解析 XML 文檔,它也是一個 pull 解析器(擴展了 XmlPullParser 接口)。該 pull 解析器將 XML 文檔處理為一系列解析事件。可以使用 next()
方法獲得下一個解析事件,代碼如下:xpp.next();
。
使用 getEventType
方法 int
獲取事件類型,它返回一個 int 值:eventType = xpp.getEventType();
。
Table 1 中顯示了所有可能返回的 int
值。
表 1. 事件類型 int
值
int 值 | 描述 |
COMMENT | 一段 XML 注釋 |
DOCDECL | XML 文檔類型描述 |
END_DOCUMENT | 文檔結尾 |
END_TAG | 一個元素標簽的結尾 |
IGNORABLE_WHITESPACE | 可忽略的空格 |
PROCESSING_INSTRUCTION | 處理指令 |
START_DOCUMENT | 文檔開始 |
START_TAG | 一個元素標簽的開始 |
TEXT | 字符數據 |
XML 文檔只需要解析元素與元素文本節點。這些屬性不會生成事件,您可以從元素中檢索它們。您只會看到 START_TAG
與 TEXT
事件類型,它們分別對應于元素開始標簽與元素文本節點。您首先要確定元素標簽,然后獲得元素標簽的文本節點值。使用 int
變量 iter
來表示 XML 文檔中不同的 "article"
元素,同時使用 String
變量 elemtext
來制定元素標簽名稱。要為迭代器指定一個 int
變量并為元素名稱指定一個 String
變量,請使用 清單 17 中的代碼。
清單 17. 指定變量
int iter = 0; String elemtext = null;
當到達 XML 文檔的結尾之前:
- 確定事件類型
- 獲得元素標簽名稱與元素標簽文本值
- 設置對應
TextView
小部件上的文本節點值
例如,像 清單 18 中一樣獲得元素標簽名稱。
清單 18. 獲得開始標簽的元素名稱
while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG) { String elemName = xpp.getName(); ... ... } }
如果元素標簽名稱是 "catalog"
,請獲得 "journal"
與 "publisher"
的屬性值,并設置 "journal"
與 "publisher"
TextView 小部件上的屬性值。可以使用 XmlResourceParser
的 getAttributeValue()
方法來獲得屬性值,如 清單 19 中所示。
清單 19. 獲得與設置屬性值
if (elemName.equals("catalog")) { String journalAttr = xpp.getAttributeValue(null,"journal"); String publisherAttr = xpp.getAttributeValue(null,"publisher"); journal.setText(journalAttr); publisher.setText(publisherAttr); ... }
增加每個 "article"
元素的迭代器變量 iter
的值,如 清單 20 中所示。
清單 20. 增加變量的值
if (elemName.equals("article")) {
iter = iter + 1;
}
如果事件類型為 TEXT
則獲得文本節點值,并在相應的 TextView
小部件上設置文本節點值。可以使用 elemtext
String
變量來獲得元素標簽名稱,該變量是為事件類型 START_TAG
設置的。使用 XmlResourceParser
的 getText()
方法獲得文本節點值。使用 setText
方法設置 TextView
小部件上的文本節點值,如 清單 21 中所示。
清單 21. 獲得文本節點值
else if (eventType == XmlPullParser.TEXT) { //Obtain the element name and element text node values and //set the text node values on the corresponding TextView //widgets }
清單 22 顯示了 Activity
類 ParsingXML
。
清單 22. Activity 類 ParsingXML
package android.xml; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import android.content.res.XmlResourceParser; public class ParsingXML extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.main); setContentView(R.layout.relativelayout); TextView journal = (TextView) findViewById(R.id.journal); TextView publisher = (TextView) findViewById(R.id.publisher); TextView edition1 = (TextView) findViewById(R.id.edition1); TextView title1 = (TextView) findViewById(R.id.title1); TextView author1 = (TextView) findViewById(R.id.author1); TextView edition2 = (TextView) findViewById(R.id.edition2); TextView title2 = (TextView) findViewById(R.id.title2); TextView author2 = (TextView) findViewById(R.id.author2); try { XmlResourceParser xpp = getResources().getXml(R.xml.catalog); xpp.next(); int eventType = xpp.getEventType(); int iter = 0; String elemtext = null; while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG) { String elemName = xpp.getName(); if (elemName.equals("catalog")) { String journalAttr = xpp.getAttributeValue(null, "journal"); String publisherAttr = xpp.getAttributeValue(null, "publisher"); journal.setText(journalAttr); publisher.setText(publisherAttr); } if (elemName.equals("article")) { iter = iter + 1; } if (elemName.equals("edition")) { elemtext = "edition"; } if (elemName.equals("title")) { elemtext = "title"; } if (elemName.equals("author")) { elemtext = "author"; } } else if (eventType == XmlPullParser.TEXT) { if (iter == 1) { if (elemtext.equals("edition")) { edition1.setText(xpp.getText()); } else if (elemtext.equals("title")) { title1.setText(xpp.getText()); } else if (elemtext.equals("author")) { author1.setText(xpp.getText()); } } else if (iter == 2) { if (elemtext.equals("edition")) { edition2.setText(xpp.getText()); } else if (elemtext.equals("title")) { title2.setText(xpp.getText()); } else if (elemtext.equals("author")) { author2.setText(xpp.getText()); } } } eventType = xpp.next(); } } catch (XmlPullParserException e) { } catch (IOException e) { } } }
要運行 Android 應用程序,請右鍵單擊 ParsingXML 應用程序并選擇 Run As > Android Application,如 圖 7 中所示。
圖 7. 運行一個 Android 應用程序來解析 XML 文檔
Android AVD 已啟動,而且 ParsingXML 應用程序已經安裝在了 Android 設備上,如 圖 8 中所示。
圖 8. 安裝在 Android 設備上的ParsingXML 應用程序
單擊 ParsingXML 應用程序啟動應用程序活動。然后解析 XML 文檔 catalog.xml 并將它輸出到 Android 設備,如 圖 9 中所示。
圖 9. 通過解析獲得的 XML 文檔節點值
元素標簽與元素文本節點是垂直堆放的。文本節點值位于相應標簽右側的布局更為可取。為了實現文本節點值位于標簽右側的自定義布局,可以使用 RelativeLayout
代替 LinearLayout
。使用 TextView
小部件的 android:layout_marginLeft
屬性可以讓文本節點值出現在標簽的右側。使用 android:layout_below
屬性可以讓文本節點值出現在前一行中文本節點值的下方。
RelativeLayout
提供了其他屬性,比如 android:layout_toRightOf
,用于輸出一個小部件在另一個小部件的右側;還提供了 android:layout_toLeftOf
,用于輸出一個組件在另一個組件的左側。清單 23 顯示了相對布局的 main.xml。
清單 23. 相對布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5px"> <TextView android:id="@+id/journal_label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Journal:"/> <TextView android:id="@+id/journal" android:layout_marginLeft="50px" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:id="@+id/publisher_label" android:layout_below="@id/journal_label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Publisher:"/> <TextView android:id="@+id/publisher" android:layout_below="@id/journal" android:layout_marginLeft="70px" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:id="@+id/edition1_label" android:layout_below="@id/publisher_label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Edition:"/> <TextView android:id="@+id/edition1" android:layout_below="@id/publisher" android:layout_width="fill_parent" android:layout_marginLeft="50px" android:layout_height="wrap_content"/> <TextView android:layout_width="fill_parent" android:id="@+id/title1_label" android:layout_below="@id/edition1_label" android:layout_height="wrap_content" android:text="Title:"/> <TextView android:id="@+id/title1" android:layout_marginLeft="40px" android:layout_below="@id/edition1" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:layout_width="fill_parent" android:id="@+id/author1_label" android:layout_below="@id/title1_label" android:layout_height="wrap_content" android:text="Author:"/> <TextView android:id="@+id/author1" android:layout_below="@id/title1" android:layout_width="fill_parent" android:layout_marginLeft="50px" android:layout_height="wrap_content"/> <TextView android:id="@+id/edition2_label" android:layout_below="@id/author1_label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Edition:"/> <TextView android:id="@+id/edition2" android:layout_below="@id/author1" android:layout_width="fill_parent" android:layout_marginLeft="50px" android:layout_height="wrap_content"/> <TextView android:layout_width="fill_parent" android:id="@id/title2_label" android:layout_below="@id/edition2_label" android:layout_height="wrap_content" android:text="Title:"/> <TextView android:id="@+id/title2" android:layout_marginLeft="40px" android:layout_below="@id/edition2" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TextView android:layout_width="fill_parent" android:id="@+id/author2_label" android:layout_below="@id/title2_label" android:layout_height="wrap_content" android:text="Author:"/> <TextView android:id="@+id/author2" android:layout_below="@id/title2" android:layout_width="fill_parent" android:layout_marginLeft="50px" android:layout_height="wrap_content"/> </RelativeLayout>
修改布局后返回 ParsingXML 應用程序。XML 文檔將在指定布局中解析與輸出節點值,如 圖 10 中所示。
圖 10. 格式化的 XML 文檔節點值
結束語
您可以在 Android 3.0 平臺上創建與解析 XML 文檔,該平臺既適用于智能手機,也適用于移動平板電腦。在本文中的示例中,您在 Android 上使用了標準的 DocumentBuilder
和 Transformer
API 來創建 XML 文檔。您應該已經學會了如何使用 XMLResourceParser
(它擴展了 XmlPullParser
)來解析 XML 文檔。
參考資料
學習
- Android: 學習如何創建 Android 應用程序。
- 在 Android 上使用 XML (Michael Galpin, developerWorks, 2009 年 6 月):探討當您使用針對 Android 的 XML API 構建自己的 Android 應用程序時,面對的處理 XML 的不同選擇。
- 使用 Android 和 XML 構建動態用戶界面 (Frank Ableson, developerWorks, 2010 年 9 月):了解用于設計類似于 Android 動態用戶界面應用程序的一種簡單架構,它允許非程序員從移動用戶那里收集數據。
- 在 Android 上使用 XML 和 JSON,第 1 部分:在 Android 應用程序上研究 JSON 和 XML 益處 (Frank Ableson, developerWorks, 2010 年 8 月):學習 XML 與 JSON 的基礎知識。了解如何構建一個可以解析與顯示以兩種格式提供的 Twitter 狀態更新種子的 Android 應用程序。
- 在 Android 上使用 XML 和 JSON,第 2 部分:交付混合了 JSON 的 Android 應用程序 (Frank Ableson, developerWorks, 2010 年 8 月):探討如何混合使用 JavaScript、JSON、回調函數與 Android-SDK Java 代碼來實現靈活的移動應用程序。
- developerWorks 上的 Android 內容:探討關于 Android 的文章、演示與指南。
- 此作者的更多文章 (Deepak Vohra, developerWorks, 2005 年 4 月至今):閱讀關于 Android、Ajax、PHP、XML、Web 服務、Ruby on Rails、EJB 和其他技術的文章。
- XML 新手入門 獲取學習 XML 所需的資源。
- developerWorks 中國網站 XML 技術專區:在 XML 專區獲取提高您的專業技能所需的資源,包括 DTD、模式和 XSLT。參閱 XML 技術文檔庫,獲得大量的技術文章和技巧、教程、標準和 IBM 紅皮書。
- IBM XML 認證:了解如何才能成為一名 IBM 認證的 XML 和相關技術的開發人員。
- 關注 developerWorks 技術活動 和 網絡廣播:隨時關注這些活動中的技術。
- developerWorks 播客:收聽面向軟件開發人員的有趣訪談和討論。
- developerWorks 演示中心:觀看演示,包括面向初學者的產品安裝和設置演示,以及為經驗豐富的開發人員提供的高級功能。
獲得產品和技術
- Android SDK:獲取最新的工具或平臺。
- Android Development Tools (ADT):下載這個插件,它可以為您提供構建 Android 應用程序的一個強大集成環境。
- JDK 6.0.:獲取最新的 Java™ 版本,包括性能改進與 bug 修復。
- Eclipse for Java EE.:下載最新版本。
- IBM 產品評估試用版軟件:下載或 IBM SOA 人員沙箱,并開始使用來自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的應用程序開發工具和中間件產品。
討論
- developerWorks 配置文件:現在就創建您自己的配置文件并 在 Blogger Data API 上建立一個觀看列表。
- XML 專區討論論壇:參與任何一個 XML 相關討論。
- developerWorks 中文社區:查看開發人員推動的博客、論壇、組和 wikis,并與其他 developerWorks 用戶交流。
關于作者
Deepak Vohra 是一名經過 Sun 認證的 Java 程序員和 Web 組件開發人員。Deepak 曾在 Java Developer's Journal 和 XML Journal 上發表過文章。