XMLRPCの戻り値は Perl 構造体の配列

というようなことが書かれていてもサッパリどうアクセスするかわからんちんでした。

ちなみにmt.getCategoryListは Categoryのリストをとるための関数です。ポストするエントリーのカテゴリをセットするために必要な情報なので取ります。

MovableType で使える XML-RPC API

mt.getCategoryList
説明
その weblog にあるすべての分類(カテゴリ)を返します。
引数

String blogid, /* blog ID */
String username, /* blog のユーザ名(アカウント) */
String password /* 上記ユーザの blog への login 用パスワード */

返り値
成功すると、分類の数だけ、次の要素を含む構造体の配列が返ってきます:


String categoryId /* カテゴリID */
String categoryName; /* カテゴリの名前 */

以下が参考になりました。

Perlテクニック集

▼構造体の配列の使い方 ■2000年04月13日 木曜日

 Perlには、C言語のような構造体が存在しません。そこで、リファレンスとハッシュを使って擬似的に構造体を作ります。例えば、氏名、住所、電話番号を保持する構造体を作るとします。

構造体のメンバ

氏名・・・Name
住所・・・Address
電話番号・・・Tel

この構造体は、Perlで次のように表します。

%Data1 = ("Name" => "Shintaro", "Address" => "Japan", "Tel" => "0123");

この構造体のメンバにアクセスするには、次のように記述します。

$Data1{"Name"};
$Data1{"Address"};
$Data1{"Tel"};

更に、この構造体の配列を作るとすると、

$DataArray = [ \%Data1, \%Data2 ];

これで、$DataArray変数が構造体の配列を指し示すことになります。各構造体にアクセスするときは、

$DataArray->[0]{"Name"};
$DataArray->[0]{"Address"};
$DataArray->[0]{"Tel"};

$DataArray->[1]{"Name"};
$DataArray->[1]{"Address"};
$DataArray->[1]{"Tel"};

関連リンク:Perl入門

具体的には以下のコードで取れます。

#!/usr/bin/perl -w

use CGI ':standard';
use XMLRPC::Lite;
use strict;

# init
my $query = CGI->new;
my $uri = "http://url/path/to/mt/mt-xmlrpc.cgi";
my $method = "mt.getCategoryList";
my $blogid = "2";
my $user = "username";
my $passwd = "password";

# get category id and name
my $res = XMLRPC::Lite->proxy($uri)->call( $method,
$blogid,
$user,
$passwd
)
-> result;

my $catid;
my $catname;
my %tmp;
foreach( @$res ){
%tmp = %$_;
$catid = $tmp{"categoryId"};
$catname = $tmp{"categoryName"};
print $catid, $catname, "\n";
}

categoryId, categoryNameが表示されます。

metaWeblog.newPostではカテゴリをセットできないので、返り値でもらった記事IDと、categoryIdを利用して、後からmt.setPostCategoriesを使ってセットします。

#!/usr/bin/perl -w

use CGI ':standard';
use XMLRPC::Lite;
#use strict;

# init
my $query = CGI->new;
my $uri = "http://url/path/to/mt/mt-xmlrpc.cgi";
my $method = "mt.setPostCategories";
my $blogid = "2";
my $user = "username";
my $passwd = "password";
my $category = "1";
my $postid = "1234";

my %cat = ( "categoryId" => $category, "isPrimary" => 1 );
my $array = [ \%cat ];

my $res = XMLRPC::Lite->proxy($uri)->call( $method,
$postid,
$user,
$passwd,
$array
)
-> result;

if( $res ){
print "success: $res\n";
}
else{
print "failed: $postid, $category\n";
}

とりあえずやりたいことが一通り出来たので、今度はAtomかな。