SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ASP.NET Core Blazorチュートリアル

ASP.NET CoreでホストされたBlazorアプリを公開する

ASP.NET Core Blazorチュートリアル 第5回

  • X ポスト
  • このエントリーをはてなブックマークに追加

気象情報XMLを処理して天気予報を表示する

 それでは、気象情報のXMLを処理していきましょう。

気象情報XMLのURLを取得する

 まずは、Atomフィードの処理です。Atomフィードといっても、XMLファイルなので、やることはXMLファイルの処理と同様となります。

 XMLファイルを扱う方法として、すべて読み込んでから処理する方法(DOM)と、先頭から読み込んで要素毎に処理する方法(SAX)、という2つの方法が一般的です。ただし、.NETでは、LINQ(LINQ to XML)という機能も利用できます。LINQでは、データベースのSQL的な問い合わせ構文で、コレクションやXMLファイルなどを扱えます。

 今回は、C#言語内でXMLが操作できるLINQ to XMLを利用して、Atomフィードを処理するようにしました。指定された府県コードの天気予報XMLファイルのURLを抽出するコードは、次のようになります。

[リスト1]JmaController.cs
// 指定された府県コードの天気予報XMLファイルのURLを取得する
public string GetUrl(string code)
{
    // Atomフィードの読み込み(1)
    var xml = XElement.Load(AtomフィードのURL);

    // 名前空間の取得(2)
    var nspace = xml.Name.Namespace;

    // LINQ(クエリ式)で該当のURLを抽出する(3)
    var urls =
        from item in xml.Descendants(nspace + "id")
        where item.Value.Contains("VPFD51_" + code)
        orderby item.Value descending
        select item.Value;

    // データがあれば先頭のデータを返す(4)
    return urls.Any() ? urls.First() : null;
}

 LINQ to XMLで提供されるクラスは、System.Xml.Linq名前空間で定義されています。ここでは、XElementクラスを使って、XMLファイルを読み込んでいます(1)。XElementクラスは、LINQ to XMLのベースとなるクラスのひとつで、XML要素の作成や変更、追加、削除などが行えます。XElementクラスのLoadメソッドは、XMLファイルのルート要素を示すXElementオブジェクトを返します。またLoadメソッドは、ローカルのファイルだけでなく、ここでの例のように外部サイトにあるファイルも指定可能です。

 次に、XML名前空間を取得します(2)。Atomフィードのルート要素である<feed>要素には、xmlns属性で、XML名前空間が宣言されています。これが定義されている場合、LINQ to XMLで要素を指定する際には、要素名にXML名前空間を付加する必要があります。

 (3)のコードが、LINQを使ったコードになります。今回は、LINQのクエリ式と呼ばれる記法としています。fromキーワードで、列挙型などのシーケンスデータを指定し、inキーワードの後に、そのオブジェクトから取り出した値を格納する変数(ここではitem)を指定します。

 変数itemも、XElementオブジェクトになります。XElementクラスのDescendantsメソッドは、子孫要素から、指定された名前の要素をすべて列挙します(戻り値はIEnumerableオブジェクトとなります)。(3)のコードでは、ルート要素以下のすべての要素から、idという名前の要素を取得することになります。

 次のwhereキーワードは、抽出条件の指定です。ここでは、<id>要素の値に「"VPFD51_" + 指定の府県コード」という文字列が含まれるもの、としています。VPFD51は、天気予報を示すコードです。<id>要素の値は、気象情報XMLのURLとなっていて、またURLには、種別を示すコードと府県コードが含まれています。

 orderbyキーワードは、ソートの指定です。ここでは、ソートのキーとして要素の値(item.Valueプロパティ)を指定し、descendingをつけて降順としています。

 最後のselectキーワードでは、クエリ式の戻り値であるIEnumerableオブジェクトの型を指定します。ここでは、XElementクラスのValueプロパティを指定していますので、戻り値は、IEnumerable<string>となります。ちなみに、単にitemだけなら、IEnumerable<XElement>となります。

 戻り値のIEnumerable<string>には、値が複数含まれる可能性がありますので、Firstメソッドで先頭の値のみを取得しています(4)。

天気予報XMLファイルをHTMLに変換する

 天気予報XMLファイルのURLが取得できるようになったので、次は、そのXMLを処理しましょう。ただ、天気予報XMLはかなり複雑でわかりにくいため、今回は、XSLTスタイルシートを用いて変換するようにしました。

 XSLT(eXtensible Stylesheet Language Transformations)とは、XMLドキュメントをHTMLドキュメントやプレーンテキストに変換するための言語で、XSLTスタイルシートは、その変換処理を記述したファイルになります。気象庁のサイトには、参考資料として、天気予報XMLをHTMLに変換できるXSLTスタイルシートが公開されています。今回のアプリでは、サイトで公開されているXSLTスタイルシート(190501_yoho.xsl)をダウンロードして利用しました。なお、190501_yoho.xslは、~.Serverプロジェクト直下にコピーしておきます。

 XSLTスタイルシートでの変換は、.NET環境では、XslCompiledTransformクラスを利用すれば簡単に行うことができます。それでは、JmaControllerクラスに、指定した府県コードの天気予報HTMLを返すGetYohoメソッドを追加しましょう。

[リスト2]JmaController.cs
// オブジェクト初期化(1)
readonly XslCompiledTransform xslt = new();
public JmaController()
{
    // XSLTファイル読み込み(2)
    xslt.Load("190501_yoho.xsl");
}

Route("yoho/{code}")]
public ContentResult GetYoho(string code)
{
    // 指定の府県コードに該当するURLを取得する
    var url = GetUrl(code);
    if (url != null)
    {
        // XmlWriterの初期化(3)
        var html = new StringBuilder();
        using var writer = XmlWriter.Create(html);

        // XSLT変換処理(4)
        xslt.Transform(url, writer);

        // HTMLを返す(5)
        return base.Content(html.ToString(), "text/html");
    }
    return base.Content("<html><head><meta charset=\"utf-8\" /></head><body>予報がありません</body></html>", "text/html");
}

 最初に、クラスのメンバとして定義したXslCompiledTransformオブジェクトを初期化します(1)。C#9.0から、このように、new型名()の型名を省略した書き方ができるようになりました。

 XslCompiledTransformクラスの基本的な使い方は、LoadメソッドでXSLTスタイルシートを読み込み(2)、Transformメソッドで変換する(4)、という手順になります。Transformメソッドで変換するXMLファイルは、あらかじめ読み込む必要はなく、URLを第1引数に指定するだけで変換できます。Transformメソッドの第2引数には、XmlWriterオブジェクトを指定します。変換結果をファイルに出力する場合は、出力ファイル名の指定も可能です。

 XmlWriterクラスは、XMLを作成するためのライターオブジェクトで、静的メソッドのCreateメソッドを使って初期化しておきます(3)。なお、XmlWriterオブジェクトは最後にクローズ処理が必要なため、usingステートメントを使って、自動的にCloseメソッドが呼び出されるようにしています。

 変換結果は、親クラスのContentメソッドを用いてHTMLとして返します(5)。GetYohoメソッドの戻り値をHTMLとして認識させるために、メソッドの戻り値をContentResultオブジェクトとしています。ContentResultオブジェクトでは、コンテンツタイプ(Content-Type)を指定できるため、HTMLコンテンツとして返すことができます。

天気予報表示ページ

 最後に、天気予報表示を表示する処理を追加します。といっても、次のようにインラインフレームの<iframe>タグを追加するだけです。

[リスト3]Jma.razor
~略~
@if (codes == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <select @bind="selectCode" class="form-control">
        @foreach (var c in codes)
        {
            <option value="@c.Code">@c.Name</option>
        }
    </select>
    <br />
    <iframe src="api/jma/yoho/@selectCode" width="100%" height="800" frameborder="0"></iframe>
}
~略~

 インラインフレームのsrc属性に、先ほど追加したAPIのURLを指定しています。これだけで、天気予報のコンテンツが表示されます。また、セレクトボックスの値が変更されるたびに、自動的にインラインフレームの表示が更新されます。

 なお、サンプルのアプリでは、NavMenu.razorを少し変更して、メニューから天気予報ページを表示できるようにしています。

[リスト4]Jma.razor
~略~
<li class="nav-item px-3">
    <NavLink class="nav-link" href="tenki">
        <span class="oi oi-plus" aria-hidden="true"></span> 天気予報
    </NavLink>
</li>
~略~

次のページ
Blazorアプリの公開

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
ASP.NET Core Blazorチュートリアル連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/14382 2021/06/24 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング