<前回の記事>
前回は使用できるレスポンスグループの一覧を確認する所まででした。
早速組み合わせて何か作ろう・・・と思ったのですが、まずは既存のプログラムを修正してXMLから目的のデータを取得する機能、いわゆるパーサ(構文解析)を作る事が先だと気付きました。
という訳で今回は少し逸れて、XML解析に重点を置いた番外編2.5となります。
XMLオブジェクトの生成
まず既存の処理でXMLをやり取りする部分の処理を確認します。
'XML オブジェクト作成 Set xml = CreateObject("Microsoft.XMLDOM") xml.Async = False xml.Load URI Set itemAttributes = xml.SelectSingleNode("ItemLookupResponse/Items/Item/ItemAttributes")
まずここで使われていた「Microsoft.XMLDOM」については既にサポート切れ?で古い処理の様なので、「MSXML2.XMLHTTP」と「MSXML2.DOMDocument」を用いた処理に変更します。
[修正後]
'========================================================== ' 指定したURLのレスポンスXMLをMSXML2.DOMDocument形式で返す '========================================================== Public Function getXMLDoc(url As String) As MSXML2.DOMDocument Dim objXML As Object 'サイトデータの格納先 Dim objDoc As Object 'ドキュメントの格納先 'XMLHTTPオブジェクトを生成 Set objXML = CreateObject("MSXML2.XMLHTTP") On Error Resume Next Call objXML.Open("GET", url, False) Call objXML.send 'ロード完了まで待つ Do While objXML.readyState <> 4 Sleep 100 DoEvents Loop 'DOM操作を行える様にする Set objDoc = New MSXML2.DOMDocument objDoc.LoadXML objXML.responseText Set getXMLDoc = objDoc End Function
この「getXMLDoc」にエンコード後のURLを投げると、「MSXML2.DOMDocument」形式にてオブジェクトが返ってきます。
「MSXML2.DOMDocument」を使用する際は参照設定が必要になりますので、事前に以下の「Microsoft XML v6.0」にチェックを入れておきましょう。
これを呼び出し側の処理で受け取ることで、以前の処理で言う所の
Set xml = CreateObject("Microsoft.XMLDOM") xml.Async = False xml.Load URI
この辺まで置き換えが完了した事になります。
これだけ見ると「以前の処理の方が行数少なくてシンプルで良いじゃん。」って思いますよね。
・・・そうなんですよねー
まぁ私自身も具体的に「Microsoft.XMLDOM」と「MSXML2.DOMDocument」がどう違うのかっていうのを説明できないので申し訳無いのですが・・・。
とりあえず「古い」という事は今後使えなくなる可能性が十分にあります。素直に置き換えておいた方が無難です。
ちなみにAmazonAPIを使ってデータを取得しようとする際、エラーになる事がよくあります。
ウォッチウィンドウで見てみると、成功時は以下の様なステータスに。
statusに200が返って来ていればOKです。
失敗時は以下の様なステータスになります。
statusが503だとパラメータの取得に失敗している状態ですので、再度要求し直す必要があります。
「503」自体はWebサーバーへの同時アクセス数の制限をこえた場合や、Webサーバーがメンテナンス中などにより、リクエストに応答できない場合に出力されるエラーコードです。
ですが『いつ』、『どの時間帯に』やっても大体数回に1回は発生します。(笑)
なので実際に使用する場合は200が返ってくるまで数秒間隔でループさせる処理にした方が良さそうですね。
XMLDocumentからパラメータを抽出
では取得したXMLデータから、特定のパラメータ値を取り出してみましょう。
今回使用したXMLは以下のものです。
<?xml version="1.0" ?> <ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01"> <OperationRequest> (省略) </OperationRequest> <Items> <Request> <IsValid>True</IsValid> <ItemLookupRequest> <IdType>ASIN</IdType> <ItemId>B010EB1KL2</ItemId> <ResponseGroup>SalesRank</ResponseGroup> <VariationPage>All</VariationPage> </ItemLookupRequest> </Request> <Item> <ASIN>B010EB1KL2</ASIN> <SalesRank>3968</SalesRank> </Item> </Items> </ItemLookupResponse>
これはAmazonAPIを使用して、レスポンスグループに「SalesRank」を指定した際に返されたXMLです。
この中から「SalesRank」の『3968』という値を取り出してみます。
まず、以下従来のサンプル部分から
'不足が出るので=で埋める sign = sign & "=" 'URLエンコード sign = UrlEncode(sign) URI = "http://" & ecsaddress & "/onca/xml?" & rawText & "&Signature=" & sign 'XML オブジェクト作成 Set xml = CreateObject("Microsoft.XMLDOM") xml.Async = False xml.Load URI Set itemAttributes = xml.SelectSingleNode("ItemLookupResponse/Items/Item/ItemAttributes")
URLエンコード処理より下の部分を全て削除し、以下の処理を記述します。
Dim XMLDocument As MSXML2.DOMDocument Dim xmlData As IXMLDOMNode '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ '不足が出るので=で埋める sign = sign & "=" 'URLエンコード sign = UrlEncode(sign) URI = "http://" & ecsaddress & "/onca/xml?" & rawText & "&Signature=" & sign Set XMLDocument = getXMLDoc(URI) Set xmlData = XMLDocument.SelectSingleNode("//ItemLookupResponse/Items/Item/SalesRank") MsgBox xmlData.text
あ、
Dim XMLDocument As MSXML2.DOMDocument
Dim xmlData As IXMLDOMNode
上記2つの定数も忘れずに宣言追加しておいて下さい。
そして冒頭で記述した「getXMLDoc」関数をどこかに記述した状態で実行させると・・・
と出るはずです。
<ItemLookupResponse>の中にある、
<Items>の中にある、
<Item>の中にある、
<SalesRank>を抽出したいと言う場合には、
SelectSingleNode(“//ItemLookupResponse/Items/Item/SalesRank“)
という風に指定すれば値を取り出せるという事ですね。
同じ様に<Request>の中にある<ItemId>を取り出したい場合は、
SelectSingleNode(“//ItemLookupResponse/Items/Request/ItemId“)
となります。
データの切り出しは意外と簡単でしたね!(調べて検証してここまで纏めるのに2日掛かりましたが)
これさえ分かれば後のパラメータも簡単に取得できると思いますので、ぜひ試してみて下さい。
複数の商品の情報が返って来た場合、全く同じ名前のノードが複数個存在する事になりますが、その場合の処理はまた今度考えましょう。
今回はこの辺で終了となります。
ではまた!
<次の記事>