日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

【Android Developers Training】 81. 解析XML数据

發布時間:2023/12/2 Android 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android Developers Training】 81. 解析XML数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由于喜愛安卓而產生了翻譯的念頭,純屬個人興趣愛好。

原文鏈接:http://developer.android.com/training/basics/network-ops/xml.html


可擴展標記語言(XML)是一種將文檔編碼為機器可閱讀的形式的規則集合。XML是一種在互聯網中分享數據的比較流行的格式。那些頻繁更新內容的網站(如新的站點或者博客),經常會提供一個XML源,這樣外部程序就可以與內容變更保持同步。上傳及解析XML數據對于需要聯網的應用來說是一個很平常的任務。這節課將講解如何解析XML文檔并使用它們的數據。


一). 選擇一個解析器

我們推薦使用XmlPullParser,它是一個在Android上解析XML的一種比較有效及穩定的方法。歷史中Android有兩種實現該接口的方法:

  • 通過XmlPullParserFactory.newPullParser()實現的KXmlParser。
  • 通過Xml.newPullParser()實現的ExpatPullParser。

每一種選擇都是可以的。不過這里我們使用第二個例子。?


二). 分析源

解析源的第一步是決定哪些字段是你感興趣的。解析器會提取這些你感興趣的字段數據并把其余的忽略。

下面是在應用中被解析的源的一段摘錄。每一個到StackOverflow.com的推送都會在源中顯示為一個entry標簽,并包含若干entry子標簽:

<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" ..."> <title type="text">newest questions tagged android - Stack Overflow</title> ...<entry>...</entry><entry><id>http://stackoverflow.com/q/9439999</id><re:rank scheme="http://stackoverflow.com">0</re:rank><title type="text">Where is my data file?</title><category scheme="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest/tags" term="android"/><category scheme="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest/tags" term="file"/><author><name>cliff2310</name><uri>http://stackoverflow.com/users/1128925</uri></author><link rel="alternate" href="http://stackoverflow.com/questions/9439999/where-is-my-data-file" /><published>2012-02-25T00:30:54Z</published><updated>2012-02-25T00:30:54Z</updated><summary type="html"><p>I have an Application that requires a data file...</p></summary></entry><entry>...</entry> ... </feed>

應用會提取會提取entry標簽及其子標簽:titlelinksummary子標簽的數據。


三). 初始化解析器

下一步是初始化解析器,并啟動解析的步驟。在下面的代碼片段中,一個不處理命名空間的解析器被初始化,并使用InputStream作為參數。通過調用nextTag()開始解析的步驟,并激活readFeed()方法,該方法提取并處理應用感興趣的數據:

public class StackOverflowXmlParser {// We don't use namespacesprivate static final String ns = null;public List parse(InputStream in) throws XmlPullParserException, IOException {try {XmlPullParser parser = Xml.newPullParser();parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);parser.setInput(in, null);parser.nextTag();return readFeed(parser);} finally {in.close();}}... }

四). 閱讀源

readFeed()方法執行一些工作來處理源。它尋找entry標簽作為開始遞歸處理的起始點。如果一個標簽不是entry標簽,那么就忽略它。一點整個源都被遞歸處理完了,readFeed()方法返回一個包含它從源中提取的字段的List(包含子數據成員)。該List被解析器返回。

private List readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {List entries = new ArrayList();parser.require(XmlPullParser.START_TAG, ns, "feed");while (parser.next() != XmlPullParser.END_TAG) {if (parser.getEventType() != XmlPullParser.START_TAG) {continue;}String name = parser.getName();// Starts by looking for the entry tagif (name.equals("entry")) {entries.add(readEntry(parser));} else {skip(parser);}} return entries; }

五). 解析XML

解析一個XML源的步驟如下:

  • 如第二節中所述,在你的應用中標識出你希望包含的標簽。該例子中提取的數據為entry標簽及其子標簽:titlelinksummary子標簽的數據。
  • 創建下列方法:
      • 為每個你感興趣的標簽創建“read”方法。例如,readEntry(),readTitle()等。解析器從輸入流中讀取標簽。當它遇到了名為entry,title,link或summary時,它會為標簽調用相應的方法。否則就略過該標簽。
      • 為每個不同類型標簽提取數據并將解析器推進到下一個標簽的方法。例如:
        • 對于title和summary標簽,解析器調用readText()。該方法提取通過調用parser.getText(),從這些標簽中提取數據。
        • 對于link標簽,解析器首先確定該link是否是自己感興趣的,如果是的話就調用parser.getAttributeValue()來提取它的值。
        • 對于entry標簽,解析器會調用readEntry()。該方法解析entry中的子標簽,并返回一個Entry對象,其中包含了數據成員:title,link和summary。
      • 一個用以輔助的方法skip()。更多信息可以閱讀:Skip Tags You Don't Care About。

    下列代碼片段展示了如何解析上述標簽:

    public static class Entry {public final String title;public final String link;public final String summary;private Entry(String title, String summary, String link) {this.title = title;this.summary = summary;this.link = link;} }// Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them off // to their respective "read" methods for processing. Otherwise, skips the tag. private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {parser.require(XmlPullParser.START_TAG, ns, "entry");String title = null;String summary = null;String link = null;while (parser.next() != XmlPullParser.END_TAG) {if (parser.getEventType() != XmlPullParser.START_TAG) {continue;}String name = parser.getName();if (name.equals("title")) {title = readTitle(parser);} else if (name.equals("summary")) {summary = readSummary(parser);} else if (name.equals("link")) {link = readLink(parser);} else {skip(parser);}}return new Entry(title, summary, link); }// Processes title tags in the feed. private String readTitle(XmlPullParser parser) throws IOException, XmlPullParserException {parser.require(XmlPullParser.START_TAG, ns, "title");String title = readText(parser);parser.require(XmlPullParser.END_TAG, ns, "title");return title; }// Processes link tags in the feed. private String readLink(XmlPullParser parser) throws IOException, XmlPullParserException {String link = "";parser.require(XmlPullParser.START_TAG, ns, "link");String tag = parser.getName();String relType = parser.getAttributeValue(null, "rel"); if (tag.equals("link")) {if (relType.equals("alternate")){link = parser.getAttributeValue(null, "href");parser.nextTag();} }parser.require(XmlPullParser.END_TAG, ns, "link");return link; }// Processes summary tags in the feed. private String readSummary(XmlPullParser parser) throws IOException, XmlPullParserException {parser.require(XmlPullParser.START_TAG, ns, "summary");String summary = readText(parser);parser.require(XmlPullParser.END_TAG, ns, "summary");return summary; }// For the tags title and summary, extracts their text values. private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {String result = "";if (parser.next() == XmlPullParser.TEXT) {result = parser.getText();parser.nextTag();}return result; }... }

    六). 跳過你不關注的標簽

    上面所描述的解析XML步驟中,其中有一步是解析器跳過我們不關注的標簽。下面是skip()方法的代碼:

    private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {if (parser.getEventType() != XmlPullParser.START_TAG) {throw new IllegalStateException();}int depth = 1;while (depth != 0) {switch (parser.next()) {case XmlPullParser.END_TAG:depth--;break;case XmlPullParser.START_TAG:depth++;break;}}}

    它為何這樣就能實現跳過的功能呢:

    • 如果當前遇到的不是START_TAG,那么拋出一個異常。
    • 它接收START_TAG,以及之后遇到的內容,并匹配END_TAG。
    • 為了確保它在正確的END_TAG停止,而不是在START_TAG之后遇到的第一個標簽,它會一直向子標簽深度搜索。

    因此如果當前標簽含有子標簽,那么depth的值不會變成0,直到解析器處理了所有在原始的START_TAG和與它匹配的END_TAG之間的所有標簽。例如,考慮該解析器如何略過<author>標簽,該標簽含有兩個子標簽<name>和<uri>:

    • 第一次while循環,解析器在<author>之后遇到了START_TAG:<name>,此時depth的值增加到2。
    • 第二次while循環,解析器遇到了END_TAG:</name>。此時depth的值減少到1。
    • 第三次while循環,解析器遇到了START_TAG:<uri>。此時depth的值增加到2。
    • 第四次while循環,解析器遇到了END_TAG:</uri>。此時depth的值減少到1。
    • 最后一次while循環,解析器遇到了END_TAG:</author>。此時depth的值減少到0,表明<author>已經被成功忽略了。

    七). 處理XML數據

    樣例代碼中,使用了AsyncTask獲取并解析XML源。這樣該過程就不會再UI主線程中執行。當處理執行完畢,應用會更新主Activity(NetworkActivity)的UI。

    在下面摘錄的代碼片段中,loadPage()方法進行了如下的處理:

    用XML源的URL初始化一個String變量。

    在用戶的設置及網絡連接允許的情況下,調用new DownloadXmlTask().execute(url)。這將初始化一個新的DownloadXmlTask對象(AsyncTask的子類)并運行它的execute()方法,它會下載并解析源并將結果以String的形式返回,顯示在UI上。?

    public class NetworkActivity extends Activity {public static final String WIFI = "Wi-Fi";public static final String ANY = "Any";private static final String URL = "http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest";// Whether there is a Wi-Fi connection.private static boolean wifiConnected = false; // Whether there is a mobile connection.private static boolean mobileConnected = false;// Whether the display should be refreshed.public static boolean refreshDisplay = true; public static String sPref = null;...// Uses AsyncTask to download the XML feed from stackoverflow.com.public void loadPage() { if((sPref.equals(ANY)) && (wifiConnected || mobileConnected)) {new DownloadXmlTask().execute(URL);}else if ((sPref.equals(WIFI)) && (wifiConnected)) {new DownloadXmlTask().execute(URL);} else {// show error } }

    AsyncTask的子類:DownloadXmlTask如下所示,它實現了下列AsyncTask的方法:

    doInBackground()執行loadXmlFromNetwork(),它將源的URL作為參數傳入。loadXmlFromNetwork()方法獲取并處理源。當它結束以后,它會返回String作為結果。

    onPostExecute()接收結果String并將它顯示在UI上。

    // Implementation of AsyncTask used to download XML feed from stackoverflow.com. private class DownloadXmlTask extends AsyncTask<String, Void, String> {@Overrideprotected String doInBackground(String... urls) {try {return loadXmlFromNetwork(urls[0]);} catch (IOException e) {return getResources().getString(R.string.connection_error);} catch (XmlPullParserException e) {return getResources().getString(R.string.xml_error);}}@Overrideprotected void onPostExecute(String result) { setContentView(R.layout.main);// Displays the HTML string in the UI via a WebViewWebView myWebView = (WebView) findViewById(R.id.webview);myWebView.loadData(result, "text/html", null);} }

    下面是方法:loadXmlFromNetwork(),它被DownloadXmlTask調用,它執行下列任務:

    • 初始化一個StackOverflowXmlParser,它也創建一個裝載entry對象的List(entries),以及title,url,和summary,來存儲從XML源中相應字段里提取出的數據。
    • 調用downloadUrl(),它獲取源并以InputStream的形式返回
    • 使用StackOverflowXmlParser來解析InputStream。StackOverflowXmlParser會用源中的數據填充entries這個List。
    • 處理List,并將源數據和HTML標記向結合。
    • 返回HTML字符串,由AsyncTask的onPostExecute()方法將它顯示在主Activity UI上的。
    // Uploads XML from stackoverflow.com, parses it, and combines it with // HTML markup. Returns HTML string. private String loadXmlFromNetwork(String urlString) throws XmlPullParserException, IOException {InputStream stream = null;// Instantiate the parserStackOverflowXmlParser stackOverflowXmlParser = new StackOverflowXmlParser();List<Entry> entries = null;String title = null;String url = null;String summary = null;Calendar rightNow = Calendar.getInstance(); DateFormat formatter = new SimpleDateFormat("MMM dd h:mmaa");// Checks whether the user set the preference to include summary textSharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);boolean pref = sharedPrefs.getBoolean("summaryPref", false);StringBuilder htmlString = new StringBuilder();htmlString.append("<h3>" + getResources().getString(R.string.page_title) + "</h3>");htmlString.append("<em>" + getResources().getString(R.string.updated) + " " + formatter.format(rightNow.getTime()) + "</em>");try {stream = downloadUrl(urlString); entries = stackOverflowXmlParser.parse(stream);// Makes sure that the InputStream is closed after the app is// finished using it.} finally {if (stream != null) {stream.close();} }// StackOverflowXmlParser returns a List (called "entries") of Entry objects.// Each Entry object represents a single post in the XML feed.// This section processes the entries list to combine each entry with HTML markup.// Each entry is displayed in the UI as a link that optionally includes// a text summary.for (Entry entry : entries) { htmlString.append("<p><a href='");htmlString.append(entry.link);htmlString.append("'>" + entry.title + "</a></p>");// If the user set the preference to include summary text,// adds it to the display.if (pref) {htmlString.append(entry.summary);}}return htmlString.toString(); }// Given a string representation of a URL, sets up a connection and gets // an input stream. private InputStream downloadUrl(String urlString) throws IOException {URL url = new URL(urlString);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setReadTimeout(10000 /* milliseconds */);conn.setConnectTimeout(15000 /* milliseconds */);conn.setRequestMethod("GET");conn.setDoInput(true);// Starts the query conn.connect();return conn.getInputStream(); }

    轉載于:https://www.cnblogs.com/jdneo/p/3612892.html

    總結

    以上是生活随笔為你收集整理的【Android Developers Training】 81. 解析XML数据的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 日本一本在线视频 | 久久亚 | 污污视频网站在线免费观看 | 色在线免费观看 | 91久久精品www人人做人人爽 | 九色porny原创自拍 | av网在线播放 | 狠色综合7777夜色撩人 | 亚洲国产精品二区 | 亚洲精品免费在线 | 波多野结衣在线观看一区 | 人人干人人做 | 亚洲最大中文字幕 | 激情小说五月天 | 四虎图库 | 精品少妇人妻av免费久久洗澡 | 成人免费直播 | 久久大奶 | 欧美日韩91 | 国内老熟妇对白xxxxhd | 亚洲伦理天堂 | 东京热无码av一区二区 | 爱上av| 五月婷中文字幕 | 日韩久久高清 | 67194在线免费观看 | 欧美色性视频 | 精品亚洲永久免费精品 | 特黄特色大片免费播放器使用方法 | 久久久久噜噜噜亚洲熟女综合 | 欧美日韩18 | 亚洲中文字幕久久无码 | 欧美色图在线播放 | 亚洲一区二区三区在线 | 亚洲一区二区三区在线视频观看 | 天天干天天添 | 黄色在线网 | 人人射视频| 黑人无套内谢中国美女 | 国产精品黄 | 亚洲h片| 91黄色大片| 亚洲麻豆| 91全免费 | 99国产在线视频 | 欧美一级免费 | 两根大肉大捧一进一出好爽视频 | 亚洲欧美久久 | 国产片在线播放 | 欧美黄色录像带 | 国产丝袜一区二区 | 一区二区三区四区高清视频 | 波多野结衣爱爱 | 亚洲一区二区三区四区在线观看 | 秋霞7777鲁丝伊人久久影院 | 亚洲欲妇 | 欧美三级午夜理伦三级小说 | 国产成人愉拍精品久久 | 懂色av一区二区三区在线播放 | japanese24hdxxxx中文字幕 | 色女人av | 狠狠鲁视频 | 日本三级少妇 | 亚洲干干干 | 不用播放器av | 亚洲色p| 涩涩视频免费在线观看 | 在线观看日韩精品 | 一区二区三区精品久久久 | 国产乱国产乱老熟 | 男人天堂亚洲天堂 | 久久精品视频18 | 欧美日韩高清一区二区三区 | 黄色在线网 | 国产一区二区视频在线观看免费 | 亚洲AV无码国产成人久久 | 91精品久久久久久综合五月天 | 国产超碰91 | 99久热在线精品996热是什么 | 一曲二曲三曲在线观看中文字幕动漫 | 久久久久亚洲AV成人无在 | 成人91免费视频 | 噜噜噜久久 | 成人区人妻精品一区二区不卡视频 | 精品人妻一区二区三区视频 | 免费一级suv好看的国产网站 | 申鹤乳液狂飙 | 国内精品久久久久久久影视简单 | 韩国美女啪啪 | 午夜爽视频 | 熟妇毛片| 性欧美最猛 | 天天av综合| av片免费看 | 国产日韩欧美视频在线 | 欧美熟妇另类久久久久久不卡 | 欧美日韩四区 | 亚洲国产aaa | 亚洲精品白虎 |