天天看點

WindowsPhone中XML和Json格式的資料解析

        由于WindowsPhone的沙箱機制,緻使關系型資料庫無法很好的在WindowsPhone手機中大行其道,此外,大型的資料庫一方面打破了WindowsPhone的沙箱機制,破壞了系統的嚴密、安全性,可能會帶來一些意想不到的危害,另一方面資料庫服務的開啟會一直占用系統的記憶體。但有時候有些應用卻又需要存儲大量的資料,這個時候XML的優勢就展現的淋漓盡緻了,此外一些WebService傳回的結果大都也是XML格式或者Json格式的資料,這時候就要用到XML或者Json解析傳回的資料,這便是本文的初衷。

先來講一下XML解析本地的資料,

一、首先應在目前項目下建立一個.xml檔案,例如本例的SpokenEnglish.xml檔案

檔案的格式如下:

<?xml version="1.0" encoding="utf-8" ?>

<SpokenEnglish>

  <Items>

    <Item>

      <Spoken>1. I see.</Spoken>

      <Chinese>我明白了。</Chinese>

    </Item>

    <Item>

      <Spoken>2. I quit!</Spoken>

      <Chinese>我不幹了! </Chinese>

    </Item>

    <Item>

      <Spoken>3. Let go! </Spoken>

      <Chinese>放手! </Chinese>

    </Item>

    <Item>

      <Spoken>4. Me too.</Spoken>

      <Chinese>我也是。</Chinese>

    </Item>

    <Item>

      <Spoken>5. My god!</Spoken>

      <Chinese>天哪!</Chinese>

    </Item>

</Items>

</SpokenEnglish>

這是本地的資料存儲檔案

下邊再建一個與源資料相映射的類:SpokenEnglishes.cs

如下:

在使用之前應先加入以下命名空間

using System.Collections.Generic;//對應List<T>泛型集合

using System.Linq;//對應Element.load().Select();

using System.Xml.Linq;//對應XDocument

namespace XMLAndJSON       

{

    public class SpokenEnglishes

    {

        public static readonly string xmlPath;//資料檔案的路徑

        public string Spoken

        {

            get;

            set;

        }

        public string Chinese

        {

            get;

            set;

        }

       static SpokenEnglishes()

        {

            xmlPath = @"SpokenEnglish.xml";

        }

XML解析方法一

        public static List<SpokenEnglishes> GetAllSpokenEnglishes()//擷取資料檔案中的資料,并映射為SpokenEnglishes類

        {

           return XElement.Load(xmlPath).Element("Items").Descendants("Item").Select(item => new SpokenEnglishes()

            {

                Spoken = item.Element("Spoken").Value,

                Chinese=item.Element("Chinese").Value

            }).ToList();

        }

XML解析方法二

        public static List<SpokenEnglishes> GetAll()//與上一個函數功能相同,隻不過是另一個XML解析方法

        {

            XDocument xDocument = XDocument.Load("SpokenEnglish.xml");

            return xDocument.Descendants("Item").Select(item => new SpokenEnglishes()

            {

                Chinese = item.Element("Chinese").Value,

                Spoken = item.Element("Spoken").Value

            }).ToList();

        }

    }

}

然後就是在MainPage.xaml頁進行UI的布局和資料的綁定

主要代碼如下:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

            <ListBox Height="591" HorizontalAlignment="Left" Margin="10,10,0,0" Name="listBox1" VerticalAlignment="Top"

                    Width="440" >      

                <ListBox.ItemTemplate>

                    <DataTemplate>

                        <StackPanel Orientation="Vertical">

                        <TextBlock Name="spoken" Text="{Binding Spoken}"/>//與SpokenEnglish類屬性相綁定

                        <TextBlock Text="{Binding Chinese}"/>

                        </StackPanel>

                    </DataTemplate>

                </ListBox.ItemTemplate>

            </ListBox>

        </Grid>

然後在MainPage.xaml.cs頁的構造函數裡為listbox1指定資料源

代碼如下:  listBox1.ItemsSource = SpokenEnglishes.GetAll();//靜态類SpokenEnglishes調用其GetAll()方法擷取List<SpokenEnglishes>的集合

運作效果如下:

二、用XML解析Web服務傳回的資料跟解析本地資料的方法差不多,

大體步驟如下:

1、先根據傳回的XML資料格式建立與資料互相映射的實體類:

例如:AirLine類,航班資訊類

public class AirLine1

    {

        public string Company1 { get; set; }

        public string AirLineCode1 { get; set; }

        public string StartDrome1 { get; set; }

        public string EndDrome1 { get; set; }

        public string StartTime1 { get; set; }

        public string EndTime1 { get; set; }

        public string AirLineStop1 { get; set; }

        public string Week1 { get; set; }

    }

然後在異步傳回函數中做出如下的解析:

  void airws_getDomesticAirlinesTimeCompleted(object sender, AirLineWS.getDomesticAirlinesTimeCompletedEventArgs e)

        {

            try

            {//關鍵的解析部分

                List<AirLine1> airlinelist = e.Result.Nodes.Descendants("AirlinesTime").Select(

                    item => new AirLine1()

                    {

                        Company1 = item.Element("Company").Value,

                        AirLineCode1 = item.Element("AirlineCode").Value,

                        StartDrome1 = item.Element("StartDrome").Value,

                        EndDrome1 = item.Element("ArriveDrome").Value,

                        StartTime1 = item.Element("StartTime").Value,

                        EndTime1 = item.Element("ArriveTime").Value,

                        AirLineStop1 = item.Element("AirlineStop").Value,

                        Week1 = item.Element("Week").Value

                    }).ToList();

                foreach (AirLine1 al in airlinelist)

                {

                    TextBlock t = new TextBlock();

                    t.Text = "航空公司:" + al.Company1;

                    t.FontSize = 24;

                    TextBlock t1 = new TextBlock();

                    t1.Text = "航班号:" + al.AirLineCode1;

                    t1.FontSize = 24;

                    TextBlock t2 = new TextBlock();

                    t2.Text = "出發機場:" + al.StartDrome1;

                    t2.FontSize = 24;

                    TextBlock t3 = new TextBlock();

                    t3.Text = "到達機場:" + al.EndDrome1;

                    t3.FontSize = 24;

                    TextBlock t4 = new TextBlock();

                    t4.Text = "出發時間:" + al.StartTime1;

                    t4.FontSize = 24;

                    TextBlock t5 = new TextBlock();

                    t5.Text = "到達時間:" + al.EndTime1;

                    t5.FontSize = 24;

                    TextBlock t6 = new TextBlock();

                    t6.Text = "經停:" + al.AirLineStop1 + "次";

                    t6.FontSize = 24;

                    TextBlock t7 = new TextBlock();

                    t7.Text = "飛行周期:" + al.Week1;

                    t7.FontSize = 24;

                    StackPanel sp = new StackPanel();

                    sp.Margin = new Thickness(0, 10, 0, 0);

                    sp.Width = 400;

                    sp.Children.Add(t);

                    sp.Children.Add(t1);

                    sp.Children.Add(t2);

                    sp.Children.Add(t3);

                    sp.Children.Add(t4);

                    sp.Children.Add(t5);

                    sp.Children.Add(t6);

                    sp.Children.Add(t7);

                    stackPanel1.Children.Add(sp);

                }

            }

            catch (Exception ee)

            {

                MessageBox.Show("很抱歉,找不到您所要查詢的資訊,請稍後再試");

            }

        }

這個例子是一個航班查詢的實力,在使用之前需要先添加WebService 服務,這裡主要是講XML存儲本地資料和解析,是以對于web應用友善就不多講了,如果有需要源碼的朋友可以給我留個郵箱,到時發到你們郵箱。

運作的效果圖:

三、資料的序列化和反序列化

1、序列化:

     事先寫好一個類例如:

People類

public class People

{

   string Name{get;set;}

   string Address{get;set;}

}

static void Main(string[] args)

        {

            var people = new People()

            {

                Name = “Olive",

                Address="北京"

            };

序列化:

            //序列化将序列化People類的執行個體寫入記憶體流中,需要引入using System.Runtime.Serialization;命名空間

            var serializer = new DataContractJsonSerializer(typeof(People));

            var stream = new MemoryStream();

            serializer.WriteObject(stream, people);

            //從記憶體流中中讀到string中,即生成Json

            byte[] dataBytes = new byte[stream.Length];

            stream.Position = 0;

            stream.Read(dataBytes, 0,(int) stream.Length);

            string dataString = Encoding.UTF8.GetString(dataBytes);

            Console.WriteLine(dataString);//即:序列化之後的Json格式的字元串

            Console.ReadLine();

反序列化:

           //反序列化先将json格式的字元串讀入到記憶體中,然後在經過反序列化成類的對象

            var mStream = new MemoryStream(Encoding.UTF8.GetBytes(dataString));

            DataContractJsonSerializer dcJoson = new DataContractJsonSerializer(typeof(People));

            People pp=(People) dcJoson.ReadObject(mStream);

            Console.WriteLine(pp.Name);//輸入People類對象的Name屬性

            Console.ReadLine();

        }

序列化和反序列化主要用到了using System.Runtime.Serialization;命名空間下的 DataContractJsonSerializer類的兩個執行個體方法

WirteObject()和ReadObject()

在WindowsPhone中解析Json需要同時加入using System.Runtime.Serialization;命名空間和System.Servicemodel.Web命名空間

其解析方法和桌面程式解析差不多,

主要是在異步回調函數中将傳回的字元串進行解析,先建立和傳回資料相映射的類,然後在用DataContractJsonSerilzer類的執行個體方法

ReadObject()将傳回資料反序列化為類的執行個體。