<statuses>
<status>
<id>4773580</id>
<text>kazuhoさんがやってくれました!</text>
<user>
<screen_name>mattn</screen_name>
</user>
</status>
<status>
<id>4773581</id>
<text>今日のnickは○○提供です。</text>
<user>
<screen_name>kazuho</screen_name>
</user>
</status>
</statuses>
こんなXMLを以下の様な形にしたい場合がある場合に少し不便だったりします。
---
id: 4773580
text: kazuhoさんがやってくれました!
screen_name: mattn
---
id: 4773581
text: 今日のnickは○○提供です。
screen_name: kazuho
XML::Simpleを使うと、arrayノード一つにID要素があると勝手にノード扱いになったり、不必要なノードへのアクセスが必要になったりします。以下XML::Simpleのパース結果
---
status:
4773580:
text: kazuhoさんがやってくれました!
user:
screen_name: mattn
4773581:
text: 今日のnickは○○提供です。
user:
screen_name: kazuho
こんな場合にはXML::CuteQueriesを使うと便利です。
Paul Miller / XML-CuteQueries - search.cpan.org上の例であれば以下のコードで望み通りの形式でパース出来てしまいます。
A cute little query language for converting XML to Perl
http://search.cpan.org/dist/XML-CuteQueries/
use strict;
use warnings;
use LWP::Simple;
use XML::CuteQueries;
my $cq = XML::CuteQueries->new;
$cq->parse(get "http://api.wassr.jp/statuses/public_timeline.xml");
my @statuses = $cq->cute_query("/statuses/*" => {'*' => '', 'user/*' => ''});
use YAML;
warn Dump @statuses;
PODを見ていただければ分かりますが、XPathでクエリ式を書きそれに対するデータシェイプを指定します。例であれば"/statuses/*"にあるノードすべて"*"はデータシェイプのルートに、また"/statuses/*"にある"user/*"(user内の全て)もデータシェイプ内のルートに置くという指定になります。これ、XML版のWeb::Scraperって感じですかね。便利だわー。