2012年11月22日木曜日

XMLデータの読み込み


テキストボックスに入力したIDの地域の明日の天気を表示します。
天気の情報はXMLで記述されています。
XMLの仕様、IDと地域の対応表、XMLデータをどこから取得するかは、livedoor の「お天気Webサービス仕様」に詳細な説明があります。
http://weather.livedoor.com/weather_hacks/webservice.html

XmlDocument インスタンスを生成して、Webから取得したXML文字列をロードします。

XmlDocument doc = new XmlDocument();
doc.LoadXml(content);

XPathでそれぞれの要素を特定して情報を取得しています。
最高気温の摂氏の数値が格納されている要素は、「temerature要素の子のmax要素の子のcelsieus要素」なので、「//temperature/max/celsius」となります。
先頭の「//temperature」は、すべてのtemperature要素をあらわしますが、XMLドキュメント中に存在するtemperature要素は高々1つで、その子のmax要素とさらにその子のcelsius要素も1回ずつしか出現しないので、このXPathで取得できるノードは1つに特定されます。
XmlElement maxXe = (XmlElement)doc.SelectSingleNode("//temperature/max/celsius");


MainWindow.xaml

<Window x:Class="ReadXml.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="明日の天気"  Height="170" Width="220">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <DockPanel Grid.Row="0" LastChildFill="True">
            <Button DockPanel.Dock="Right" Click="cancelButton_Click">×</Button>
            <Button DockPanel.Dock="Right" Click="Button_Click">Get</Button>
            <TextBox DockPanel.Dock="Right" Name="cityTextBox" />
        </DockPanel>
        <TextBox Grid.Row="1" Name="contentTextBox" />
        <StatusBar Grid.Row="2">
            <TextBlock Name="logTextBlock" />
        </StatusBar>
    </Grid>
</Window>


MainWindow.xaml.cs


using System.Net.Http;
using System.Threading.Tasks;
using System.Windows;
using System.Xml;

namespace ReadXml
{
    public partial class MainWindow : Window
    {
        private HttpClient client = new HttpClient();

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.client.CancelPendingRequests();
            string city = this.cityTextBox.Text;
            string url = "http://weather.livedoor.com/forecast/webservice/rest/v1?day=tomorrow&city=" + city;
            this.logTextBlock.Text = "取得中";
            this.client.GetStringAsync(url).ContinueWith(
                task => ReadXml(task),
                TaskScheduler.FromCurrentSynchronizationContext());
        }

        private void ReadXml(Task<string> task)
        {
            string content = task.Result;
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(content);
            XmlElement locationXe = (XmlElement)doc.SelectSingleNode("//location");
            XmlElement telopXe = (XmlElement)doc.SelectSingleNode("//telop");
            XmlElement maxXe = (XmlElement)doc.SelectSingleNode("//temperature/max/celsius");
            XmlElement minXe = (XmlElement)doc.SelectSingleNode("//temperature/min/celsius");
            string outputString =
                locationXe.Attributes["area"].Value + " / " +
                locationXe.Attributes["pref"].Value + " / " +
                locationXe.Attributes["city"].Value +
                "\n" + telopXe.InnerText +
                "\n最高気温:" + maxXe.InnerText +
                "\n最低気温:" + minXe.InnerText;

            this.contentTextBox.Text = outputString;
            this.logTextBlock.Text = "完了";
        }

        private void cancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.client.CancelPendingRequests();
            this.logTextBlock.Text = "キャンセル";
        }
    }
}


0 件のコメント:

コメントを投稿