homeへのリンクです。

Yahoo WEB API を使う 2

2007年05月11日

前回のサンプルのコードの説明。
ActionScript 3.0では、URLRequestクラスができて、ロードに必要なURLをきれいにまとめられる。

package com.kishineshiki.yahoo{
    import flash.net.*;
    public class MakeYahooJapanURLRequest{
        private static var urlstr:String="http://api.search.yahoo.co.jp/ImageSearchService/V1/imageSearch";
        private static var appid:String="自分のID";
        public static function searchURL(word:String):URLRequest{
            var urlvar:URLVariables =new URLVariables();
            urlvar.appid=appid;
            urlvar.query="+"+word;
            var urlrequest:URLRequest=new URLRequest(urlstr);
            urlrequest.data=urlvar;
            return urlrequest;
        }
        private static function extractResult(xmllist:XMLList,uri:String,nodename:Array):XMLList{
            var qname:QName=new QName(uri,nodename.shift());
            xmllist=xmllist.child(qname);
            if(nodename.length>0){
               xmllist=MakeYahooJapanURLRequest.extractResult(xmllist,uri,nodename);
            }
            return xmllist;
        }
        public static function thumbnailURL(xml:XML):Array{
            var urllist:XMLList=extractResult(XMLList(xml),xml.namespace().uri,["Result","Thumbnail","Url"]);
            var widthlist:XMLList=extractResult(XMLList(xml),xml.namespace().uri,["Result","Thumbnail","Width"]);
            var heightlist:XMLList=extractResult(XMLList(xml),xml.namespace().uri,["Result","Thumbnail","Height"]);
            var urlrequestlist:Array=new Array();
            for(var i:Number=0;i<urllist.length();i++){
                urlrequestlist[i]={urlreq:new URLRequest(urllist[i]),width:widthlist[i],height:heightlist[i]};
            } 
            return urlrequestlist;
        }
    }
}
YahooJapan WEB APIのレスポンスはXMLにネームスペースを使用しているので、素直にE4Xのメソッドでノードをサーチすることができない。
xml.namespace().uri
(ここのuriはストリングなので、ネームスペースの名前がわかっていれば"xs"などとしてもよい) のようにネームスペースを抽出して、
new QName(uri,nodename.shift())
のようにQNameというのを作成してノード検索の文字として使う必要がある。 ("Thumbnail","xs:Thumbnail"どちらもノードのオブジェクト名として利用できない。)

呼び出し側の方は以下。

package{
    import flash.display.*;
    import flash.text.*;
    import flash.events.*;
    import com.kishineshiki.xml.LoadXML;
    import com.kishineshiki.yahoo.*;
    import com.kishineshiki.btn.*;
    import com.kishineshiki.txt.*;
    [SWF(width="600",height="500",backgroundColor="#ffffff",frameRate="24")]
    public class YahooImageSearchTest extends Sprite{
        private var loadxml:LoadXML;
        private var textinput:TextInput;
        private var loaderlist:Array;
        public function YahooImageSearchTest(){
            loadxml=new LoadXML();
            loadxml.addEventListener(onLoad);
            textinput=new TextInput(150,22);
            textinput.x=10;
            textinput.y=10;
            addChild(textinput);
            var searchbutton:ButtonBase=new ButtonBase("search",100,22);
            searchbutton.x=170;
            searchbutton.y=10;
            searchbutton.addEventListener(MouseEvent.CLICK,search);
            addChild(searchbutton);
            loaderlist=new Array();
        }
        private function search(event:MouseEvent):void{
            loadxml.load(MakeYahooJapanURLRequest.searchURL(textinput.text));
        }
        private function onLoad(xml:XML):void{
            loadSumbnail(xml);
        }
        private function loadSumbnail(xml:XML):void{
            unloadSumbnail();
            var currentx:Number=0;
            var currenty:Number=40;
            var maxy:Number=0;
            var requestlist:Array=MakeYahooJapanURLRequest.thumbnailURL(xml);
            for(var i:Number=0;i<requestlist.length;i++){
                loaderlist[i]=new Loader();
                addChild(loaderlist[i]);
                loaderlist[i].load(requestlist[i].urlreq);
                loaderlist[i].x=currentx;
                loaderlist[i].y=currenty;
                currentx+=Number(requestlist[i].width);
                if((i+1)<requestlist.length&¤tx+Number(requestlist[i+1].width)>600){
                    currentx=0;
                    currenty+=maxy;
                    maxy=0;
                }
                if(maxy<Number(requestlist[i].height)){
                    maxy=Number(requestlist[i].height);
                }
            }
        }
        private function unloadSumbnail():void{
            for(var i:Number=0;i<loaderlist.length;i++){
                loaderlist[i].unload();
            }
        }
    }
}

[SWF(・・・)]の部分はflex builder用のコマンドライン引数の代わりになるもの。