ここに挙げた問題点は、2003 年 7 月 27 日、 AWS サーバのバージョンアップによって解決しました。 詳しくはこちらをご覧下さい。 (2003/07/27 追記)
はてさて、先日から始まっている XML 初心者のAmazon Web サービス遊びです (以下の内容でアソシエイト・タグは MYTAG, デベロッパー・トークンは MYDEVT と記述します)。 要するに XML/HTTP や SOAP による DB へのインターフェースを Amazon がデベロッパー向けに公開しているわけですが、 それを使ってアプリケーションを組んでみたい、ということです。
まずは XML/HTTP でアクセスしてみましょう。 ためしに Mozilla で http://xml.amazon.com/onca/xml3?t=MYTAG&dev-t=MYDEVT&KeywordSearch=dogs&mode=books-jp&type=lite&page=1&f=xml&locale=jp にアクセスしてみましょう。これで日本の Amazon のデータベースを、 書籍情報に関して「dogs」というキーワードで検索したことになります。 Mozilla は IE などと同様、XML の表示機能を持っているため、 エレメント構造をフォールド・アンフォールドしながらインタラクティブに見ることができます。
この結果のスキーマは、1 行目の記述にある通り http://xml.amazon.com/schemas3/dev-lite.xsd に存在します。 検索結果としては 27 件のデータが得られています (<TotalResults>27</TotalResults> がこれに該当します)。
各項目のデータとして、ASIN (この場合は本なので ISBN に相当)、 商品名、著者名、表紙画像の URI、価格情報などが得られます。 「lite」モードではなく、「heavy」モードで検索すると、 レビューや在庫情報なども結果に含まれるようになります。
う〜む、結構面白いかも。いろいろパラメータを変えてひとしきり遊んでみます。 まあ、そうなると XML/HTTP だけではなく SOAP でも遊んでみたくなってきました。 ということで、SOAP::Lite (FreeBSD では ports/net/p5-SOAP-Lite にあります。 Perl 5.8.0 のインストールに関しては先日の内容を参考に) をインストールして、 以下のテスト用プログラムを走らせてみます。
#!/usr/local/bin/perl use SOAP::Lite; my $s = SOAP::Lite -> service('http://soap.amazon.com/schemas3/AmazonWebServices.wsdl'); my $p = $s -> KeywordSearchRequest( SOAP::Data->name("KeywordSearchRequest") ->type("KeywordRequest") ->value(\SOAP::Data->value( SOAP::Data->name("keyword" => 'dogs'), SOAP::Data->name("page" => '1'), SOAP::Data->name("mode" => 'books-jp'), SOAP::Data->name("tag" => 'MYTAG'), SOAP::Data->name("type" => "lite"), SOAP::Data->name("devtag" => 'MYDEVT'), SOAP::Data->name("locale" => "jp"), SOAP::Data->name("format" => "xml"), SOAP::Data->name("version" => "1.0"), ) ) );
ところがどっこい、このプログラムが正しいかどうかを確かめる以前に、 エラーが出て動かないのです…。
% ./soaptest.pl
not well-formed (invalid token) at line 1, column 1541, byte 1555 at \
/usr/local/lib/perl5/site_perl/5.8.0/mach/XML/Parser.pm line 185
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-EN\
C="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="\
http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://sche\
mas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLS\
chema-instance" xmlns:xsd="http://www.w3.....(略)....
</namesp1822:KeywordSearchRequestResponse></SOAP-ENV:Body></SOAP-ENV:E\
nvelope> at soaptest2.pl line 8
うーん。しかし、エラーメッセージを見るに、 何か SOAP の使い方に問題があるというよりは、 もっと根本的な問題のような予感 (expat 的問題?)。 ためしに、もう一度 XML/HTTP に戻って、expat でチェックをしてみることに。
% wget -O out.xml 'http://xml.amazon.com/onca/xml3?t=MYTAG&dev-t=MYDEVT&\ KeywordSearch=dogs&mode=books-jp&type=lite&page=1&f=xml&locale=jp' --01:25:17-- http://xml.amazon.com/onca/xml3?t=MYTAG&dev-t=MYDEVT&Keywo\ rdSearch=dogs&mode=books-jp&type=lite&page=1&f=xml&locale=jp => `out.xml' xml.amazon.com をDNSに問いあわせています... 完了しました。 xml.amazon.com[207.171.179.33]:80 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 特定できません [text/xml] [ <=> ] 8,447 24.26K/s 01:25:18 (24.26 KB/s) - `out.xml' saved [8447] % xmlwf out.xml out.xml:36:17: not well-formed (invalid token)
あらら…。expat (ports/textproc/expat2) に付属の xmlwf コマンド (XML が Well-formed かをチェックする) でエラーが出ています。 で、その 36:17 というのはどこかというと…。なるほどここか! (文字化けした部分は「〓」で表記してます)
<ListPrice>〓 590</ListPrice> ← この「〓」の部分が 36:17 に相当
<OurPrice>〓 590</OurPrice>
<UsedPrice>〓 315</UsedPrice>
文字化けしているが、文脈的には円マークがある場所だ。 ためしにこの部分を除いて xmlwf でもう一度試してみよう。
% egrep -v '(OurPrice|UsedPrice|ListPrice)' out.xml > out2.xml % wc out2.xml 146 194 7673 out2.xml % xmlwf out2.xml %
なるほど、これは well-formed XML らしい。 ということで仮説。 Amazon の「円マーク」のエンコーディングが、 UTF-8 としては不正なエンコーディングになっていて、 そのせいで expat が発狂している。 expat にパーサーを依存した SOAP::Lite はそのために失敗している。 こんなところでしょう。
てなことで、Amazon.com のディスカッションボードに以上の結果を投稿したところ、 「We know this problem exists. We have a fix for it and will be deploying it soon.」という回答が Amazon.com の Nicholas Lee 氏からありました。 うん、早く直してほしいなぁ〜。 この件、AWS FAQ のページにも掲載されたみたい。
現在でも、XML/HTTP を用いれば、結果に正規表現を一発通すだけでアプリケーションの開発はできるんだけど、 せっかくだから直るまで待って SOAP で作るかな? という感じです。 あまり長期間バグが放置されるようだと考えてしまいますが。
この話題、続く→ 2003/07/21 『AWS: XEmacs 21.4.x で UTF-8 を使う』