じゃらんのWebAPIから取得したXMLをASP.NET(VB)でデシリアライズしてオブジェクトに格納する練習

検索キーを指定してリクエストするとXML形式で検索結果をリターンしてくれるWebAPIがあると思います。
JSON形式のリターンデータをデシリアライズするのはTMDb API V3 を利用して取得した JSON形式 のデータを ASP.NET でデシリアライズするでやりました。XMLはどうやるのだろう?ということでGoogle先生に聞いてみますが、Web-APIでXML取得~XMLのデシリアライズまでを解説したものが見当たりませんでした。
ここではじゃらんWebサービスのじゃらんWebサービス 宿表示API ライトを使用して、ユニバーサルシティ周辺のホテル情報を取得したいと思います。
じゃらんWebサービスを利用するには、事前にアカウント登録しAPIキーを取得しておく必要があります。
取得したAPIキーをリクエストURLに埋め込んで、じゃらんWebサービス(WebAPI)を呼び出します。
ユニバーサルシティ周辺のホテル情報を取得するリクエストは下記のようになります。
http://jws.jalan.net/APILite/HotelSearch/V1/?key=**************&s_area=272302
keyには取得したAPIキーを指定します。s_areaはユニバーサルシティの小エリアコードを指定します。小エリアコード表はじゃらんWebサービス - エリアコードで確認できます。
上記のリクエストにより下図のようなXMLがリターンされます。
01


デシリアライズ

素人メモなので理解、手法、用語に大きな誤りがあるかもしれません。コメントなどでご指摘、ご指導いただけるとありがたいです。
  1. XMLの最上位要素から末端までクラスとして定義しておく
    最上位要素は<XmlRoot("要素名")>、要素は<XmlElement("Area")>
  2. System.Net.HttpWebResponse.GetResponseStream()でリクエストし、取得したXMLSystem.IO.StreamReader.ReadToEndでテキストに変換
  3. System.Text.Encoding.UTF8.GetBytesでXMLテキストをUTF-8のバイトシーケンスにエンコード
  4. System.Xml.Serialization.XmlSerializerでバイトシーケンスをデシリアライズして1で定義したクラスのインスタンスに格納
System.Xml.Serialization.XmlSerializerでは文字列をデシリアライズできないので、3でバイトシーケンスにエンコードしています。
3、4については下記の記事を読んで実現できました。ありがとうございました。
VB XMLのシリアライズ・デシリアライズ - XmlSerializer シリアル化 逆シリアル化
http://homepage1.nifty.com/rucio/main/VBdotNet/Samples201/Sample235XMLSerialize.htm

(コード)
TestXMLJaran2.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="TestXMLJaran2.aspx.vb" Inherits="TestXML" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <style type="text/css">
        .auto-style1 {
            width: 100%;
            border-collapse: collapse;
        }
        .auto-style2 {
            height: 19px;
        }
        .auto-style3 {
            height: 18px;
        }
    </style>
</head>
<body>
     <form id="form1" runat="server">
         <br />
         <asp:Button ID="ButtonClear" runat="server" Text="Clear" />
         <asp:Button ID="ButtonDeserialize" runat="server" style="height: 21px" Text="Deserialize" />
         <br />
         <br />
         <asp:Label ID="LabelResults" runat="server"></asp:Label>
         <br />
         <asp:DataList ID="DataListHotels" runat="server">
             <ItemTemplate>
                 <table class="auto-style1">
                     <tr>
                         <td colspan="2">
                             <asp:Image ID="ImagePictureURL" runat="server" ImageUrl='<%# eval("PictureURL") %>' />
                         </td>
                     </tr>
                     <tr>
                         <td>HotelID</td>
                         <td>
                             <asp:Label ID="LabelHotelID" runat="server" Text='<%# eval("HotelID") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>HotelName</td>
                         <td>
                             <asp:Label ID="LabelHotelName" runat="server" Text='<%# Eval("HotelName") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>PostCode</td>
                         <td>
                             <asp:Label ID="LabelPostCode" runat="server" Text='<%# eval("PostCode") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>HotelAddress</td>
                         <td>
                             <asp:Label ID="LabelHotelAddress" runat="server" Text='<%# eval("HotelAddress") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>HotelType</td>
                         <td>
                             <asp:Label ID="LabelHotelType" runat="server" Text='<%# eval("HotelType") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>HotelDetailURL</td>
                         <td>
                             <asp:HyperLink ID="HyperLinkHotelDetailURL" runat="server" NavigateUrl='<%# Eval("HotelDetailURL") %>' Target="_blank" Text='<%# eval("HotelDetailURL") %>'></asp:HyperLink>
                         </td>
                     </tr>
                     <tr>
                         <td>HotelCatchCopy</td>
                         <td>
                             <asp:Label ID="LabelHotelCatchCopy" runat="server" Text='<%# eval("HotelCatchCopy") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>HotelCaption</td>
                         <td>
                             <asp:Label ID="LabelHotelCaption" runat="server" Text='<%# eval("HotelCaption") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>PictureURL</td>
                         <td>
                             <asp:Label ID="LabelPictureURL" runat="server" Text='<%# eval("PictureURL") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>PictureCaption</td>
                         <td>
                             <asp:Label ID="LabelPictureCaption" runat="server" Text='<%# eval("PictureCaption") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>AccessInformation</td>
                         <td>
                             <asp:Label ID="LabelAccessInformation" runat="server" Text='<%# eval("AccessInformation") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>name</td>
                         <td>
                             <asp:Label ID="Labelname" runat="server" Text='<%# eval("name") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>CheckInTime</td>
                         <td>
                             <asp:Label ID="LabelCheckInTime" runat="server" Text='<%# eval("CheckInTime") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>X</td>
                         <td>
                             <asp:Label ID="LabelX" runat="server" Text='<%# eval("X") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>y</td>
                         <td>
                             <asp:Label ID="LabelY" runat="server" Text='<%# eval("Y") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td class="auto-style2">LastUpdate</td>
                         <td class="auto-style2">
                             <asp:Label ID="LabelLastUpdate" runat="server" Text='<%# eval("LastUpdate") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td class="auto-style3">day</td>
                         <td class="auto-style3">
                             <asp:Label ID="Labelday" runat="server" Text='<%# eval("day") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>month</td>
                         <td>
                             <asp:Label ID="Labelmonth" runat="server" Text='<%# eval("month") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>year</td>
                         <td>
                             <asp:Label ID="Labelyear" runat="server" Text='<%# eval("year") %>'></asp:Label>
                         </td>
                     </tr>
                     <tr>
                         <td>WifiHikariStation</td>
                         <td>
                             <asp:Label ID="LabelWifiHikariStation" runat="server" Text='<%# eval("WifiHikariStation") %>'></asp:Label>
                         </td>
                     </tr>
                 </table>
             </ItemTemplate>
         </asp:DataList>
</form>
</body>
</html>

TestXMLJaran2.aspx.vb
Imports System.Xml.Serialization
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Xml
Imports System.Data

Partial Class TestXML
    Inherits System.Web.UI.Page

    <XmlRoot("Results")> _
    Public Class Results

        Public Property NumberOfResults As Integer
        Public Property DisplayPerPage As Integer
        Public Property DisplayFrom As Integer
        Public Property APIVersion As String
        <XmlElement("Hotel")> _
        Public Property Hotel As List(Of HotelProperties)

    End Class

    Public Class HotelProperties

        Public Property HotelID As String
        Public Property HotelName As String
        Public Property PostCode As String
        Public Property HotelAddress As String
        <XmlElement("Area")> _
                Public Property Area As List(Of AreaProperties)
        Public Property HotelType As String
        Public Property HotelDetailURL As String
        Public Property HotelCatchCopy As String
        Public Property HotelCaption As String
        Public Property PictureURL As String
        Public Property PictureCaption As String
        Public Property AccessInformation As String
        Public Property name As String
        Public Property CheckInTime As String
        Public Property CheckOutTime As String
        Public Property X As String
        Public Property Y As String
        Public Property LastUpdate As String
        Public Property day As String
        Public Property month As String
        Public Property year As String
        Public Property WifiHikariStation As String

    End Class

    Public Class AreaProperties

        Public Property Region As String
        Public Property Prefecture As String
        Public Property LargeArea As String
        Public Property SmallArea As String

    End Class

    Protected Sub ButtonDeserialize_Click(sender As Object, e As EventArgs) Handles ButtonDeserialize.Click

        DataListHotels.DataSource = Nothing
        DataListHotels.DataBind()

        Dim strURL As String = "http://jws.jalan.net/APILite/HotelSearch/V1/?key=cyg14185d01458&s_area=272302"

        Dim request = TryCast(System.Net.WebRequest.Create(strURL), System.Net.HttpWebRequest)
        request.Method = "GET"
        request.Accept = "text/xml"

        Dim objStreamReader As StreamReader = Nothing

        request.ContentLength = 0
        Dim responseContent As String = ""
        Dim responseContentR As String = ""
        Try
            Using Response = TryCast(request.GetResponse(), System.Net.HttpWebResponse)
                Using reader = New System.IO.StreamReader(Response.GetResponseStream())
                    responseContent = reader.ReadToEnd
                    responseContentR = responseContent.Replace("<Results xmlns=""jws"">", "<Results xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">")
                End Using
            End Using
        Catch ex As WebException
            LabelResults.Text = ex.Message
            Exit Sub
        End Try


        Dim Results As New Results()
        Results = Deserialize(Of Results)(responseContentR)

        Dim tableHotels As New DataTable
        tableHotels.Columns.Add("HotelID")
        tableHotels.Columns.Add("HotelName")
        tableHotels.Columns.Add("PostCode")
        tableHotels.Columns.Add("HotelAddress")
        tableHotels.Columns.Add("HotelType")
        tableHotels.Columns.Add("HotelDetailURL")
        tableHotels.Columns.Add("HotelCatchCopy")
        tableHotels.Columns.Add("HotelCaption")
        tableHotels.Columns.Add("PictureURL")
        tableHotels.Columns.Add("PictureCaption")
        tableHotels.Columns.Add("AccessInformation")
        tableHotels.Columns.Add("name")
        tableHotels.Columns.Add("CheckInTime")
        tableHotels.Columns.Add("CheckOutTime")
        tableHotels.Columns.Add("X")
        tableHotels.Columns.Add("Y")
        tableHotels.Columns.Add("LastUpdate")
        tableHotels.Columns.Add("day")
        tableHotels.Columns.Add("month")
        tableHotels.Columns.Add("year")
        tableHotels.Columns.Add("WifiHikariStation")

        If Results.NumberOfResults <= 0 Then
            LabelResults.Text = ""
        Else
            For Each hotel In Results.Hotel
                Dim rowHotel = tableHotels.NewRow()
                rowHotel("HotelID") = hotel.HotelID
                rowHotel("HotelName") = hotel.HotelName
                rowHotel("PostCode") = hotel.PostCode
                rowHotel("HotelAddress") = hotel.HotelAddress
                rowHotel("HotelType") = hotel.HotelType
                rowHotel("HotelDetailURL") = hotel.HotelDetailURL
                rowHotel("HotelCatchCopy") = hotel.HotelCatchCopy
                rowHotel("HotelCaption") = hotel.HotelCaption
                rowHotel("PictureURL") = hotel.PictureURL
                rowHotel("PictureCaption") = hotel.PictureCaption
                rowHotel("AccessInformation") = hotel.AccessInformation
                rowHotel("name") = hotel.name
                rowHotel("CheckInTime") = hotel.CheckInTime
                rowHotel("CheckOutTime") = hotel.CheckOutTime
                rowHotel("X") = hotel.X
                rowHotel("Y") = hotel.Y
                rowHotel("LastUpdate") = hotel.LastUpdate
                rowHotel("day") = hotel.day
                rowHotel("month") = hotel.month
                rowHotel("year") = hotel.Y
                rowHotel("WifiHikariStation") = hotel.WifiHikariStation
                tableHotels.Rows.Add(rowHotel)
            Next
            DataListHotels.DataSource = tableHotels
            DataListHotels.DataBind()
            DataListHotels.Visible = True
        End If

    End Sub

    Protected Sub ButtonClear_Click(sender As Object, e As EventArgs) Handles ButtonClear.Click

        DataListHotels.DataSource = Nothing
        DataListHotels.DataBind()

    End Sub

    Public Function Deserialize(Of T)(xml As String) As T

        Dim result As T
        Dim serializer As New System.Xml.Serialization.XmlSerializer(GetType(T))

        Using stream As New IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(xml))
            result = DirectCast(serializer.Deserialize(stream), T)
        End Using

        Return result

    End Function

End Class

(結果)
Deserializeを押すと、じゃらんWebサービスからユニバーサルシティ周辺のホテル情報をXML形式で取得し、それをDataListに展開します。
02

参考
XmlSerializer.Deserialize メソッド (XmlReader) (System.Xml.Serialization)
https://msdn.microsoft.com/ja-jp/library/tz8csy73(v=vs.110).aspx

DirectCastで定義したクラスのインスタンスにデータを格納できる?
TMDb API V3 を利用して取得した JSON形式 のデータを ASP.NET でデシリアライズするでは取得した作品情報をいったん汎用オブジェクトに展開し、一つ一つのデータを定義済クラスのインスタンスへ設定するという不適切?という方法としました。DirectCastで正しく(適切に)できないか後日やってみようと思います。

コメント

このブログの人気の投稿

ダブルクォーテーションで括られたCSVカ​ンマ区切りテキストファイルを SQL Server で Bulk Insert する方法

PowerShellでTSV/CSVの列を絞り込んで抽出し、(先頭/行末)からN行出力する

IKEAの鏡を壁に取り付ける