在 Android 3.0 平臺上創建和解析 XML

來源: ibmdeveloperworks  發布時間: 2011-11-15 17:51  閱讀: 1418 次  推薦: 0   原文鏈接   [收藏]  
摘要:Android 是最常用的智能手機平臺,它在移動平板電腦上也能發揮作用。XML 是數據交換的標準媒介。您可以對標準 XML 解析、標準 XML 轉換和 Android 使用相同的生成器、解析器和轉換器 API。借助 javax.xml.parsers.DocumentBuilder,您可以創建 org.w3c.dom.Document 對象。在本文中,將使用來自 DocumentBuilderFactory 的 DocumentBuilder 對象在 Android 設備上創建與解析 XML 文檔。您將使用 XML pull 解析器的擴展來解析 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,可擴展標記語言
  1. 安裝 Eclipse IDE。
  2. 安裝針對 Eclipse 的 Android Development Tools (ADT)插件,它提供一組在 Eclipse 中開發 Android 應用程序的擴展。
  3. 下載并安裝 Android SDK Platform,它提供用于開發 Android 應用程序的工具。
  4. 選擇 Window > Android SDK 和 AVD Manager,在 Eclipse 中啟動 Android SDK 和 AVD Manager。
  5. 在 Android SDK 和 AVD Manager 中創建一個 Android Virtual Device (AVD),它是 Android 的模擬器。

    請為 AVD 選擇 Platform 3.0 和 API 11。

  創建一份 XML 文檔

  在這一節中,您將在 Android 上創建一份 XML 文檔。第一步是創建一個 Android 項目。

  1. 在 Eclipse IDE 中選擇 File > New。在 New 對話框中,選擇 Android > Android Project。然后單擊 Next。
  2. 在 New Android Project 窗口中,如 圖 1中所示,指定:
    • 項目名稱:CreatingXML
    • “構建目標” 復選框:Android Platform 3.0 和 API 11
    • 屬性:
      • 應用程序名稱:CreatingXML
      • 包名稱 :android.xml
      • 選擇創建活動:活動類 (CreatingXML)。一個活動代表一次用戶交互。該類擴展了 Activity 類,為 UI 創建了一個窗口。
      • 最低 SDK 版本:11

    圖 1. 為平臺 3.0 創建一個 Android 項目

  3. 單擊 Next。
  4. 單擊 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 為 xmlresultTextView 元素,以顯示 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-filteraction。清單 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 方法設置根元素上的 publisherjournal 屬性。
  清單 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 顯示了 ActivityCreatingXML
  清單 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 文檔。

  1. 在 Eclipse IDE 中選擇 File > New。在 New 對話框中,選擇 Android > Android Project。然后單擊 Next。
  2. 在 New Android Project 窗口中,如 圖 6中一樣指定:
    • 項目名稱:ParsingXML
    • “構建目標” 復選框:Android Platform 3.0 與 API 11。
    • 屬性:
      • 應用程序名稱:ParsingXML
      • 包名稱:android.xml
      • 選擇 “創建活動”:Activity 類 (ParsingXML)
      • 最低 SDK 版本:11

    圖 6. 創建一個 Android 項目來解析 XML 文檔

  3. 單擊 Finish。

    這樣就創建好了一個 Android 項目,它包含以下內容:

    • 一個 ActivityParsingXML
    • 一個 res/layout/main.xml 布局文件
    • 一個 AndroidManifest.xml 應用程序配置文件

  解析 XML 文檔并使用標簽輸出元素值,將標簽與元素文本節點值輸出到 TextView 小部件上。

  1. 在 main.xml 文件中,為每個標簽和元素文本節點值添加一個 TextView 小部件。
  2. 創建一個 LinearLayout 并將 android:orientation 設置為 "vertical"
  3. 添加具有以下 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
  • 使用活動元素與子元素指定 activityintent-filteraction

  清單 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 文檔創建一個目錄。

  1. 在 res 目錄中創建一個名為 xml 的目錄,然后將 XML 文檔復制到 res/xml 目錄中。
  2. ParsingXML活動類中,導入 android.content.res.XmlResourceParser 和 org.xmlpull.v1.XmlPullParser 接口。

    啟動活動時調用了 onCreate(Bundle savedInstanceState) 方法。

  3. onCreate 方法中,使用 setContentView 方法和布局資源設置 UI,比如: setContentView(R.layout.main);
  4. 使用 findViewById 方法與小部件 id 獲取 main.xml 文件中定義的 Android TextView 小部件,如 清單 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_TAGTEXT 事件類型,它們分別對應于元素開始標簽與元素文本節點。您首先要確定元素標簽,然后獲得元素標簽的文本節點值。使用 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 小部件上的屬性值。可以使用 XmlResourceParsergetAttributeValue() 方法來獲得屬性值,如 清單 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 小部件上設置文本節點值。可以使用 elemtextString 變量來獲得元素標簽名稱,該變量是為事件類型 START_TAG 設置的。使用 XmlResourceParsergetText() 方法獲得文本節點值。使用 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 顯示了 ActivityParsingXML
  清單 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 文檔節點值
Screen capture of the formatted XML Document node values

  結束語

  您可以在 Android 3.0 平臺上創建與解析 XML 文檔,該平臺既適用于智能手機,也適用于移動平板電腦。在本文中的示例中,您在 Android 上使用了標準的 DocumentBuilderTransformer API 來創建 XML 文檔。您應該已經學會了如何使用 XMLResourceParser(它擴展了 XmlPullParser)來解析 XML 文檔。

  參考資料

  學習

  獲得產品和技術

  討論

  關于作者

  Deepak Vohra 是一名經過 Sun 認證的 Java 程序員和 Web 組件開發人員。Deepak 曾在 Java Developer's Journal 和 XML Journal 上發表過文章。

 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()