--- title: JSONの構造をグラフ化する author: kazu634 date: 2009-08-10 wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:4753;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - Perl ---

はてぶで話題になっていたGraph::Easyを用いてJSONの構造をグラフ化してみました。JSONのデータはiTunesのWebAPIをたたいた結果を用いてみました。

Perlソース

use strict;
use warnings;
use Perl6::Say;
use WebService::Simple;
use JSON::Syck;
use Data::Dumper;
use utf8;
use Graph::Easy;
# === Main Part ===
# iTunesのWebAPIをたたくための準備
my $itunes = WebService::Simple->new(
base_url =>
"http://ax.phobos.apple.com.edgesuite.net/WebObjects/MZStoreServices.woa/wa/wsSearch",
param => {
country => 'JP',
lang    => 'ja_jp',
}
);
# 「手紙」と「アンジェラ・アキ」で検索
my $response = $itunes->get( { term => "手紙 + アンジェラ・アキ", } );
# 返ってきたJSONを読み込む
my $data = JSON::Syck::Load( $response->content );
# グラフを作成
my $graph = Graph::Easy->new();
# JSONの構造を再帰的に取得する。
# recursive_lookは
#   (1) JSONを格納したリファレンス変数
#   (2) リファレンス変数をrefした結果
#   (3) 親のノードを示す文字列
# という引数を取る
recursive_look( $data, ref($data), "Root" );
# グラフの構造をgraphvizで読み込める形式に出力する
print $graph->as_graphviz();
sub recursive_look {
my ( $ref, $type, $parent ) = @_;
# ハッシュだったら
if ( $type eq 'HASH' ) {
foreach my $x ( keys %{$ref} ) {
$graph->add_edge_once( $parent, $x );
recursive_look( $ref->{$x}, ref( $ref->{$x} ), $x );
}
}
# 配列だったら
elsif ( $type eq 'ARRAY' ) {
foreach my $x ( @{$ref} ) {
$graph->add_edge_once( $parent, "Array" );
recursive_look( $x, ref($x), "Array" );
}
}
else {
#        $graph->add_edge_once( $parent, $ref );
}
}

実行例

~/working/tmp_perl on simoom634 [542] $: perl test.pl > output.dot
~/working/tmp_perl on simoom634 [543] $: cat output.dot
digraph GRAPH_0 {
// Generated by Graph::Easy .64 at Mon Aug 10 23:08:26 2009
edge [ arrowhead=open ];
graph [ rankdir=LR ];
node [
fontsize=11,
fillcolor=white,
style=filled,
shape=box ];
Root -> resultCount [ color="#000000" ]
Root -> results [ color="#000000" ]
results -> Array [ color="#000000" ]
Array -> collectionCensoredName [ color="#000000" ]
Array -> trackCensoredName [ color="#000000" ]
Array -> collectionPrice [ color="#000000" ]
Array -> currency [ color="#000000" ]
Array -> primaryGenreName [ color="#000000" ]
Array -> collectionViewUrl [ color="#000000" ]
Array -> trackNumber [ color="#000000" ]
Array -> discCount [ color="#000000" ]
Array -> previewUrl [ color="#000000" ]
Array -> collectionId [ color="#000000" ]
Array -> trackId [ color="#000000" ]
Array -> artistId [ color="#000000" ]
Array -> trackTimeMillis [ color="#000000" ]
Array -> trackViewUrl [ color="#000000" ]
Array -> trackName [ color="#000000" ]
Array -> wrapperType [ color="#000000" ]
Array -> kind [ color="#000000" ]
Array -> collectionExplicitness [ color="#000000" ]
Array -> trackExplicitness [ color="#000000" ]
Array -> artistName [ color="#000000" ]
Array -> discNumber [ color="#000000" ]
Array -> collectionName [ color="#000000" ]
Array -> artistViewUrl [ color="#000000" ]
Array -> "artworkUrl100" [ color="#000000" ]
Array -> country [ color="#000000" ]
Array -> trackCount [ color="#000000" ]
Array -> "artworkUrl60" [ color="#000000" ]
Array -> trackPrice [ color="#000000" ]
}
~/working/tmp_perl on simoom634 [544] $: dot -Tgif output.dot -o foo.png

出力された画像

from typhoon634

参考