iT邦幫忙

DAY 20
5

Windows Phone 程式開發系列 第 17

[WP 開發] 文化部資料開放服務網 App 開發 (1) 讀取資料

在台灣有很多公開服務平台,讓您可以獲取想要的資料,像是臺北市政府資料開放平台,文化部資料開放服務網等。
其中文化部資料開放服務網提供了 EXCEL、XML、JSON 三種格式,本文將撰寫一個程式讀取文化部資料開放服務網文化設施-公共藝術的 XML 資料。

本文刊載於
http://www.dotblogs.com.tw/chou/archive/2013/10/07/123392.aspx

在這篇文章您可以學到:

  1. 文化部資料開放服務網格式。
  2. 下載與分析資料,顯示於 Windows Phone 中。

實作
首先連結到 [文化部資料開放服務網],切換到文化設施-公共藝術中,可以看到包含三種格式 :

其中 XML 的網址 :
http://cloud.culture.tw/frontsite/trans/emapOpenDataAction.do?method=exportEmapXML&typeId=F

新增專案 Panorama,首先先針對 XML 檔案修改 ItemViewModel.cs

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace PanoramaApp1
{
    public class ItemViewModel : INotifyPropertyChanged
    {
        private string _Name;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Name
        {
            get
            {
                return _Name;
            }
            set
            {
                if (value != _Name)
                {
                    _Name = value;
                    NotifyPropertyChanged("Name");
                }
            }
        }

        private string _RepresentImage;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string RepresentImage
        {
            get
            {
                return _RepresentImage;
            }
            set
            {
                if (value != _RepresentImage)
                {
                    _RepresentImage = value;
                    NotifyPropertyChanged("RepresentImage");
                }
            }
        }

        private string _Intro;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Intro
        {
            get
            {
                return _Intro;
            }
            set
            {
                if (value != _Intro)
                {
                    _Intro = value;
                    NotifyPropertyChanged("Intro");
                }
            }
        }

        private string _AreaCode;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string AreaCode
        {
            get
            {
                return _AreaCode;
            }
            set
            {
                if (value != _AreaCode)
                {
                    _AreaCode = value;
                    NotifyPropertyChanged("AreaCode");
                }
            }
        }

        private string _Address;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Address
        {
            get
            {
                return _Address;
            }
            set
            {
                if (value != _Address)
                {
                    _Address = value;
                    NotifyPropertyChanged("Address");
                }
            }
        }

        private string _Longitude;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Longitude
        {
            get
            {
                return _Longitude;
            }
            set
            {
                if (value != _Longitude)
                {
                    _Longitude = value;
                    NotifyPropertyChanged("Longitude");
                }
            }
        }

        private string _Latitude;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Latitude
        {
            get
            {
                return _Latitude;
            }
            set
            {
                if (value != _Latitude)
                {
                    _Latitude = value;
                    NotifyPropertyChanged("Latitude");
                }
            }
        }

        private string _BuildingYearName;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string BuildingYearName
        {
            get
            {
                return _BuildingYearName;
            }
            set
            {
                if (value != _BuildingYearName)
                {
                    _BuildingYearName = value;
                    NotifyPropertyChanged("BuildingYearName");
                }
            }
        }

        private string _Author;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Author
        {
            get
            {
                return _Author;
            }
            set
            {
                if (value != _Author)
                {
                    _Author = value;
                    NotifyPropertyChanged("Author");
                }
            }
        }

        private string _Size;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Size
        {
            get
            {
                return _Size;
            }
            set
            {
                if (value != _Size)
                {
                    _Size = value;
                    NotifyPropertyChanged("Size");
                }
            }
        }

        private string _Material;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Material
        {
            get
            {
                return _Material;
            }
            set
            {
                if (value != _Material)
                {
                    _Material = value;
                    NotifyPropertyChanged("Material");
                }
            }
        }

        private string _MainTypeName;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string MainTypeName
        {
            get
            {
                return _MainTypeName;
            }
            set
            {
                if (value != _MainTypeName)
                {
                    _MainTypeName = value;
                    NotifyPropertyChanged("MainTypeName");
                }
            }
        }

        private string _CityName;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string CityName
        {
            get
            {
                return _CityName;
            }
            set
            {
                if (value != _CityName)
                {
                    _CityName = value;
                    NotifyPropertyChanged("CityName");
                }
            }
        }

        private string _GroupTypeName;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string GroupTypeName
        {
            get
            {
                return _GroupTypeName;
            }
            set
            {
                if (value != _GroupTypeName)
                {
                    _GroupTypeName = value;
                    NotifyPropertyChanged("GroupTypeName");
                }
            }
        }

        private string _MainTypePk;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string MainTypePk
        {
            get
            {
                return _MainTypePk;
            }
            set
            {
                if (value != _MainTypePk)
                {
                    _MainTypePk = value;
                    NotifyPropertyChanged("MainTypePk");
                }
            }
        }

        private string _Version;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Version
        {
            get
            {
                return _Version;
            }
            set
            {
                if (value != _Version)
                {
                    _Version = value;
                    NotifyPropertyChanged("Version");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

在 MainViewModel.cs 進行資料下載以及將資料填入 Items 中。

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Net;
using System.IO;
using HtmlAgilityPack;
using System.Linq;
using System.Xml.Linq;

namespace PanoramaApp1
{
    public class MainViewModel : INotifyPropertyChanged
    {
        public MainViewModel()
        {
            Items = new ObservableCollection<ItemViewModel>();
        }

        /// <summary>
        /// A collection for ItemViewModel objects.
        /// </summary>
        public static ObservableCollection<ItemViewModel> Items { get; private set; }

        private string _sampleProperty = "Sample Runtime Property Value";
        /// <summary>
        /// Sample ViewModel property; this property is used in the view to display its value using a Binding
        /// </summary>
        /// <returns></returns>
        public string SampleProperty
        {
            get
            {
                return _sampleProperty;
            }
            set
            {
                if (value != _sampleProperty)
                {
                    _sampleProperty = value;
                    NotifyPropertyChanged("SampleProperty");
                }
            }
        }

        public bool IsDataLoaded
        {
            get;
            private set;
        }

        public void LoadData()
        {
            HttpWebRequest request =
                (HttpWebRequest)WebRequest.Create("http://cloud.culture.tw/frontsite/trans/emapOpenDataAction.do?method=exportEmapXML&typeId=F");
            request.BeginGetResponse(new AsyncCallback(GetHttpDocumentCallback), request);

            this.IsDataLoaded = true;
        }

        private static void GetHttpDocumentCallback(IAsyncResult res)
        {

            HttpWebRequest request = (HttpWebRequest)res.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(res);
            using (var reader = new StreamReader(response.GetResponseStream()))
            {

                var resultStream = reader.ReadToEnd();
                XDocument resdoc = XDocument.Parse(resultStream.Trim());
                var newsitems = from newsitem in resdoc.Descendants("Info")
                                select new ItemViewModel
                                {
                                    Name = newsitem.Attribute("name") == null ? string.Empty : newsitem.Attribute("name").Value,
                                    RepresentImage = newsitem.Attribute("representImage") == null ? string.Empty : newsitem.Attribute("representImage").Value,
                                    Intro = newsitem.Attribute("intro") == null ? string.Empty : newsitem.Attribute("intro").Value,
                                    AreaCode = newsitem.Attribute("areaCode") == null ? string.Empty : newsitem.Attribute("areaCode").Value,
                                    Address = newsitem.Attribute("address") == null ? string.Empty : newsitem.Attribute("address").Value,
                                    Longitude = newsitem.Attribute("longitude") == null ? string.Empty : newsitem.Attribute("longitude").Value,
                                    Latitude = newsitem.Attribute("latitude") == null ? string.Empty : newsitem.Attribute("latitude").Value,
                                    BuildingYearName = newsitem.Attribute("buildingYearName") == null ? string.Empty : newsitem.Attribute("buildingYearName").Value,
                                    Author = newsitem.Attribute("author") == null ? string.Empty : newsitem.Attribute("author").Value,
                                    Size = newsitem.Attribute("size") == null ? string.Empty : newsitem.Attribute("size").Value,
                                    Material = newsitem.Attribute("material") == null ? string.Empty : newsitem.Attribute("material").Value,
                                    MainTypeName = newsitem.Attribute("mainTypeName") == null ? string.Empty : newsitem.Attribute("mainTypeName").Value,
                                    CityName = newsitem.Attribute("cityName") == null ? string.Empty : newsitem.Attribute("cityName").Value,
                                    GroupTypeName = newsitem.Attribute("groupTypeName") == null ? string.Empty : newsitem.Attribute("groupTypeName").Value,
                                    MainTypePk = newsitem.Attribute("mainTypePk") == null ? string.Empty : newsitem.Attribute("mainTypePk").Value,
                                    Version = newsitem.Attribute("version") == null ? string.Empty : newsitem.Attribute("version").Value,
                                };

                // System.Diagnostics.Debug.WriteLine("共" + newsitems.Count() + "筆"); 

                Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    foreach (var i in newsitems)
                    {
                        Items.Add(i);
                    }
                    
                }));
            }
        }
        
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

以設計模式開啟 MainPage.cs,將 Items 資料綁定在控制項。

執行程式。


上一篇
[WP 開發] 以多國語言做為開發前提 (2) 變數和圖片多國語言
下一篇
[WP 開發] 文化部資料開放服務網 App 開發 (2) 地圖
系列文
Windows Phone 程式開發27

1 則留言

我要留言

立即登入留言