XML::Simpleの使い方について

このQ&Aのポイント
  • XML::Simpleを使ってプログラムを書いたが、連続して出てくるentryが取得できない。
  • アドバイスを求めている。
  • 使い方を教えてほしい。
回答を見る
  • ベストアンサー

XML::Simpleの使い方について

下記のような、プログラムを書いたのですが、上のタイトルはとれるのですが、連続して出てくるentryがどうしても取得できません。 何かご助言頂ければありがたいです。 my $url = "http://blog.livedoor.jp/takapon_ceo/atom.xml"; my $xml = get($url); my $tree = XMLin($xml); my $title = $tree->{title}; print "$title"; for (my $i = 0; $i <= 5; $i++) { $id[$i] = $tree->{'entry'}->[$i]->{'id'}; print "$id[$i]"; } よろしくお願いします。

  • Perl
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.2

use Data::Dumper; をして Dumper($tree->{entry}) を表示すれば分かりますが、その実体は配列ではなくハッシュです。 このハッシュのキーは各エントリの id で、id は投稿順に文字列昇順となっていますから、キーをソートして値を取り出せばOKです。 # IDリストの取り出し(新着順にしたいので降順にソート) my @entries_id = sort {$b cmp $a} keys %{$tree->{entry}}; foreach my $id (@entries_id) {   print "$id\n";   # 各要素へのアクセス   my $entry = $tree->{entry}->{$id};   print "$entry->{title}\n";   print "$entry->{summary}->{content}\n"; } # この結果は $tree = XMLin($xml) とした場合のものです。 # インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

eltech
質問者

お礼

サンプルコードまでご用意頂きありがとうございました。 ありがとうございました。 おかげさまで無事動作させることができました。 Dumperもデバッグに使えそうですね。

その他の回答 (1)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

こんな感じ? ---------------------------------------------------- use encoding 'UTF-8', STDOUT => "shiftjis"; use LWP::Simple; use XML::Simple; my $url = "http://blog.livedoor.jp/takapon_ceo/atom.xml"; my $xml = get($url); my $tree = XMLin($xml, forcearray=>1); my $title = $tree->{title}->[0]; print "$title\n"; for my $entry (@{$tree->{entry}}) { $id[$i] = $entry->{'id'}->[0]; print "$id[$i]\n"; }

関連するQ&A

  • 関数でxml::simpleが使えない。

    AWSがらみで以下のようなことがしたいです。 --------------- my $url = 'amazon web service RESTのURL'; my %XMLtree = xmlget($url); sub xmlget{ my $url = shift; my $content = LWP::Simple::get($url); #xml->hash変換 my $xs = new XML::Simple(); my $XMLtree = $xs->XMLin($content); return $XMLtree; } ----------------------- しかしハッシュを関数の引数や返り値にすると上手く動きませんでした。 そこでreturnで値を渡さずに、globalで%XMLtreeを宣言してXMLinの値を代入しようとしたのですがうまくいきません。 他にもリファレンスを渡してみたりしたのですが上手くいきません。 よく考えたら$XMLtreeはハッシュのリファレンスの塊なので、トップのアドレスを渡しても、関数を抜けてしまえば実体は消えます。(ですよね?) ハッシュのリファレンスの塊である$XMltreeを関数から外側に渡すにはどうすればいいでしょうか? それとも全く別の問題なのでしょうか?

    • ベストアンサー
    • Perl
  • XMLパラメータの取り込みに関して

    XMLパラメータの取り込みに関して http://geocode.didit.jp/ 先日上のサイトと見つけ面白いと思い http://www.kawa.net/works/perl/treepp/treepp.html#example 上のサイトを参考に use XML::TreePP; my $tpp = XML::TreePP->new(); my $tree = $tpp->parsehttp( GET => "http://geocode.didit.jp/reverse/?lat=35.68653&lon=139.69193" ); print "Title: ", $tree->{"rdf:RDF"}->{channel}->{title}, "\n"; こんな感じでXMLパラメータの住所を取り込もうとしたのですがどうしても上手く取り込めません どなたか取り込み方を教えて頂けませんでしょうか? お願いいたします。

    • ベストアンサー
    • Perl
  • 実行対象のブログのURLは抽出させない

    以前の質問http://oshiete1.goo.ne.jp/kotaeru.php3?q=1725502 のご回答のプログラムを改良してトラックバックされたブログURLを抽出する 以下のようなプログラムを作成しました。 (省略部分は参考プログラムとほぼ同じ。) class GetTBurlLivedoor { public static String[] getTBaddrLivedoor(String urlString){ … //ブログのURLを抽出。ただし、スペースの都合上ここではライブドアのみ抽出とする //indexOfを用いての範囲指定はせず、HTMLすべてに対してパース Pattern trackBack = Pattern.compile("http://blog.livedoor.jp/.*/archives/\\d+.html"); while((aLine = reader.readLine())!=null){ Matcher m = trackBack.matcher(aLine); if(m.find()){ addr+=m.group(0)+","; } … public static void main(String[] args){ String url = args[0]; //実行例 http://blog.livedoor.jp/takapon_ceo/archives/50030785.html String[] TBaddr = getTBaddrLivedoor(url); for(int i=0;i<TBaddr.length;i++) System.out.println(TBaddr[i]); } } そこで、URLを抽出する際に、実行対象となるブログ自身に関するURL 例)http://blog.livedoor.jp/takapon_ceo/archives/50034644.html などは抽出しないようにするため、 そのブログ自身のIDを含むURLは抽出しないような処理をしたいと思います。 例えば、ライブドアでは、ブログのIDは、 http://blog.livedoor.jp/ ID /archives/50030785.html となっているので、このID(実行例ではtakapon_ceo)を含むURLは抽出しないようにさせたいです。 このようにするには、どのようにプログラムを組めばよいでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • XML::XPathでのfor文の記述

    たびたびお世話になります。よろしくお願いいたします。 perlでXML文書をHTMLへ変換しています。 ---------------------------------------- <!-- file.xml --> <root> <jouhou> <mei> <toushu>あ</toushu> <toushu>い</toushu> <toushu>う</toushu> </mei> <mei> <toushu>え</toushu> <toushu>お</toushu> <toushu>か</toushu> </mei> </jouhou> </root> ---------------------------------------- このようなXMLの場合に、XML::XPathで「あ」と「え」などの最初に来る<toushu>取りたいのですが 日によって<mei>の数が異なるため、<mei>の数を取得してその数でforをすることにしました。 が、うまくいきません。 my $xp = new XML::XPath( filename => "./file.xml" ); for(my $j=1;$j<=$xp->findvalue("count(//jouhou/mei/toushu)");$j++){ print $j; #←ここでは1と2が出ます。 print $xpath->find('//jouhou/mei[$j]/toushu')->get_node(1)->string_value; } このままでは全く出なく、["$j"]とすると、出るには出るのですが「あ」が2回出てしまいます。 書き方が違うと思うのですが、()でくくってみても出ません。 ちなみに print $xpath->find('//jouhou/mei[1]/toushu')->get_node($j)->string_value; だと、ちゃんと「あ」と「い」が出ました…。 もし、お分かりになれば教えていただきたいです。 お手数をおかけしますが、よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • XML::DOM / XML::XPathでソート

    XML::DOMで効率的なソートの方法はどんなものがありますでしょうか。 一応動くものは作れたのですが、効率的とは言い難く、しかも ソート項目が一意のデータでないといけないという欠点があります。 ############################################### use XML::DOM::XPath; my $xml = <<EOM; <?xml version="1.0" encoding="UTF-8" ?> <list> <item id="10">Apple</item> <item id="5">Orange</item> <item id="20">Melon</item> </list> EOM my $parser = XML::DOM::Parser->new(); my $doc = $parser->parse( $xml ); ## <item>タグの一覧を作成 my @list = $doc->findnodes('/list/item'); ## <item>タグ id属性一覧を作成 my @idlist = map{ $_->getAttribute("id") } @list; ## id属性順にソート foreach my $id ( sort{ $a<=>$b } @idlist ){ ## id属性値を指定してノードリストを取得 my @item = $doc->findnodes('/list/item[@id='.$id.']'); ## idは一意なのでリストの先頭で固定 print $item[0]->getAttribute('id')."\n"; print $item[0]->getFirstChild->getNodeValue."\n"; } ############################################### ハッシュなら sort{ $hoe{$b} <=> $hoe{$a} } keys %hoe といった方法があるのですが、XML::DOMの場合は同じようにいきません。 良い方法がありましたらお願いします。

    • ベストアンサー
    • Perl
  • youtube api HASH(0x856eaec)の謎

    googlenewsのapiにつづいてyoutubeのapiと格闘しています。 その際、TreePPモジュールを利用しているのですが、 どうしても解決できない問題があり、御相談させて下さい。 目標:youtubeのデータベースに人名で検索をかけ、その結果のリスト(XML)の中から、動画タイトルと動画IDを取り出す。 で、以下のプログラムで、動画IDは取り出せるのですが、動画タイトルの部分が HASH(0x856eaec) といた様な表示になってしまうのです。 ●どの様な状態の時に、HASH(0x856eaec)の様なものが表示されるのでしょうか(そもそも、これって何の値なんでしょうか?) ●動画タイトルを取り出すには、どの部分をどう修正すればいいのでしょうか? ●$ua->timeout(3);の部分で、タイムアウト処理をかましているつもりなのですが、どうも稼働している様には感じません。この様なプログラムの場合に、タイムアウト処理をかませるには、どうしたらよいのでしょうか? 以上3点、アドバイスいただければ幸です。 尚、当該xmlのタグ構造はコチラで確認していただけます。 http://gdata.youtube.com/feeds/api/videos?vq=aiko&start-index=1&max-results=50&orderby=relevance&alt=atom 以下、そのプログラムです。 ------------------------------ #!/usr/local/bin/perl print <<"HTML"; Content-type: text/html <html> HTML # 動画スタートnoを乱数で決める srand; $startno = rand; $startno =( int($startno * 6))+1; # モジュールのロード use Jcode; use XML::TreePP; # 検索単語の設定 $searchword = "aiko"; use Encode; #検索キーワードをUTF-8コードに変換する Encode::from_to($searchword , 'sjis', 'utf8'); #URLエンコードを行う $searchword=~s/([^0-9A-Za-z_])/'%'.unpack('H2',$1)/ge; $searchword=~s/\s/+/g; use LWP::UserAgent; use HTTP::Request; my $url = 'http://gdata.youtube.com/feeds/api/videos?vq='.$searchword.'&start-index='.$startno.'&max-results=50&orderby=relevance&alt=atom'; # XML::TreePPオブジェクトの作成 my $tpp = XML::TreePP->new( force_array => [ "entry" ], ); # parsehttpメソッドでURLからXMLデータを取得して $tree変数に格納 my $tree = $tpp->parsehttp( GET => "$url" ); $ua = LWP::UserAgent->new(); $tpp->set( lwp_useragent => $ua ); $ua->timeout(3); # [rss] - [channel] - [item] を $Items変数に格納 my $Items = $tree->{feed}->{entry}; # 検索結果を表示 foreach my $hash (@$Items){ $urlyou=$hash->{id}; $titleyou=$hash->{title}; $idyou = substr($urlyou,42,11); print "$titleyou".$idyou."<BR>"; }

    • ベストアンサー
    • Perl
  • PerlでXMLがデコード出来ません。

    いつもお世話になっております。 今回も質問させていただきます。 PerlでhttpリクエストをしてXMLで返ってくるapiを使っているのですが、 英語で返答が来る時にはバックスラッシュが入っておらず成功するのですが、 日本語で返答が来ると、バックスラッシュがxml内部に記述されて Cannot decode string with wide characters と怒られます。 my $http2 = get($trans_url); my $result2=XML::Simple->new()->XMLin($http2); use CGI::Carp qw(fatalsToBrowser); die Dumper $result2; とダンプすると 成功するとき <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">testtest</string> 失敗するとき <string xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/\">\x{79c1}\x{306f}\x{65e5}\x{672c}\x{4eba}\x{3067}\x{3059}\x{3002}</string> と、明らかに「¥」が入っているときにデコードに失敗しているのですが、 このXMLの中の”の前の¥マークを取り除くことが出来ませんか? お知恵を拝借できればと思います。 どうぞよろしくお願いいたします。

    • ベストアンサー
    • Perl
  • [Perl]XML::SimpleでSJIS

    Windows7、ActivePerl v5.24.1を使っています。 use XML::Simple; use Data::Dumper; my $data = XMLin('test.xml'); print Dumper($data); というコードで、以下のXMLファイルを読み込むと、 <?xml version="1.0" encoding="shift_jis"?> <root> <top id="1234"> <second>値</second> <third> <fourth>1234</fourth> <fifth>myvalue</fifth> </third> </top> </root> Couldn't open encmap shift_jis.enc: No such file or directory at C:/Perl/lib/XML/Parser.pm line 187. XML::Simple called at read_xml_test.pl line 10. というエラーがでます。 ググると、以下のサイトで解決できたという記事がヒットしますが このサイトはもう存在しません。 Perl XMLでencoding=’Shift_JIS’や’euc-jp’を使う http://homepage3.nifty.com/hippo2000/perltips/xml/xmlenc.htm なにかコード間のマップファイルと思われますが、 どなたかお持ちじゃないでしょうか?

  • 「認証情報をヘッダに挿入したGETリクエストを送信

    表題のとおり「GETリクエストのヘッダにX-WSSE認証を追加して送出する」方法がわからず困っています。 なぜそれをやりたいかと申しますと ライブドアブログに投稿するのに、XML::Atomを使った方法はわかったのですが、 XML::Atomを使わないでやるにはどうしたらいいのかとおもい試しています。 http://www.witha.jp/Atom/Chapter-3_The_Atom_Publishing_Protocol_or_AtomAPI.html#Atom3-4-3 によりますと、 ---- エンドポイントのhttp://cms.blog.livedoor.com/atomに認証情報をヘッダに挿入したGETリクエストを送信します.  生のHTTP通信は以下のようになります. リクエスト: GET http://cms.blog.livedoor.com/atom HTTP/1.1 X-WSSE: UsernameToken Username="***", PasswordDigest="eNSBiuFfcLpau1RfWc3lOWufje0=", Nonce="ZGFrZHZueGJ6aGh1", Created="2004-10-31T14:08:34Z" --- と、あっさり書いてあるのですが、 ◆「認証情報をヘッダに挿入したGETリクエストを送信」◆はどうやれば良いのやら・・・ 強引にこうかいてみたのですが・・ -------- use LWP::UserAgent; $request = HTTP::Request->new(GET => 'http://cms.blog.livedoor.com/atom', ['X-WSSE'=>'User nameToken Username="*****", PasswordDigest="KxZ4DElJVqsIBXiF9ZIWCp59ghM", Nonce="YWFh", Created="2004-01-20T01:09:39Z"']); $ua = LWP::UserAgent->new; $response = $ua->request($request); print $response->content; ---------- 以下のように成ってしまいました。 ---------------- <?xml version="1.0" encoding="utf-8"?> <error>Invalid login</error> ---------------- どうかよろしくおねがいします。

    • ベストアンサー
    • Perl
  • XML::XPathを使う

    エラーがでて期待する出力が出ず困っています。 ファイル名とXPathのコマンドライン引数をとり、 指定されたパスに一致するノードを出力するものです。 (参考書の写しなので、記述ミスはないと思います。) ■grabber.pl use XML::XPath; use XML::XPath::XMLParser; my $xpath = XML::XPath->new( filename => shift @ARGV ); my $nodeset = $xpath->find( shift @ARGV ); foreach my $node ( nodeset->get_nodelist ) { print XML::XPath::XMLParser::as_string( $node ) . "\n"; } コマンドラインに入力しているものは、 perl grabber.pl data.xml "/inventory/category/item/name" ■data.xml <?xml version="1.0"?> <inventory date="2001"> <category> <item id="2"> <name>aaaa</name> </item> </category> </inventory> です。 perl grabber.pl data.xml "/inventory/category/item/name" としても、下記にエラーが出ます。 Can't locate object method "get_nodelist" via package "nodeset" (perhaps you for got to load "nodeset"?) at grabber.pl line 5. いろいろ試してみたり調べたのですが、 行き詰ってしまいました。 期待する出力は"<name>aaaa</name>"なのですが・・・ どなたかこのエラーの原因がおわかりになるかた いらっしゃいますでしょうか。 環境は以下になります。 ・windowsxp ・activePerl モジュールのインストール済み ・XML-XPath ・XML-Parser 以上です。

    • ベストアンサー
    • Perl

専門家に質問してみよう