XML-TreePP-0.39/0000755000175100017510000000000011222330343012441 5ustar u-sukeu-sukeXML-TreePP-0.39/t/0000755000175100017510000000000011222330343012704 5ustar u-sukeu-sukeXML-TreePP-0.39/t/31_tie_ixhash.t0000755000175100017510000000572610652552410015545 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- SKIP: { local $@; eval { require Tie::IxHash; } unless defined $Tie::IxHash::VERSION; if ( ! defined $Tie::IxHash::VERSION ) { plan skip_all => 'Tie::IxHash is not loaded.'; } plan tests => 19; use_ok('XML::TreePP'); &test_parse(); &test_write(); &test_parse_with_attr(); &test_write_with_attr(); } # ---------------------------------------------------------------- sub test_parse { my $xml = <<"EOT"; 1 2 3 4 5 6 7 8 9 EOT my $tpp = XML::TreePP->new(); $tpp->set( use_ixhash => 1 ); my $tree = $tpp->parse( $xml ); my $prev; foreach my $key ( keys %{$tree->{root}} ) { my $val = $tree->{root}->{$key}; is( $prev+1, $val, "<$key>$val" ) if $prev; $prev = $val; } } # ---------------------------------------------------------------- sub test_write { my $root = {}; tie( %$root, 'Tie::IxHash' ); $root->{one} = 1; $root->{two} = 2; $root->{three} = 3; $root->{four} = 4; $root->{five} = 5; $root->{six} = 6; $root->{seven} = 7; $root->{eight} = 8; $root->{nine} = 9; my $tree = { root => $root }; my $tpp = XML::TreePP->new(); $tpp->set( use_ixhash => 1 ); my $xml = $tpp->write( $tree ); like( $xml, qr{1.*2.*3.*4.*5.*6.*7.*8.*9}s, "1-2-3-4-5-6-7-8-9" ); } # ---------------------------------------------------------------- sub test_parse_with_attr { my $xml = <<"EOT"; 6 7 8 9 EOT my $tpp = XML::TreePP->new(); $tpp->set( use_ixhash => 1 ); my $tree = $tpp->parse( $xml ); my $prev; foreach my $key ( keys %{$tree->{root}} ) { my $val = $tree->{root}->{$key}; my $view = ( $key =~ /^-/ ) ? "$key=" : "<$key>"; is( $prev+1, $val, $view.$val ) if $prev; $prev = $val; } } # ---------------------------------------------------------------- sub test_write_with_attr { my $root = {}; tie( %$root, 'Tie::IxHash' ); $root->{one} = 1; $root->{two} = 2; $root->{-three} = 3; $root->{-four} = 4; $root->{-five} = 5; $root->{-six} = 6; $root->{-seven} = 7; $root->{eight} = 8; $root->{nine} = 9; my $tree = { root => $root }; my $tpp = XML::TreePP->new(); $tpp->set( use_ixhash => 1 ); my $xml = $tpp->write( $tree ); like( $xml, qr{3.*4.*5.*6.*7.*1.*2.*8.*9}s, "3-4-5-6-7-1-2-8-9" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/16_encoding_ko.t0000755000175100017510000000216410432046334015672 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 5; # ---------------------------------------------------------------- my $FILES = [qw( t/example/hello-ko-euc.xml t/example/hello-ko-utf8.xml )]; # ---------------------------------------------------------------- SKIP: { skip( "Perl $]", 5 ) if ( $] < 5.008 ); use_ok('XML::TreePP'); &test_main(); } # ---------------------------------------------------------------- sub test_main { my $tpp = XML::TreePP->new(); my $prev; foreach my $file ( @$FILES ) { my $tree = $tpp->parsefile( $file ); if ( defined $prev ) { is( $tree->{root}->{text}, $prev, $file ); } else { like( $tree->{root}->{text}, qr/\S\!/, $file ); $prev = $tree->{root}->{text}; } my $xml = $tpp->write( $tree ); like( $xml, qr/^\s*<\?xml[^<>]+encoding="UTF-8"/is, "write encoding" ); } } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/42_cdata_comment.t0000755000175100017510000000474510676265315016233 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 129; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- { my $test = { '' => 'AAA', 'AAACCC' => 'AAABBBCCC', 'BBB' => 'AAABBBCCC', 'AAACCCEEE' => 'AAABBBCCCDDDEEE', '' => '', 'AAACCC' => 'AAACCC', 'BBB' => 'BBB', 'AAACCCEEE' => 'AAACCCEEE', 'BBB' => 'BBBCCC', 'BBB' => 'AAABBB', 'BBBDDD' => 'BBBCCCDDD', 'BBBDDD' => 'AAABBBDDDEEE', ']]>' => '', '' => '', ']]>' => '', ']]>' => '', }; &cdata_cdsect( $test ); &cdata_cdsect( $test, { cdata_scalar_ref=>1 } ); } # ---------------------------------------------------------------- sub cdata_cdsect { my $list = shift; my $opt = shift; my $tpp = XML::TreePP->new( %$opt ); foreach my $src ( keys %$list ) { my $val = $list->{$src}; my $tree = $tpp->parse( $src ); ok( exists $tree->{xml}, 'exists' ); my $cdata = $tree->{xml}; $cdata = $$cdata if ( ref $cdata eq 'SCALAR' ); ok( ! ref $cdata, 'invalid ref' ); is( $cdata, $val, $val ); my $xml = $tpp->write( $tree ); my $again = $tpp->parse( $xml ); my $cdat2 = $again->{xml}; $cdat2 = $$cdat2 if ( ref $cdat2 eq 'SCALAR' ); is( $cdat2, $cdata, 'round trip' ); } } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/02_write.t0000755000175100017510000000230610467562467014560 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 6; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $tpp = XML::TreePP->new(); my $tree = { rss => { channel => { item => [ { title => "The Perl Directory", link => "http://www.perl.org/", }, { title => "The Comprehensive Perl Archive Network", link => "http://cpan.perl.org/", } ] } } }; my $xml = $tpp->write( $tree ); like( $xml, qr{^<\?xml version="1.0" encoding="UTF-8"}, "xmldecl" ); like( $xml, qr{.*}s, "rss" ); my $back = $tpp->parse( $xml ); is_deeply( $tree, $back, "write and parse" ); # 2006/08/13 added $tpp->set( xml_decl => '' ); my $nodecl = $tpp->write( $back ); unlike( $nodecl, qr{^<\?xml}, "xml_decl is null" ); my $decl = ''; $tpp->set( xml_decl => $decl ); my $setdecl = $tpp->write( $back ); like( $setdecl, qr{^\Q$decl\E}, "xml_decl is set" ); # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/32_base_class.t0000755000175100017510000000413010655660723015516 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { plan tests => 14; use_ok('XML::TreePP'); &test_base_class( force_array => [qw( six )], base_class => 'Element' ); } # ---------------------------------------------------------------- sub test_base_class { my $tpp = XML::TreePP->new(@_); my $xml = <<"EOT"; 1 2 4 5 5 7 8 9 EOT my $tree = $tpp->parse( $xml ); is( ref $tree, 'Element', '/root' ); is( ref $tree->{root}, 'Element::root', '/root' ); is( ref $tree->{root}->{two}, 'Element::root::two', '/root/two' ); is( ref $tree->{root}->{three}, 'Element::root::three', '/root/three' ); is( ref $tree->{root}->{three}->{five}, 'Element::root::three::five', '/root/three/five' ); is( ref $tree->{root}->{six}, 'ARRAY', '/root/six (ARRAY)' ); is( ref $tree->{root}->{six}->[0], 'Element::root::six', '/root/six' ); is( ref $tree->{root}->{six}->[0]->{seven}, 'Element::root::six::seven', '/root/six/seven' ); is( ref $tree->{root}->{eight}, 'ARRAY', '/root/eight (ARRAY)' ); is( ref $tree->{root}->{eight}->[1], 'Element::root::eight', '/root/eight' ); # 2007/08/07 added is( ref $tree->{root}->{foo}, 'Element::root::foo', '/root/foo' ); is( ref $tree->{root}->{foo}->{bar}, 'ARRAY', '/root/foo/bar (ARRAY)' ); is( ref $tree->{root}->{foo}->{bar}->[0], 'Element::root::foo::bar', '/root/foo/bar' ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/49_invalid_encoding.t0000755000175100017510000000314411152511332016707 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { local $@; eval { require 5.008001; }; plan skip_all => 'Perl 5.8.1 is required.' if $@; } # ---------------------------------------------------------------- my $ENC = 'UNKNOWN_ENCODING'; # ---------------------------------------------------------------- { plan tests => 4; use_ok('XML::TreePP'); &test1(); &test2(); &test3(); } # ---------------------------------------------------------------- sub test1 { my $xml = <<"EOT"; value EOT my $tpp = XML::TreePP->new(); local $@; eval { my $tree = $tpp->parse( $xml ); }; like( $@, qr#^Unknown encoding#, 'parse: '.$@ ); } # ---------------------------------------------------------------- sub test2 { my $tree = { root => { elem => 'value' }}; my $tpp = XML::TreePP->new(); local $@; eval { my $xml = $tpp->write( $tree, $ENC ); }; like( $@, qr#^Unknown encoding#, 'write: '.$@ ); } # ---------------------------------------------------------------- sub test3 { my $tree = { root => { elem => 'value' }}; my $tpp = XML::TreePP->new( output_encoding => $ENC ); local $@; eval { my $xml = $tpp->write( $tree ); }; like( $@, qr#^Unknown encoding#, 'output_encoding: '.$@ ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/24_ignore_error.t0000755000175100017510000000145210467627612016121 0ustar u-sukeu-suke use strict; use Test::More tests => 7; BEGIN { use_ok('XML::TreePP') }; &no_carp( \&invalid_tag, qr{Invalid tag sequence}i ); &no_carp( \&no_such_file, qr{file-not-found}i ); &no_carp( \&invalid_tree, qr{Invalid tree}i ); sub no_carp { my $sub = shift; my $err = shift; local $@; &$sub( ignore_error => 1 ); ok( ! $@, 'ignore error' ); eval { &$sub(); }; like( $@, $err, 'raise error' ); } sub invalid_tag { my $tpp = XML::TreePP->new( @_ ); my $xml = ''; return $tpp->parse( $xml ); } sub no_such_file { my $tpp = XML::TreePP->new( @_ ); return $tpp->parsefile( 'file-not-found-'.$$ ); } sub invalid_tree { my $tpp = XML::TreePP->new( @_ ); return $tpp->write( undef ); } ;1; XML-TreePP-0.39/t/27_http-lite-force.t0000755000175100017510000000411310655240317016423 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- SKIP: { local $@; eval { require HTTP::Lite; } unless defined $HTTP::Lite::VERSION; if ( ! defined $HTTP::Lite::VERSION ) { plan skip_all => 'HTTP::Lite is not loaded.'; } eval { require LWP::UserAgent; } unless defined $LWP::UserAgent::VERSION; if ( ! defined $LWP::UserAgent::VERSION ) { # ok } if ( ! defined $ENV{MORE_TESTS} ) { plan skip_all => 'define $MORE_TESTS to test this.'; } plan tests => 14; use_ok('XML::TreePP'); my $name = 'HTTP::Lite'; my $url = "http://www.kawa.net/works/perl/treepp/example/envxml.cgi"; my $query = time(); { my $tpp = XML::TreePP->new(); my $http = HTTP::Lite->new(); ok( ref $http, 'HTTP::Lite->new()' ); $tpp->set( http_lite => $http ); $tpp->set( user_agent => '' ); &test_http_req( $tpp, $name, POST => $url, $query ); # use HTTP::Lite } { my $tpp = XML::TreePP->new(); my $http = HTTP::Lite->new(); ok( ref $http, 'HTTP::Lite->new()' ); $tpp->set( http_lite => $http ); $tpp->set( user_agent => '' ); my $ret = &test_http_req( $tpp, $name, GET => "$url?$query" ); is( $ret, $query, "QUERY_STRING: $query" ); } } # ---------------------------------------------------------------- sub test_http_req { my $tpp = shift; my $name = shift; my( $tree, $xml, $code ) = $tpp->parsehttp( @_ ); ok( ref $tree, "parsehttp: $_[1]" ); my $decl = ( $xml =~ /(<\?xml[^>]+>)/ )[0]; like( $xml, qr/(<\?xml[^>]+>)/, "XML Decl: $decl" ); is( $code, 200, "HTTP Status: $code" ); my $agent = $tree->{env}->{HTTP_USER_AGENT}; ok( $agent, "User-Agent: $agent" ); like( $agent, qr/\Q$name\E/, "Match: $name" ); $tree->{env}->{QUERY_STRING}; } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/43_encoding_quote.t0000755000175100017510000000247010715550725016426 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 5; # ---------------------------------------------------------------- SKIP: { skip( "Perl $]", 5 ) if ( $] < 5.008 ); use_ok('XML::TreePP'); use_ok('Encode'); &test_main(); } # ---------------------------------------------------------------- sub test_main { my $tpp = XML::TreePP->new(); my $xml1 = "FOO"; my $tree1 = $tpp->parse( $xml1 ); is( $tree1->{root}, 'FOO', 'windows-1250' ); # 0xxxxxxx (00-7f) # 110xxxxx 10xxxxxx (c0-df)(80-bf) # 1110xxxx 10xxxxxx 10xxxxxx (e0-ef)(80-bf)(80-bf) my $soa = "\xEA\x92\xB1"; # is a valid Shift_JIS string my $xml3 = "$soa"; my $tree3 = $tpp->parse( $xml3 ); Encode::from_to( $soa, 'Shift_JIS', 'utf8' ); is( $tree3->{root}, $soa, 'Shift_JIS' ); my $xml2 = "BAR"; local $@; eval { $tpp->parse( $xml2 ); }; like( $@, qr/INVALID_ENCODING/, 'INVALID_ENCODING' ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/37_undef.t0000755000175100017510000000227710661673143014534 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { plan tests => 6; use_ok('XML::TreePP'); &test_undef( first_out => [qw( attr hash list empty undef -one -two three four )] ); } # ---------------------------------------------------------------- sub test_undef { my $tpp = XML::TreePP->new(@_); my $empty = ''; my $undef = undef; my $tree = { root => { attr => { -one=>'', -two=>undef }, hash => { three => '', four => undef }, list => [ '', undef ], empty => \$empty, undef => \$undef, } }; my $xml = $tpp->write( $tree ); like( $xml, qr{\s*\s* 5; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- { my $tpp = XML::TreePP->new(); my $scalar = 'string'; { local $@; eval { my $xml = $tpp->write( undef ); }; like( $@, qr#^Invalid tree#, 'undef: '.$@ ); } { local $@; eval { my $xml = $tpp->write( [] ); }; like( $@, qr#^Invalid tree#, 'arrayref: '.$@ ); } { local $@; eval { my $xml = $tpp->write( $scalar ); }; like( $@, qr#^Invalid tree#, 'scalar: '.$@ ); } { local $@; eval { my $xml = $tpp->write( \$scalar ); }; like( $@, qr#^Invalid tree#, 'scalarref: '.$@ ); } } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/35_force_hash.t0000755000175100017510000000446410655240711015524 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 23; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $source = <<"EOT"; ZZZ AAA BBB EEE EOT # ---------------------------------------------------------------- { my $tpp = XML::TreePP->new( force_hash => [qw( one two three )] ); my $tree = $tpp->parse( $source ); ok( ! ref $tree->{root}->{zero}, "A: zero" ); ok( ref $tree->{root}->{one}, "A: one" ); ok( ref $tree->{root}->{two}->[0], "A: two with text node" ); ok( ref $tree->{root}->{two}->[1], "A: two with attribute" ); ok( ref $tree->{root}->{three}->[0], "A: three with both text node and attribute" ); ok( ref $tree->{root}->{three}->[1], "A: three empty node 1" ); ok( ref $tree->{root}->{three}->[2], "A: three empty node 2" ); is( $tree->{root}->{zero}, 'ZZZ', "A: ZZZ" ); is( $tree->{root}->{one}->{'#text'}, 'AAA', "A: AAA" ); is( $tree->{root}->{two}->[0]->{'#text'}, 'BBB', "A: BBB" ); is( $tree->{root}->{three}->[0]->{'#text'}, 'EEE', "A: EEE" ); } # ---------------------------------------------------------------- { my $tpp = XML::TreePP->new( force_hash => '*' ); my $tree = $tpp->parse( $source ); ok( ref $tree->{root}->{zero}, "B: zero" ); ok( ref $tree->{root}->{one}, "B: one" ); ok( ref $tree->{root}->{two}->[0], "B: two with text node" ); ok( ref $tree->{root}->{two}->[1], "B: two with attribute" ); ok( ref $tree->{root}->{three}->[0], "B: three with both text node and attribute" ); ok( ref $tree->{root}->{three}->[1], "B: three empty node 1" ); ok( ref $tree->{root}->{three}->[2], "B: three empty node 2" ); is( $tree->{root}->{zero}->{'#text'}, 'ZZZ', "B: ZZZ" ); is( $tree->{root}->{one}->{'#text'}, 'AAA', "B: AAA" ); is( $tree->{root}->{two}->[0]->{'#text'}, 'BBB', "B: BBB" ); is( $tree->{root}->{three}->[0]->{'#text'}, 'EEE', "B: EEE" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/18_escape_amp.t0000755000175100017510000000350210433667400015513 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 9; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $tpp = XML::TreePP->new(); my $space0 = ' '; my $space1 = ' '; my $entref0 = '&quot;&apos;&lt;&gt;&amp;'; my $entref1 = '"'<>&'; my $charref0 = "\x21\x22"; my $charref1 = '!"'; my $invalid0 = '&#32&#x20&#foo;&#ZZ&#&32;&x20;&bar'; my $invalid1 = ' &#foo;&#ZZ&#&32;&x20;&bar'; my $tree = { root => { space => $space1, entref => $entref1, charref => $charref1, invalid => $invalid1, }, }; my $write = $tpp->write( $tree ); my $space2 = ( $write =~ m#(.*)# )[0]; # through is( $space2, $space1, 'write space' ); my $entref2 = ( $write =~ m#(.*)# )[0]; # escaped is( $entref2, $entref0, 'write entref' ); my $charref2 = ( $write =~ m#(.*)# )[0]; # through is( $charref2, $charref1, 'write charref' ); my $invalid2 = ( $write =~ m#(.*)# )[0]; # escaped is( $invalid2, $invalid0, 'write invalid' ); my $parse = $tpp->parse( $write ); is( $parse->{root}->{space}, $space0, 'write space' ); # unescaped is( $parse->{root}->{entref}, $entref1, 'write entref' ); # unescaped is( $parse->{root}->{charref}, $charref0, 'write charref' ); # unescaped is( $parse->{root}->{invalid}, $invalid1, 'write invalid' ); # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/29_http-lwp-withcache.t0000755000175100017510000000300010650623015017120 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- SKIP: { local $@; eval { require LWP::UserAgent::WithCache; } unless defined $LWP::UserAgent::WithCache::VERSION; if ( ! defined $LWP::UserAgent::WithCache::VERSION ) { plan skip_all => 'LWP::UserAgent::WithCache is not loaded.'; } if ( ! defined $ENV{MORE_TESTS} ) { plan skip_all => 'define $MORE_TESTS to test this.'; } plan tests => 6; use_ok('XML::TreePP'); my $http = LWP::UserAgent::WithCache->new(); ok( ref $http, 'LWP::UserAgent::WithCache' ); my $name = ( $0 =~ m#([^/:\\]+)$# )[0]; $http->agent( "$name " ); my $tpp = XML::TreePP->new(); $tpp->set( lwp_useragent => $http ); &test_http_post( $tpp, $name ); # use LWP::UserAgent::WithCache } # ---------------------------------------------------------------- sub test_http_post { my $tpp = shift; my $name = shift; my $url = "http://www.kawa.net/works/perl/treepp/example/envxml.cgi"; my( $tree, $xml ) = $tpp->parsehttp( POST => $url, '' ); ok( ref $tree, $url ); my $agent = $tree->{env}->{HTTP_USER_AGENT}; ok( $agent, "User-Agent: $agent" ); like( $agent, qr/libwww-perl/, "Test: libwww-perl" ); like( $agent, qr/\Q$name\E/, "Test: $name" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/44_utf8_bom.t0000755000175100017510000000320210737373025015141 0ustar u-sukeu-suke# ---------------------------------------------------------------- # this test script is written in utf8 but does not "use utf8" for 5.005-compatibility # ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { local $@; eval { require 5.008001; }; plan skip_all => 'Perl 5.8.1 is required.' if $@; } # ---------------------------------------------------------------- my $FILES = [qw( t/example/hello-en-utf8.xml t/example/hello-en-nodecl.xml t/example/hello-en-noenc.xml t/example/hello-en-utf8-bom.xml t/example/hello-en-nodecl-bom.xml t/example/hello-en-noenc-bom.xml )]; # ---------------------------------------------------------------- { plan tests => 13; use_ok('XML::TreePP'); &test_main(); } # ---------------------------------------------------------------- sub test_main { my $octets = 'Hello, World! §±×÷'; my $string = $octets; require utf8; utf8::decode( $string ); my $tpp1 = XML::TreePP->new( utf8_flag => 0 ); my $tpp2 = XML::TreePP->new( utf8_flag => 1 ); foreach my $file ( @$FILES ) { my $tree1 = $tpp1->parsefile( $file ); is( $tree1->{root}->{text}, $octets, $file." without utf8_flag" ); my $tree2 = $tpp2->parsefile( $file ); is( $tree2->{root}->{text}, $string, $file." with utf8_flag" ); } } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/04_escape.t0000755000175100017510000000353310432030042014636 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 9; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $tpp = XML::TreePP->new(); my $source = '<>&"'&gt;&lt;BBB'; my $tree = $tpp->parse( $source ); is( $tree->{root}->{text}, '<>&"\'><', "parse text node" ); is( $tree->{root}->{cdata}, '<>&"'&gt;&lt;', "parse cdata node" ); is( $tree->{root}->{attr}->{'-key'}, '<>&"\'><', "parse attribute" ); $tree->{root}->{text_add} = '<>&"'&gt;&lt;'; my $cdata_raw = $tree->{root}->{cdata}; $tree->{root}->{cdata_ref} = \$cdata_raw; my $back = $tpp->write( $tree ); my $text = ( $back =~ m#(.*)# )[0]; is( $text, '<>&"'&gt;&lt;', "write text node" ); my $cdata = ( $back =~ m#(.*)# )[0]; is( $cdata, '&lt;&gt;&amp;&quot;&apos;&amp;gt;&amp;lt;', "write cdata node (as text node)" ); my $attr = ( $back =~ m## )[0]; is( $attr, '<>&"'&gt;&lt;', "write attribute" ); my $tadd = ( $back =~ m#(.*)# )[0]; is( $tadd, '&lt;&gt;&amp;&quot;&apos;&amp;gt;&amp;lt;', "write new var" ); my $cref = ( $back =~ m#(.*)# )[0]; is( $cref, '', "write cdata node (as cdata)" ); # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/14_encoding_zh.t0000755000175100017510000000223310432046263015676 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 7; # ---------------------------------------------------------------- my $FILES = [qw( t/example/hello-zh-utf8.xml t/example/hello-zh-big5.xml t/example/hello-zh-gb2312.xml )]; # ---------------------------------------------------------------- SKIP: { skip( "Perl $]", 7 ) if ( $] < 5.008 ); use_ok('XML::TreePP'); &test_main(); } # ---------------------------------------------------------------- sub test_main { my $tpp = XML::TreePP->new(); my $prev; foreach my $file ( @$FILES ) { my $tree = $tpp->parsefile( $file ); if ( defined $prev ) { is( $tree->{root}->{text}, $prev, $file ); } else { like( $tree->{root}->{text}, qr/\S\!/, $file ); $prev = $tree->{root}->{text}; } my $xml = $tpp->write( $tree ); like( $xml, qr/^\s*<\?xml[^<>]+encoding="UTF-8"/is, "write encoding" ); } } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/30_first_out.t0000755000175100017510000000242010650623116015421 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 3; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- { my $tree = { root => { one => 1, two => 2, three => 3, four => 4, five => 5, six => 6, seven => 7, eight => 8, nine => 9, }, }; { my $tpp = XML::TreePP->new(); $tpp->set( first_out => [qw( one two three )] ); $tpp->set( last_out => [qw( seven eight nine )] ); my $xml = $tpp->write( $tree ); like( $xml, qr{.*.*.*.*.*.*}s, "1-2-3-*-5-*-7-8-9" ); } { my $tpp = XML::TreePP->new(); $tpp->set( first_out => [qw( seven eight nine )] ); $tpp->set( last_out => [qw( one two three )] ); my $xml = $tpp->write( $tree ); like( $xml, qr{.*.*.*.*.*.*}s, "7-8-9-*-5-*-1-2-3" ); } } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/08_force_array.t0000755000175100017510000000573510655242075015726 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 25; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- { my $tpp = XML::TreePP->new( force_array => [qw( one two three )] ); my $source = <<"EOT"; AAA CCC DDDEEE EOT my $tree = $tpp->parse( $source ); ok( ! ref $tree->{root}->{zero}, "A: normal node" ); ok( ref $tree->{root}->{one} , "A: one force_array node" ); ok( ref $tree->{root}->{two} , "A: two child nodes" ); ok( ref $tree->{root}->{three} , "A: three empty nodes" ); is( scalar( @{$tree->{root}->{one}} ), 1, "A: one force_array node" ); is( scalar( @{$tree->{root}->{two}} ), 2, "A: two child nodes" ); is( scalar( @{$tree->{root}->{three}} ), 3, "A: three empty nodes" ); is( scalar( grep {$_} @{$tree->{root}->{one}} ), 1, "A: one force_array node" ); is( scalar( grep {$_} @{$tree->{root}->{two}} ), 2, "A: two child nodes" ); is( scalar( grep {$_} @{$tree->{root}->{three}} ), 0, "A: three empty nodes" ); } # ---------------------------------------------------------------- { my $tpp = XML::TreePP->new( force_array => [qw( one two three )] ); my $source = <<"EOT"; EOT my $tree = $tpp->parse( $source ); is( scalar( @{$tree->{root}->{one}} ), 1, "B: one force_array node" ); is( scalar( @{$tree->{root}->{two}} ), 2, "B: two child nodes" ); is( scalar( @{$tree->{root}->{three}} ), 3, "B: three empty nodes" ); is( scalar( grep {ref $_} @{$tree->{root}->{one}} ), 1, "B: one force_array node" ); is( scalar( grep {ref $_} @{$tree->{root}->{two}} ), 2, "B: two child nodes" ); is( scalar( grep {ref $_} @{$tree->{root}->{three}} ), 3, "B: three empty nodes" ); } # ---------------------------------------------------------------- { my $tpp = XML::TreePP->new( force_array => '*' ); my $source = <<"EOT"; 1 3 EOT my $tree = $tpp->parse( $source ); is( ref $tree->{root}, 'ARRAY', 'C: root ARRAY' ); is( ref $tree->{root}->[0], 'HASH', 'C: root HASH' ); is( ref $tree->{root}->[0]->{one}, 'ARRAY', 'C: one ARRAY' ); is( $tree->{root}->[0]->{one}->[0], '1', 'C: one text' ); is( ref $tree->{root}->[0]->{two}, 'ARRAY', 'C: two ARRAY' ); is( ref $tree->{root}->[0]->{two}->[0], 'HASH', 'C: two HASH' ); is( ref $tree->{root}->[0]->{two}->[0]->{three}, 'ARRAY', 'C: three ARRAY' ); is( $tree->{root}->[0]->{two}->[0]->{three}->[0], '3', 'C: three text' ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/48_blobref.t0000755000175100017510000000357211152507037015041 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 8; BEGIN { use_ok('XML::TreePP') }; ## ---------------------------------------------------------------- { my $scalar = 'value'; my $obj = MyObject->new( elem => 'value' ); my $tree1 = { hashref => { elem => 'value' } }; my $tree2 = { arrayref => { elem => [ 'first', 'last' ] }}; my $tree3 = { scalarref => \$scalar }; my $tree4 = { coderef => sub {} }; my $tree5 = { object => $obj }; my $tree6 = { blob => *STDIN }; my $tree7 = { blobref => \*STDIN }; my $tpp = XML::TreePP->new(); local $SIG{__WARN__} = sub {}; # ignore warn messages my $xml1 = $tpp->write( $tree1 ); like( $xml1, qr#value#, 'no1: HASHREF - child node' ); my $xml2 = $tpp->write( $tree2 ); like( $xml2, qr#first\s*last#s, 'no2: ARRAYREF - multiple nodes' ); my $xml3 = $tpp->write( $tree3 ); my $exp3 = ''; like( $xml3, qr#\Q$exp3\E#, 'no3: SCALARREF - cdata node' ); my $xml4 = $tpp->write( $tree4 ); like( $xml4, qr#xml#, 'no4: CODEREF - undefined behavior rather than die' ); my $xml5 = $tpp->write( $tree5 ); like( $xml5, qr#value#, 'no5: OBJECT - as a normal child node' ); my $xml6 = $tpp->write( $tree6 ); like( $xml6, qr#xml#, 'no6: BLOB - undefined behavior rather than die' ); my $xml7 = $tpp->write( $tree7 ); like( $xml7, qr#xml#, 'no7: BLOBREF - undefined behavior rather than die' ); } # ---------------------------------------------------------------- package MyObject; sub new { my $class = shift; my $hash = { @_ }; bless $hash, $class; } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/23_http-lwp-headers.t0000755000175100017510000000320410467562041016603 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- SKIP: { local $@; eval { require LWP::UserAgent; } unless defined $LWP::UserAgent::VERSION; if ( ! defined $LWP::UserAgent::VERSION ) { plan skip_all => 'LWP::UserAgent is not loaded.'; } if ( ! defined $ENV{MORE_TESTS} ) { plan skip_all => 'define $MORE_TESTS to test this.'; } plan tests => 8; use_ok('XML::TreePP'); my $tpp = XML::TreePP->new(); my $name = ( $0 =~ m#([^/:\\]+)$# )[0]; $tpp->set( user_agent => "$name " ); my $url = "http://www.kawa.net/works/perl/treepp/example/envxml.cgi"; my $tree1 = $tpp->parsehttp( POST => $url, '' ); ok( ref $tree1, "POST 1 $url" ); is( $tree1->{env}->{CONTENT_TYPE}, 'application/x-www-form-urlencoded', 'Content-Type (1) default' ); my $body = 'Hello, World!'; my $head2 = { Hoge => 'Pomu', }; my $tree2 = $tpp->parsehttp( POST => $url, $body, $head2 ); ok( ref $tree2, "POST 2" ); is( $tree2->{env}->{CONTENT_TYPE}, 'application/x-www-form-urlencoded', 'Content-Type (2) default' ); is( $tree2->{env}->{HTTP_HOGE}, 'Pomu', "Original Header" ); my $head3 = { 'Content-Type' => 'text/plain', }; my $tree3 = $tpp->parsehttp( POST => $url, $body, $head3 ); ok( ref $tree3, "POST 3" ); is( $tree3->{env}->{CONTENT_TYPE}, 'text/plain', 'Content-Type (3) change' ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/09_http-lite.t0000755000175100017510000000315110467560277015343 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- SKIP: { local $@; eval { require HTTP::Lite; } unless defined $HTTP::Lite::VERSION; if ( ! defined $HTTP::Lite::VERSION ) { plan skip_all => 'HTTP::Lite is not loaded.'; } if ( ! defined $ENV{MORE_TESTS} ) { plan skip_all => 'define $MORE_TESTS to test HTTP::Lite.'; } plan tests => 5; use_ok('XML::TreePP'); &parsehttp_get(); &parsehttp_post(); } # ---------------------------------------------------------------- sub parsehttp_get { my $tpp = XML::TreePP->new(); my $name = ( $0 =~ m#([^/:\\]+)$# )[0]; $tpp->set( user_agent => "$name " ); my $url = "http://use.perl.org/index.rss"; my $tree = $tpp->parsehttp( GET => $url ); ok( ref $tree, $url ); like( $tree->{"rdf:RDF"}->{channel}->{link}, qr{^http://}, "$url link" ); } # ---------------------------------------------------------------- sub parsehttp_post { my $tpp = XML::TreePP->new( force_array => [qw( item )] ); my $name = ( $0 =~ m#([^/:\\]+)$# )[0]; $tpp->set( user_agent => "$name " ); my $url = "http://search.hatena.ne.jp/keyword"; my $query = "ajax"; my $body = "mode=rss2&word=".$query; my $tree = $tpp->parsehttp( POST => $url, $body ); ok( ref $tree, $url ); like( $tree->{rss}->{channel}->{item}->[0]->{link}, qr{^http://}, "$url link" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/22_http-lite-headers.t0000755000175100017510000000323710467631040016737 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- SKIP: { local $@; eval { require HTTP::Lite; } unless defined $HTTP::Lite::VERSION; if ( ! defined $HTTP::Lite::VERSION ) { plan skip_all => 'HTTP::Lite is not loaded.'; } if ( ! defined $ENV{MORE_TESTS} ) { plan skip_all => 'define $MORE_TESTS to test this.'; } plan tests => 6; use_ok('XML::TreePP'); my $tpp = XML::TreePP->new(); my $name = ( $0 =~ m#([^/:\\]+)$# )[0]; $tpp->set( user_agent => "$name " ); my $url = "http://www.kawa.net/works/perl/treepp/example/envxml.cgi"; my $tree1 = $tpp->parsehttp( POST => $url, '' ); ok( ref $tree1, "POST 1 $url" ); is( $tree1->{env}->{CONTENT_TYPE}, 'application/x-www-form-urlencoded', 'Content-Type (1) default' ); my $body = 'Hello, World!'; my $head2 = { Hoge => 'Pomu' }; my $tree2 = $tpp->parsehttp( POST => $url, $body, $head2 ); ok( ref $tree2, "POST 2" ); is( $tree2->{env}->{CONTENT_TYPE}, 'application/x-www-form-urlencoded', 'Content-Type (2) default' ); is( $tree2->{env}->{HTTP_HOGE}, 'Pomu', "Original Header" ); # HTTP::Lite ignores Content-Type header. # my $head3 = { # 'Content-Type' => 'text/plain', # }; # my $tree3 = $tpp->parsehttp( POST => $url, $body, $head3 ); # ok( ref $tree3, "POST 3" ); # is( $tree3->{env}->{CONTENT_TYPE}, 'text/plain', 'Content-Type (3) change' ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/47_xml_deref_utf8.t0000755000175100017510000001323211134365103016326 0ustar u-sukeu-suke# ---------------------------------------------------------------- # this test script is written in utf8 but does not "use utf8" for 5.005-compatibility # ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { local $@; eval { require 5.008001; }; plan skip_all => 'Perl 5.8.1 is required.' if $@; } # ---------------------------------------------------------------- { plan tests => 155; use_ok('XML::TreePP'); &test_main(); } # ---------------------------------------------------------------- sub test_main { my $src = {}; $src->{Plain} = <<"EOT"; AA zz ©© ëë んん 漢漢 EOT $src->{XMLref} = <<"EOT"; AA zz ©© ëë んん 漢漢 EOT $src->{Mixed} = <<"EOT"; AA zz ©© ëë んん 漢漢 EOT foreach my $key ( keys %$src ) { phase2( "$key octets", $src->{$key} ); my $copy = $src->{$key}; utf8::decode( $copy ); next unless utf8::is_utf8($copy); phase2( "$key string", $copy ); } } # ---------------------------------------------------------------- sub phase2 { my $subject = shift; my $srcxml = shift; my $srcutf8 = utf8::is_utf8($srcxml); my $srcref = ( $srcxml =~ /&#\w+;/ ); foreach my $utf8_flag ( 0, 1 ) { my $subj2 = $subject .( $utf8_flag ? ' utf8_flag' : '' ); foreach my $xml_deref ( 0, 1 ) { my $subj3 = $subj2 .( $xml_deref ? ' xml_deref' : '' ); my $opt = { utf8_flag => $utf8_flag, xml_deref => $xml_deref, }; my $tpp = XML::TreePP->new( %$opt ); my $tree = $tpp->parse( $srcxml ); if ( $xml_deref ) { if ( $srcutf8 || $utf8_flag ) { check_string( $subj3, $tree ); } else { check_octets( $subj3, $tree ); } } else { if ( $srcref ) { check_has_ref( $subj3, $tree ); } else { check_no_ref( $subj3, $tree ); } } } } } # ---------------------------------------------------------------- sub check_has_ref { my $subject = shift; my $tree = shift; my $root = $tree->{root}; my $HAS_REF = qr/&#\w+;/; # \x00-\x7F is always dereferenced. # like( $root->{a}, $HAS_REF, "[$subject] has_ref: a" ); # like( $root->{z}, $HAS_REF, "[$subject] has_ref: z" ); like( $root->{c}, $HAS_REF, "[$subject] has_ref: c" ); like( $root->{e}, $HAS_REF, "[$subject] has_ref: e" ); like( $root->{n}, $HAS_REF, "[$subject] has_ref: n" ); like( $root->{k}, $HAS_REF, "[$subject] has_ref: k" ); } # ---------------------------------------------------------------- sub check_no_ref { my $subject = shift; my $tree = shift; my $root = $tree->{root}; my $HAS_REF = qr/&#\w+;/; unlike( $root->{a}, $HAS_REF, "[$subject] no_ref: a" ); unlike( $root->{z}, $HAS_REF, "[$subject] no_ref: z" ); unlike( $root->{c}, $HAS_REF, "[$subject] no_ref: c" ); unlike( $root->{e}, $HAS_REF, "[$subject] no_ref: e" ); unlike( $root->{n}, $HAS_REF, "[$subject] no_ref: n" ); unlike( $root->{k}, $HAS_REF, "[$subject] no_ref: k" ); } # ---------------------------------------------------------------- sub check_string { my $subject = shift; my $tree = shift; my $root = $tree->{root}; # \x00-\x7F never have utf8 flag # ok( utf8::is_utf8($root->{a}), "[$subject] is_utf8: a" ); # ok( utf8::is_utf8($root->{z}), "[$subject] is_utf8: z" ); ok( utf8::is_utf8($root->{c}), "[$subject] is_utf8: c" ); ok( utf8::is_utf8($root->{e}), "[$subject] is_utf8: e" ); ok( utf8::is_utf8($root->{n}), "[$subject] is_utf8: n" ); ok( utf8::is_utf8($root->{k}), "[$subject] is_utf8: k" ); is( $root->{a}, chr(0x0041) x 2, "[$subject] ok: a" ); is( $root->{z}, chr(0x007A) x 2, "[$subject] ok: z" ); is( $root->{c}, chr(0x00A9) x 2, "[$subject] ok: c" ); is( $root->{e}, chr(0x00EB) x 2, "[$subject] ok: e" ); is( $root->{n}, chr(0x3093) x 2, "[$subject] ok: n" ); is( $root->{k}, chr(0x6F22) x 2, "[$subject] ok: k" ); } # ---------------------------------------------------------------- sub check_octets { my $subject = shift; my $tree = shift; my $root = $tree->{root}; ok( ! utf8::is_utf8($root->{a}), "[$subject] is_octets: a" ); ok( ! utf8::is_utf8($root->{z}), "[$subject] is_octets: z" ); ok( ! utf8::is_utf8($root->{c}), "[$subject] is_octets: c" ); ok( ! utf8::is_utf8($root->{e}), "[$subject] is_octets: e" ); ok( ! utf8::is_utf8($root->{n}), "[$subject] is_octets: n" ); ok( ! utf8::is_utf8($root->{k}), "[$subject] is_octets: k" ); is( $root->{a}, 'AA', "[$subject] ok: a" ); is( $root->{z}, 'zz', "[$subject] ok: z" ); is( $root->{c}, '©©', "[$subject] ok: c" ); is( $root->{e}, 'ëë', "[$subject] ok: e" ); is( $root->{n}, 'んん', "[$subject] ok: n" ); is( $root->{k}, '漢漢', "[$subject] ok: k" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/12_escape_charref.t0000755000175100017510000000721711134361770016351 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 23; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $tpp = XML::TreePP->new(); my $source = ' ��  [ ] '."[\x09\x09]".' [ ] '."[\x0A\x0A]".' [ ] '."[\x0D\x0D]".' !! €ÿ€ÿ 漢漢 '; # ---------------------------------------------------------------- my $tree = $tpp->parse( $source ); # control chars are escaped/unescaped. is( $tree->{root}->{t1_zero}, "\x00\x00", "parse: t1_zero" ); is( $tree->{root}->{t2_ctrl}, "\x01\x1F\x01\x1F", "parse: t2_ctrl" ); # TAB,CR,LF are not unescaped but escaped. is( $tree->{root}->{t3_tab_esc}, "[\x09\x09]", "parse: t3_tab_esc" ); is( $tree->{root}->{t3_tab_raw}, "[\x09\x09]", "parse: t3_tab_raw" ); is( $tree->{root}->{t4_lf_esc}, "[\x0A\x0A]", "parse: t4_lf_esc" ); is( $tree->{root}->{t4_lf_raw}, "[\x0A\x0A]", "parse: t4_lf_raw" ); is( $tree->{root}->{t5_cr_esc}, "[\x0D\x0D]", "parse: t5_cr_esc" ); is( $tree->{root}->{t5_cr_raw}, "[\x0D\x0D]", "parse: t5_cr_raw" ); # ascii/latin chars are escaped/unescaped. is( $tree->{root}->{t6_space}, "\x20\x20", "parse: t6_space" ); is( $tree->{root}->{t7_ascii}, "\x21\x7F\x21\x7F", "parse: t7_ascii" ); # XML::TreePP 0.37 ignores between U+0080 and U+00FF without xml_deref # my $u80 = "\xC2\x80"; # is UTF-8 of "\x80" # my $uFF = "\xC3\xBF"; # is UTF-8 of "\xFF" # is( $tree->{root}->{t8_latin}, "$u80$uFF$u80$uFF", "parse: t8_latin" ); # CJK > 0xFF are not escaped/unescaped. is( $tree->{root}->{t9_kanji}, "漢漢", "parse: t9_kanji" ); # ---------------------------------------------------------------- my $back = $tpp->write( $tree ); # control chars are escaped/unescaped. like( $back, qr/ �� < /x, "write: t1_zero" ); like( $back, qr/  < /x, "write: t2_ctrl" ); # TAB,CR,LF are not unescaped but escaped. like( $back, qr/ \[\x09\x09\] < /x, "write: t3_tab_esc" ); like( $back, qr/ \[\x09\x09\] < /x, "write: t3_tab_raw" ); like( $back, qr/ \[\x0A\x0A\] < /x, "write: t4_lf_esc" ); like( $back, qr/ \[\x0A\x0A\] < /x, "write: t4_lf_raw" ); like( $back, qr/ \[\x0D\x0D\] < /x, "write: t5_cr_esc" ); like( $back, qr/ \[\x0D\x0D\] < /x, "write: t5_cr_raw" ); # ascii/latin chars are escaped/unescaped. like( $back, qr/ \x20\x20 < /x, "write: t6_space" ); like( $back, qr/ !! < /x, "write: t7_ascii" ); # XML::TreePP 0.37 ignores between U+0080 and U+00FF without xml_deref # like( $back, qr/ $u80$uFF$u80$uFF < /x, "write: t8_latin" ); # CJK > 0xFF are not escaped/unescaped. like( $back, qr/ 漢漢 < /x, "write: t9_kanji" ); # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/15_encoding_ja.t0000755000175100017510000000246110432046115015647 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 7; # ---------------------------------------------------------------- my $FILES = [qw( t/example/hello-ja-utf8.xml t/example/hello-ja-sjis.xml t/example/hello-ja-euc.xml )]; # ---------------------------------------------------------------- SKIP: { if ( $] < 5.008 ) { eval { require Jcode; } unless defined $Jcode::VERSION; if ( ! defined $Jcode::VERSION ) { skip( "Jcode.pm is not loaded.", 7 ); } } use_ok('XML::TreePP'); &test_main(); } # ---------------------------------------------------------------- sub test_main { my $tpp = XML::TreePP->new(); my $prev; foreach my $file ( @$FILES ) { my $tree = $tpp->parsefile( $file ); if ( defined $prev ) { is( $tree->{root}->{text}, $prev, $file ); } else { like( $tree->{root}->{text}, qr/\S\!/, $file ); $prev = $tree->{root}->{text}; } my $xml = $tpp->write( $tree ); like( $xml, qr/^\s*<\?xml[^<>]+encoding="UTF-8"/is, "write encoding" ); } } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/25_text_node_key.t0000755000175100017510000000226110522537533016260 0ustar u-sukeu-suke# 25_text_noe_key.t use strict; use Test::More tests => 13; BEGIN { use_ok('XML::TreePP') }; my $tpp = XML::TreePP->new(); $tpp->set( cdata_scalar_ref => 1 ); my $hello = 'Hello, World!'; my $tnode_keys = [ '#text', '_content', '0' ]; foreach my $tkey ( @$tnode_keys ) { my $rand = int(rand() * 9000 + 1000); my $text = "$hello $rand $tkey"; my $tree = { root => { text => { -attr => $text, $tkey => $text, }, cdata => { -attr => $text, $tkey => \$text, }, } }; $tpp->set( text_node_key => $tkey ); my $write = $tpp->write( $tree ); # print STDERR $write; my $back = $tpp->parse( $write ); is( $back->{root}->{text}->{-attr}, $text, "attribute1 for $tkey" ); is( $back->{root}->{text}->{$tkey}, $text, "text node for $tkey" ); is( $back->{root}->{cdata}->{-attr}, $text, "attribute2 for $tkey" ); my $ref = $back->{root}->{cdata}->{$tkey}; is( $$ref, $text, "cdata node for $tkey (content)" ) if ref $ref; is( $text, 'SCALAR(0x...)', "cdata node for $tkey (ref)" ) unless ref $ref; } 1; XML-TreePP-0.39/t/26_attr_prefix_null.t0000755000175100017510000000162610522537524017005 0ustar u-sukeu-suke# 26_attr_prefix_null.t.t use strict; use Test::More tests => 6; BEGIN { use_ok('XML::TreePP') }; my $tpp = XML::TreePP->new(); $tpp->set( attr_prefix => '' ); my $source = ''; my $expect = 'hoge'; my $parse1 = $tpp->parse( $source ); is( $parse1->{root}->{foo}->{bar}, 'hoge', 'parse 1' ); my $write1 = $tpp->write( $parse1 ); $write1 =~ s/\s+//sg; $write1 =~ s/<\?.*?\?>//s; is( $write1, $expect, 'write 1' ); my $tree1 = { root => { foo => { '@attr' => 'atmark', '-attr' => 'minus', 'attr' => 'null', }, }, }; my $write2 = $tpp->write( $tree1 ); my $parse2 = $tpp->parse( $write2 ); is( $parse2->{root}->{foo}->{'@attr'}, 'atmark', 'write 2' ); is( $parse2->{root}->{foo}->{'-attr'}, 'minus', 'write 3' ); is( $parse2->{root}->{foo}->{'attr'}, 'null', 'write 4' ); 1; XML-TreePP-0.39/t/46_xml_deref.t0000755000175100017510000000710311134346353015365 0ustar u-sukeu-suke# ---------------------------------------------------------------- # this test script is written in utf8 but does not "use utf8" for 5.005-compatibility # ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { plan tests => 33; use_ok('XML::TreePP'); &test_main(); } # ---------------------------------------------------------------- sub test_main { my $src = {}; $src->{Plain} = <<"EOT"; AA zz ©© ëë んん 漢漢 EOT $src->{XMLref} = <<"EOT"; AA zz ©© ëë んん 漢漢 EOT $src->{Mixed} = <<"EOT"; AA zz ©© ëë んん 漢漢 EOT foreach my $key ( keys %$src ) { phase2( "$key octets", $src->{$key} ); } } # ---------------------------------------------------------------- sub phase2 { my $subject = shift; my $srcxml = shift; my $srcref = ( $srcxml =~ /&#\w+;/ ); foreach my $xml_deref ( 0, 1 ) { my $subj3 = $subject .( $xml_deref ? ' xml_deref' : '' ); my $opt = { xml_deref => $xml_deref, }; my $tpp = XML::TreePP->new( %$opt ); my $tree = $tpp->parse( $srcxml ); if ( $xml_deref ) { check_octets( $subj3, $tree ); } else { if ( $srcref ) { check_has_ref( $subj3, $tree ); } else { check_no_ref( $subj3, $tree ); } } } } # ---------------------------------------------------------------- sub check_has_ref { my $subject = shift; my $tree = shift; my $root = $tree->{root}; my $HAS_REF = qr/&#\w+;/; # \x00-\x7F is always dereferenced. # like( $root->{a}, $HAS_REF, "$subject has_ref: a" ); # like( $root->{z}, $HAS_REF, "$subject has_ref: z" ); like( $root->{c}, $HAS_REF, "$subject has_ref: c" ); like( $root->{e}, $HAS_REF, "$subject has_ref: e" ); like( $root->{n}, $HAS_REF, "$subject has_ref: n" ); like( $root->{k}, $HAS_REF, "$subject has_ref: k" ); } # ---------------------------------------------------------------- sub check_no_ref { my $subject = shift; my $tree = shift; my $root = $tree->{root}; my $HAS_REF = qr/&#\w+;/; unlike( $root->{a}, $HAS_REF, "$subject no_ref: a" ); unlike( $root->{z}, $HAS_REF, "$subject no_ref: z" ); unlike( $root->{c}, $HAS_REF, "$subject no_ref: c" ); unlike( $root->{e}, $HAS_REF, "$subject no_ref: e" ); unlike( $root->{n}, $HAS_REF, "$subject no_ref: n" ); unlike( $root->{k}, $HAS_REF, "$subject no_ref: k" ); } # ---------------------------------------------------------------- sub check_octets { my $subject = shift; my $tree = shift; my $root = $tree->{root}; is( $root->{a}, 'AA', "$subject ok: a" ); is( $root->{z}, 'zz', "$subject ok: z" ); is( $root->{c}, '©©', "$subject ok: c" ); is( $root->{e}, 'ëë', "$subject ok: e" ); is( $root->{n}, 'んん', "$subject ok: n" ); is( $root->{k}, '漢漢', "$subject ok: k" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/19_multi_text.t0000755000175100017510000000745310435110435015617 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 41; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $xml1 = 'aaabbb'; my $xml2 = 'cccddd'; my $xml3 = ''; my $xml4 = ''; my $xml5 = 'jjj'; my $xml6 = 'lllnnn'; my $tpp = XML::TreePP->new(); foreach my $cdata ( 1, 0 ) { $tpp->set( cdata_scalar_ref => $cdata ); $tpp->set( multi_text_nodes => 0 ); my $tree1 = $tpp->parse( $xml1 ); my $tree2 = $tpp->parse( $xml2 ); my $tree3 = $tpp->parse( $xml3 ); my $tree4 = $tpp->parse( $xml4 ); my $tree5 = $tpp->parse( $xml5 ); my $tree6 = $tpp->parse( $xml6 ); ok( ! ref $tree1->{root}{text}{'#text'}, '1 parse' ); ok( ! ref $tree2->{root}{text}{'#text'}, '2 parse' ); if ( $cdata ) { is( ref $tree3->{root}{text}{'#text'}, 'SCALAR', '3 parse cdata' ); is( ref $tree4->{root}{text}{'#text'}, 'SCALAR', '4 parse cdata' ); is( ref $tree5->{root}{text}, 'SCALAR', '5 parse cdata' ); is( ref $tree6->{root}{text}, 'SCALAR', '6 parse cdata' ); } else { ok( ! ref $tree3->{root}{text}{'#text'}, '3 parse' ); ok( ! ref $tree4->{root}{text}{'#text'}, '4 parse' ); ok( ! ref $tree5->{root}{text}, '5 parse' ); ok( ! ref $tree6->{root}{text}, '6 parse' ); } is( $tree1->{root}{text}{'#text'}, 'aaabbb', '1 aaa-bbb' ); is( $tree2->{root}{text}{'#text'}, 'cccddd', '2 ccc-ddd' ); if ( $cdata ) { is( ref $tree3->{root}{text}{'#text'}, 'SCALAR', '3 eee-fff ref' ); is( ref $tree4->{root}{text}{'#text'}, 'SCALAR', '4 ggg-hhh ref' ); is( ref $tree5->{root}{text}, 'SCALAR', '5 iii-jjj-kkk ref' ); is( ref $tree6->{root}{text}, 'SCALAR', '6 lll-mmm-nnn ref' ); is( ${$tree3->{root}{text}{'#text'}}, 'eeefff', '3 eee-fff cdata' ); is( ${$tree4->{root}{text}{'#text'}}, 'ggghhh', '4 ggg-hhh cdata' ); is( ${$tree5->{root}{text}}, 'iiijjjkkk', '5 iii-jjj-kkk cdata' ); is( ${$tree6->{root}{text}}, 'lllmmmnnn', '6 lll-mmm-nnn cdata' ); } else { is( $tree3->{root}{text}{'#text'}, 'eeefff', '3 eee-fff' ); is( $tree4->{root}{text}{'#text'}, 'ggghhh', '4 ggg-hhh' ); is( $tree5->{root}{text}, 'iiijjjkkk', '5 iii-jjj-kkk' ); is( $tree6->{root}{text}, 'lllmmmnnn', '6 lll-mmm-nnn' ); } my $write1 = $tpp->write( $tree1 ); my $write2 = $tpp->write( $tree2 ); my $write3 = $tpp->write( $tree3 ); my $write4 = $tpp->write( $tree4 ); my $write5 = $tpp->write( $tree5 ); my $write6 = $tpp->write( $tree6 ); like( $write1, qr/>aaabbbcccddd/s, '3 write cdata' ); like( $write4, qr//s, '4 write cdata' ); like( $write5, qr//s, '5 write cdata' ); like( $write6, qr//s, '6 write cdata' ); } else { like( $write3, qr/>eeefffggghhhiiijjjkkklllmmmnnn 'Perl 5.8.1 is required.' if $@; } # ---------------------------------------------------------------- { plan tests => 66; use_ok('XML::TreePP'); &test_utf8(); } # ---------------------------------------------------------------- sub test_utf8 { my $octxml = <<"EOT"; 二2 三3参 四4Ⅳⅳ 5 ±6÷6 EOT my $strxml = $octxml; utf8::decode( $strxml ); my $strtpp = XML::TreePP->new( utf8_flag => 1 ); my $octtpp = XML::TreePP->new(); ok( ! utf8::is_utf8($octxml), '[source] XML: octets' ); ok( utf8::is_utf8($strxml), '[source] XML: string' ); my $treeA = $strtpp->parse( $octxml ); my $treeB = $strtpp->parse( $strxml ); my $treeC = $octtpp->parse( $octxml ); my $treeD = $octtpp->parse( $strxml ); ok( ! utf8::is_utf8($octxml), "[source] XML: octets (no damaged)" ); ok( utf8::is_utf8($strxml), "[source] XML: string (no damaged)" ); &check_string( 'A', $treeA ); &check_string( 'B', $treeB ); &check_octest( 'C', $treeC ); &check_string( 'D', $treeD ); &check_same( 'A-B', $treeA, $treeB ); &check_same( 'B-D', $treeB, $treeB ); &check_diff( 'A-C', $treeA, $treeC ); foreach my $hash ( $treeA, $treeB, $treeD ) { my $root = $hash->{root}; foreach my $key ( sort keys %$root ) { ok( utf8::is_utf8($root->{$key}), 'XML: string '.$key ); } } foreach my $hash ( $treeC ) { my $root = $hash->{root}; foreach my $key ( sort keys %$root ) { ok( ! utf8::is_utf8($root->{$key}), 'XML: octets '.$key ); } } my $xmlH = $octtpp->write( $treeC ); my $xmlE = $strtpp->write( $treeA ); my $xmlF = $strtpp->write( $treeB ); my $xmlG = $octtpp->write( $treeD ); ok( utf8::is_utf8($xmlE), '[E] XML: string' ); ok( utf8::is_utf8($xmlF), '[F] XML: string' ); ok( utf8::is_utf8($xmlG), '[G] XML: string' ); ok( ! utf8::is_utf8($xmlH), '[H] XML: octets' ); } # ---------------------------------------------------------------- sub check_string { my $name = shift; my $tree = shift; my $oct1 = '一'; my $oct2 = "二2"; my $str2 = $oct2; utf8::decode( $str2 ); my $four = $tree->{root}->{four}; ok( utf8::is_utf8($four), "[$name] 4: string" ); my $five = $tree->{root}->{five}; ok( utf8::is_utf8($five), "[$name] 5: string" ); my $six = $tree->{root}->{six}; ok( utf8::is_utf8($six), "[$name] 6: string" ); my $one = "".$tree->{root}->{one}; isnt( $one, $oct1, "[$name] 1: string != octets" ); utf8::encode( $one ); is( $one, $oct1, "[$name] 2: octets == octets" ); my $two = "".$tree->{root}->{two}; isnt( $two, $oct2, "[$name] 3: string != octets" ); is( $two, $str2, "[$name] 4: string == string" ); } # ---------------------------------------------------------------- sub check_octest { my $name = shift; my $tree = shift; my $oct1 = '一'; my $oct2 = "二2"; my $str2 = $oct2; utf8::decode( $str2 ); my $four = $tree->{root}->{four}; ok( ! utf8::is_utf8($four), "[$name] 4: octets" ); my $five = $tree->{root}->{five}; ok( ! utf8::is_utf8($five), "[$name] 5: octets" ); my $six = $tree->{root}->{six}; ok( ! utf8::is_utf8($six), "[$name] 6: octets" ); my $one = $tree->{root}->{one}; is( $one, $oct1, "[$name] 1: octets == octets" ); my $two = "".$tree->{root}->{two}; isnt( $two, $str2, "[$name] 2: octets != string" ); utf8::decode( $two ); is( $two, $str2, "[$name] 2: string == string" ); } # ---------------------------------------------------------------- sub check_same { my $name = shift; my $tree1 = shift; my $tree2 = shift; my $three1 = $tree1->{root}->{three}; my $three2 = $tree2->{root}->{three}; is( $three1, $three2, "[$name] 4: same" ); # octets' latin-1 and string's latin-1 are equal # my $five1 = $tree1->{root}->{five}; # my $five2 = $tree2->{root}->{five}; # is( $five1, $five2, "[$name] 5: same" ); my $six1 = $tree1->{root}->{six}; my $six2 = $tree2->{root}->{six}; is( $six1, $six2, "[$name] 6: same" ); } # ---------------------------------------------------------------- sub check_diff { my $name = shift; my $tree1 = shift; my $tree2 = shift; my $three1 = $tree1->{root}->{three}; my $three2 = $tree2->{root}->{three}; isnt( $three1, $three2, "[$name] 4: diff" ); # octets' latin-1 and string's latin-1 are equal # my $five1 = $tree1->{root}->{five}; # my $five2 = $tree2->{root}->{five}; # isnt( $five1, $five2, "[$name] 5: diff" ); my $six1 = $tree1->{root}->{six}; my $six2 = $tree2->{root}->{six}; isnt( $six1, $six2, "[$name] 6: diff" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/41_writefile_encode.t0000755000175100017510000000512010676257161016727 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { local $@; eval { require 5.008001; }; plan skip_all => 'Perl 5.8.1 is required.' if $@; eval { require Encode; }; plan skip_all => 'Encode is not loaded.' if $@; eval { require File::Temp; }; plan skip_all => 'File::Temp is not loaded.' if $@; my $writable = &test_filetemp(); plan skip_all => 'temp file is not writable.' unless $writable; plan tests => 19; use_ok('XML::TreePP'); &test_writefile(); &test_writefile( utf8_flag => 1 ); } # ---------------------------------------------------------------- sub test_writefile { my $opt = { @_ }; my $file = File::Temp->new->filename; ok( $file, "file:".$file ); my $foo = 'Ελληνικά/Español/Français'; # UTF-8 my $bar = 'Русский/Türkçe/日本語'; # UTF-8 my $tree = { root => { foo => $foo, bar => $bar }}; my $tpp = XML::TreePP->new( %$opt ); $tpp->writefile( $file, $tree ); ok( (-s $file), 'writefile' ); my $out = &read_file( $file ); like( $out, qr/\Q$foo\E/, 'foo raw' ); like( $out, qr/\Q$bar\E/, 'bar raw' ); my $check = $tpp->parsefile( $file ); ok( ref $check, 'parsefile' ); if ( $opt->{utf8_flag} ) { ok( utf8::is_utf8($check->{root}{foo}), 'foo string' ); ok( utf8::is_utf8($check->{root}{bar}), 'bar string' ); utf8::decode( $foo ); utf8::decode( $bar ); is( $check->{root}{foo}, $foo, 'foo tree string' ); is( $check->{root}{bar}, $bar, 'bar tree string' ); } else { ok( ! utf8::is_utf8($check->{root}{foo}), 'foo octets' ); ok( ! utf8::is_utf8($check->{root}{bar}), 'bar octets' ); is( $check->{root}{foo}, $foo, 'foo tree octets' ); is( $check->{root}{bar}, $bar, 'bar tree octets' ); } unlink( $file ); } # ---------------------------------------------------------------- sub test_filetemp { my $file = File::Temp->new->filename or return; open( TEMP, "> $file" ) or return; print TEMP "EOT\n"; close( TEMP ); my $size = ( -s $file ); unlink( $file ); $size; } # ---------------------------------------------------------------- sub read_file { my $file = shift or return; open( TEMP, $file ) or return; local $/ = undef; my $body = ; close( TEMP ); $body; } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/05_empty.t0000755000175100017510000000270610415704752014557 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 13; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $tpp = XML::TreePP->new( force_array => [qw( one two three )] ); my $source = ' '; my $tree = $tpp->parse( $source ); ok( exists $tree->{root}->{e1}, "empty element" ); ok( ref $tree->{root}->{e2}, "empty element with attribute" ); ok( exists $tree->{root}->{e3}, "no child nodes" ); ok( ref $tree->{root}->{e4}, "attribute" ); ok( exists $tree->{root}->{e5}, "white space" ); my $xml = $tpp->write( $tree ); my $round = $tpp->parse( $xml ); ok( exists $round->{root}->{e1}, "round trip: empty element" ); ok( ref $round->{root}->{e2}, "round trip: empty element with attribute" ); ok( exists $round->{root}->{e3}, "round trip: no child nodes" ); ok( ref $round->{root}->{e4}, "round trip: attribute" ); ok( exists $round->{root}->{e5}, "round trip: white space" ); is( $tree->{root}->{e2}->{"-foo"}, $round->{root}->{e2}->{"-foo"}, "round trip: attribute 1" ); is( $tree->{root}->{e4}->{"-foo"}, $round->{root}->{e4}->{"-foo"}, "round trip: attribute 2" ); # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/38_cdata_cdsect.t0000755000175100017510000000503510674071275016032 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 161; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- { my $test = { '' => '', '' => ']', ']]>' => '>', '' => ']]', '' => ']]', ']]>' => ']>', ']]>' => ']>', ']>' => ']]>', ']]]>' => ']]>', '>' => ']]>', ']]>' => ']]>', ']]>' => ']]>', ']]]>' => ']]>', '>' => ']]>', ']]]>' => ']]>', ']]>' => ']]>', ']]]]>]]>' => ']]>]]>', ']]]>]]>' => ']]>]]>', ']]>]]>' => ']]>]]>', ']]>]]>' => ']]>]]>', }; &cdata_cdsect( $test ); &cdata_cdsect( $test, { cdata_scalar_ref=>1 } ); } # ---------------------------------------------------------------- sub cdata_cdsect { my $list = shift; my $opt = shift; my $tpp = XML::TreePP->new( %$opt ); foreach my $src ( keys %$list ) { my $val = $list->{$src}; my $tree = $tpp->parse( $src ); ok( exists $tree->{cdata}, 'exists' ); my $cdata = $tree->{cdata}; $cdata = $$cdata if ( ref $cdata eq 'SCALAR' ); ok( ! ref $cdata, 'invalid ref' ); is( $cdata, $val, $val ); my $xml = $tpp->write( $tree ); my $again = $tpp->parse( $xml ); my $cdat2 = $again->{cdata}; $cdat2 = $$cdat2 if ( ref $cdat2 eq 'SCALAR' ); is( $cdat2, $cdata, 'round trip' ); } } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/00_pod.t0000755000175100017510000000031510432050145014155 0ustar u-sukeu-sukeuse strict; use Test::More; my $FILES = [qw( lib/XML/TreePP.pm )]; local $@; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok( @$FILES ); ;1; XML-TreePP-0.39/t/39_writefile.t0000755000175100017510000000271510676257165015434 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { local $@; eval { require File::Temp; }; plan skip_all => 'File::Temp is not loaded.' if $@; my $writable = &test_filetemp(); plan skip_all => 'temp file is not writable.' unless $writable; plan tests => 7; use_ok('XML::TreePP'); &test_writefile(); } # ---------------------------------------------------------------- sub test_writefile { my $file = File::Temp->new->filename; ok( $file, "file:".$file ); my $foo = 'Hello'; my $bar = 'World!'; my $tree = { root => { foo => $foo, bar => $bar }}; my $tpp = XML::TreePP->new(); $tpp->writefile( $file, $tree ); ok( (-s $file), 'writefile' ); my $check = $tpp->parsefile( $file ); ok( ref $check, 'parsefile' ); ok( ref $check->{root}, 'parsefile' ); is( $check->{root}{foo}, $foo, 'foo' ); is( $check->{root}{bar}, $bar, 'bar' ); unlink( $file ); } # ---------------------------------------------------------------- sub test_filetemp { my $file = File::Temp->new->filename or return; open( TEMP, "> $file" ) or return; print TEMP "EOT\n"; close( TEMP ); my $size = ( -s $file ); unlink( $file ); $size; } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/11_escape_cdata.t0000755000175100017510000000224510431651424016003 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 7; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $tpp = XML::TreePP->new(); $tpp->set( cdata_scalar_ref => 1 ); my $source = '<>&><BBB'; my $tree = $tpp->parse( $source ); is( $tree->{root}->{text}, '<>&><', "parse text node" ); my $cdata = $tree->{root}->{cdata}; is( $$cdata, '<>&><', "parse cdata node" ); is( $tree->{root}->{attr}->{'-key'}, '<>&><', "parse attribute" ); my $back = $tpp->write( $tree ); like( $back, qr{ \s* <>&>< \s* }sx, "write text node" ); like( $back, qr{ }sx, "write cdata node (as cdata)" ); like( $back, qr{ 'LWP::UserAgent is not loaded.'; } if ( ! defined $ENV{MORE_TESTS} ) { plan skip_all => 'define $MORE_TESTS to test this.'; } plan tests => 7; use_ok('XML::TreePP'); my $tpp = XML::TreePP->new(); my $name = ( $0 =~ m#([^/:\\]+)$# )[0]; $tpp->set( user_agent => "$name " ); &test_http_post( $tpp, $name ); # use LWP::UserAgent eval { require HTTP::Lite; }; &test_http_post( $tpp, $name ); # use LWP::UserAgent again not HTTP::Lite } # ---------------------------------------------------------------- sub test_http_post { my $tpp = shift; my $name = shift; my $url = "http://www.kawa.net/works/perl/treepp/example/envxml.cgi"; my( $tree, $xml ) = $tpp->parsehttp( POST => $url, '' ); ok( ref $tree, $url ); my $agent = $tree->{env}->{HTTP_USER_AGENT}; like( $agent, qr/libwww-perl/, "$agent" ); like( $agent, qr/^\Q$name\E/, "User-Agent has '$name'" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/45_attr_space.t0000755000175100017510000000334411101004466015535 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 49; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $tpp = XML::TreePP->new(); my $list = [ 'XXX', "XXX", 'XXX', "XXX", '', "", '', "", '', "", '', "", ]; foreach my $source ( @$list ) { my $tree = $tpp->parse( $source ); my $sep = ( $source =~ /(['"])/ )[0]; is( $tree->{root}->{"-aaa"}, "AAA", "key=".$sep."val".$sep." (no space)" ); is( $tree->{root}->{"-bbb"}, "BBB", "key =".$sep."val".$sep." (left space)" ); is( $tree->{root}->{"-ccc"}, "CCC", "key= ".$sep."val".$sep." (right space)" ); is( $tree->{root}->{"-ddd"}, "DDD", "key = ".$sep."val".$sep." (both space)" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/36_elem_class.t0000755000175100017510000000377610655660673015555 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { plan tests => 14; use_ok('XML::TreePP'); &test_elem_class( force_array => [qw( six )], elem_class => 'Element' ); } # ---------------------------------------------------------------- sub test_elem_class { my $tpp = XML::TreePP->new(@_); my $xml = <<"EOT"; 1 2 4 5 5 7 8 9 EOT my $tree = $tpp->parse( $xml ); is( ref $tree, 'Element', '/root' ); is( ref $tree->{root}, 'Element::root', '/root' ); is( ref $tree->{root}->{two}, 'Element::two', '/root/two' ); is( ref $tree->{root}->{three}, 'Element::three', '/root/three' ); is( ref $tree->{root}->{three}->{five}, 'Element::five', '/root/three/five' ); is( ref $tree->{root}->{six}, 'ARRAY', '/root/six (ARRAY)' ); is( ref $tree->{root}->{six}->[0], 'Element::six', '/root/six' ); is( ref $tree->{root}->{six}->[0]->{seven}, 'Element::seven', '/root/six/seven' ); is( ref $tree->{root}->{eight}, 'ARRAY', '/root/eight (ARRAY)' ); is( ref $tree->{root}->{eight}->[1], 'Element::eight', '/root/eight' ); # 2007/08/07 added is( ref $tree->{root}->{foo}, 'Element::foo', '/root/foo' ); is( ref $tree->{root}->{foo}->{bar}, 'ARRAY', '/root/foo/bar (ARRAY)' ); is( ref $tree->{root}->{foo}->{bar}->[0], 'Element::bar', '/root/foo/bar' ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/17_output_encoding.t0000755000175100017510000000470010432046005016613 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 43; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $DIVISION_SIGN = { 'Shift_JIS' => "\x81\x80", 'EUC-JP' => "\xA1\xE0", 'GB2312' => "\xA1\xC2", 'EUC-KR' => "\xA1\xC0", 'BIG5' => "\xA1\xD2", 'UTF-8' => "\xC3\xB7", 'Latin-1' => "\xF7", }; my $PLUSMINUS_SIGN = { 'Shift_JIS' => "\x81\x7D", 'EUC-JP' => "\xA1\xDE", 'GB2312' => "\xA1\xC0", 'EUC-KR' => "\xA1\xBE", 'BIG5' => "\xA1\xD3", 'UTF-8' => "\xC2\xB1", 'Latin-1' => "\xB1", }; # ---------------------------------------------------------------- SKIP: { &test_main('UTF-8'); if ( $] < 5.008 ) { eval { require Jcode; } unless defined $Jcode::VERSION; if ( ! defined $Jcode::VERSION ) { skip( "Jcode.pm is not loaded.", 36 ); } } &test_main('Shift_JIS'); &test_main('EUC-JP'); skip( "Perl $]", 24 ) if ( $] < 5.008 ); &test_main('Latin-1'); &test_main('EUC-KR'); &test_main('GB2312'); &test_main('BIG5'); } # ---------------------------------------------------------------- sub test_main { my $code = shift; my $tpp = XML::TreePP->new(); my $tree = { root => { division => $DIVISION_SIGN->{'UTF-8'}, plusminus => $PLUSMINUS_SIGN->{'UTF-8'}, }, }; my $xml1 = $tpp->write( $tree, $code ); $tpp->set( output_encoding => $code ); my $xml2 = $tpp->write( $tree ); like( $xml1, qr/^\s*<\?xml[^<>]+encoding="\Q$code\E"/is, "encoding $code 1" ); like( $xml2, qr/^\s*<\?xml[^<>]+encoding="\Q$code\E"/is, "encoding $code 2" ); my $div1 = ( $xml1 =~ m/([^<>]+)([^<>]+){$code}, "division $code 1" ); is( $div2, $DIVISION_SIGN->{$code}, "division $code 2" ); my $plm1 = ( $xml1 =~ m/([^<>]+)([^<>]+){$code}, "plusminus $code 1" ); is( $plm2, $PLUSMINUS_SIGN->{$code}, "plusminus $code 2" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/03_parsefile.t0000755000175100017510000000125010431661373015361 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 3; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $tpp = XML::TreePP->new(); my $tree = $tpp->parsefile( 't/example/index.rdf' ); my $title = $tree->{'rdf:RDF'}->{channel}->{title}; like( $title, qr{ kawa.net }ix, '' ); my $about = $tree->{'rdf:RDF'}->{channel}->{'-rdf:about'}; like( $about, qr{ ^http:// }x, '<channel rdf:about="">' ); # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/20_http-lite-cached.t�������������������������������������������������������������0000755�0001751�0001751�00000002604�10467630536�016537� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- SKIP: { local $@; eval { require HTTP::Lite; } unless defined $HTTP::Lite::VERSION; if ( ! defined $HTTP::Lite::VERSION ) { plan skip_all => 'HTTP::Lite is not loaded.'; } if ( ! defined $ENV{MORE_TESTS} ) { plan skip_all => 'define $MORE_TESTS to test this.'; } plan tests => 7; use_ok('XML::TreePP'); my $tpp = XML::TreePP->new(); my $name = ( $0 =~ m#([^/:\\]+)$# )[0]; $tpp->set( user_agent => "$name " ); &test_http_post( $tpp, $name ); # use HTTP::Lite eval { require LWP::UserAgent; }; &test_http_post( $tpp, $name ); # use HTTP::Lite again not LWP::UserAgent } # ---------------------------------------------------------------- sub test_http_post { my $tpp = shift; my $name = shift; my $url = "http://www.kawa.net/works/perl/treepp/example/envxml.cgi"; my( $tree, $xml ) = $tpp->parsehttp( POST => $url, '' ); ok( ref $tree, $url ); my $agent = $tree->{env}->{HTTP_USER_AGENT}; unlike( $agent, qr/libwww-perl/, $agent ); like( $agent, qr/^\Q$name\E/, "User-Agent has '$name'" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- ����������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/��������������������������������������������������������������������������0000755�0001751�0001751�00000000000�11222330343�014337� 5����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-ja-sjis.xml���������������������������������������������������������0000644�0001751�0001751�00000000144�10431663657�017543� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="Shift_JIS" ?> <root lang="ja"> <text>ɂ!</text> </root> ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-en-utf8.xml���������������������������������������������������������0000644�0001751�0001751�00000000156�10431663512�017462� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" ?> <root lang="latin"> <text>Hello, World! §±×÷</text> </root> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-zh-gb2312.xml�������������������������������������������������������0000644�0001751�0001751�00000000133�10431664174�017513� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="GB2312" ?> <root lang="zh"> <text>!</text> </root> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-ja-euc.xml����������������������������������������������������������0000644�0001751�0001751�00000000135�10431663723�017341� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-JP" ?> <root lang="ja"> <text>ˤ!</text> </root> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-ko-utf8.xml���������������������������������������������������������0000644�0001751�0001751�00000000145�10431664164�017473� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" ?> <root lang="ko"> <text>안녕하세요!</text> </root> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-ko-euc.xml����������������������������������������������������������0000644�0001751�0001751�00000000141�10431664170�017352� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="EUC-KR" ?> <root lang="ko"> <text>ȳϼ!</text> </root> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-en-nodecl.xml�������������������������������������������������������0000644�0001751�0001751�00000000105�10431663520�020031� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<root lang="latin"> <text>Hello, World! §±×÷</text> </root> �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-ja-utf8.xml���������������������������������������������������������0000644�0001751�0001751�00000000145�10431663673�017460� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" ?> <root lang="ja"> <text>こんにちは!</text> </root> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-zh-utf8.xml���������������������������������������������������������0000644�0001751�0001751�00000000134�10431664172�017500� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" ?> <root lang="zh"> <text>你好!</text> </root> ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-en-noenc-bom.xml����������������������������������������������������0000644�0001751�0001751�00000000140�10737371055�020451� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" ?> <root lang="latin"> <text>Hello, World! §±×÷</text> </root> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-en-utf8-bom.xml�����������������������������������������������������0000644�0001751�0001751�00000000161�10737370522�020236� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" ?> <root lang="latin"> <text>Hello, World! §±×÷</text> </root> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/hello-zh-big5.xml���������������������������������������������������������0000644�0001751�0001751�00000000131�10431664161�017433� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="BIG5" ?> <root lang="zh"> <text>An!</text> </root> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML-TreePP-0.39/t/example/index.rdf�����������������������������������������������������������������0000644�0001751�0001751�00000663523�11222326331�016164� 0����������������������������������������������������������������������������������������������������ustar �u-suke��������������������������u-suke�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" ?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"> <channel rdf:about="http://www.kawa.net/xp/index-e.html"> <title>Kawa.net xp - ajax/JavaScript/Perl/CGI by Yusuke Kawasaki http://www.kawa.net/xp/index-e.html 2009-04-07T06:32:00+09:00 en Copyright 1995-2009 Yusuke Kawasaki. All rights reserved. Yusuke Kawasaki's homepage from Japan. Ajax/JavaScript/Perl/CGI/etc. technical articles and photos. 25 1 54 /xp/images/xp-title-128x32.gif Kawa.net xp - ajax/JavaScript/Perl/CGI by Yusuke Kawasaki http://www.kawa.net/xp/index-e.html LiveChromaKey + LivePointers = AR Presentation! http://kawanet.blogspot.com/2009/05/livechromakey-livepointers-ar.html Yusuke Kawasaki 2009-05-30T21:48:47.575+09:00 event actionscript flash 0 I am a newbie for the wonderful ActionScript world and have worked hard for these two weeks to write a couple of pure ActionScript 3.0 libraries, LiveChromaKey and LivePointers. Then I gave a talk at <a href="http://www.libspark.org/wiki/WikiStart/en">Spark project</a>'s <a href="http://blog.jactionscripters.com/2009/05/29/monthly-spark-meeting-09/">SparkStudy/09</a> on May 28th.<br /><br />SparkStudy is a monthly meeting for the cutting-edge ActionScript developers in Tokyo. It's hosted by <a href="http://www.be-interactive.org/en.php">Yoshihiro Shindo</a> a.k.a. yossy. This was the first time for me, an ECMAScripter, to attend it but I enjoyed it.<br /><br /><a href="http://kawanet.blogspot.com/2009/05/livechromakey-bluescreen-less-augmented.html">As recently posted</a>, LiveChromaKey is a bluescreen-less image synthesizing engine for AR.<br /><br />And the new library of LivePointers is a color detection engine to handle something as the new style of human interface devices with webcam. This means, for example, fingercap would be the 3D pointing device.<br /><br />Anyway, you can <b>try</b> my presentation:<br /><a href="http://www.kawa.net/text/spark/09/spark.html">http://www.kawa.net/text/spark/09/spark.html</a><br /><br /><a href="http://www.kawa.net/text/spark/09/spark.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SiEmNDtjPwI/AAAAAAAAAkU/noNV61_NGuU/s400/spark-image.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5341592638814633730" /></a><br />Yes, I was in the live projector screen during my presentation like weather newscaster did in weather news program! It would be nice for the audiences who seated at the end of the row in the room to see me on the screen. :)<br /><br /><a href="http://www.kawa.net/text/spark/09/spark.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SiEmNfl-FKI/AAAAAAAAAkc/A-J4_r1dpoY/s400/slides+(24).JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5341592646299030690" /></a><br />In addition, I used fingercaps to manipulate slides, ex. right hand means next page. The fingercap I used costs only JPY 105, approximately USD 1.00- for six fingers. I'm sure that the cheap cap would be definitely important user interface device of the future!<br /><br />Note that you can flip to the next page by right key of your keyboard as an insurance for the live presentation. :)<br /><br />If you prefer a classical style of the slides, try slideshare:<br /><br /><center><div style="width: 425px;"><a href="http://www.slideshare.net/kawa0117/jsartoolkit-livechromakey-livepointers-next-gen-of-ar?type=presentation" style="font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block;" title="JSARToolKit / LiveChromaKey / LivePointers">JSARToolKit / LiveChromaKey / LivePointers</a><object width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=spark-090528113259-phpapp02&amp;rel=0&amp;stripped_title=jsartoolkit-livechromakey-livepointers-next-gen-of-ar"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=spark-090528113259-phpapp02&rel=0&stripped_title=jsartoolkit-livechromakey-livepointers-next-gen-of-ar" type="application/x-shockwave-flash" allowscriptaccess="always" width="425" height="355"></embed></object></div></center><br />LivePointers library is still under development. You can try the current snapshot on the Spark project's repository:<br /><a href="http://www.libspark.org/svn/as3/LivePointers/trunk/">http://www.libspark.org/svn/as3/LivePointers/trunk/</a><br />&nbsp;<br /><span style="font-style:italic;">* <a href="http://kawa.at.webry.info/200905/article_14.html">Orignal post of this</a> was written in Japanese.</span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-5070128522280735443?l=kawanet.blogspot.com'/></div> LiveChromaKey - Bluescreen-less augmented IN reality (AR) http://kawanet.blogspot.com/2009/05/livechromakey-bluescreen-less-augmented.html Yusuke Kawasaki 2009-05-30T20:49:11.540+09:00 actionscript flash ar 0 I wrote a new ActionScript library <a href="http://www.libspark.org/svn/as3/LiveChromaKey/trunk/">LiveChromaKey</a> which is an image synthesizing engine for AR. The key point is it does not make something <u>augmented ON reality</u> but also <u>augmented IN reality</u>. It really portable as it never need blue background screen. The key color of <a href="http://en.wikipedia.org/wiki/Chroma_key">chroma key</a> is automatically detected on the fly.<br /><br /><h2>Demo #1</h2>Try: <a href="http://www.libspark.org/svn/as3/LiveChromaKey/trunk/examples/pyramid.html">Travelling In Egypt</a><br />Source: <a href="http://www.libspark.org/svn/as3/LiveChromaKey/trunk/examples/Pyramid.as">Pyramid.as</a><br /><br /><div align="center"><a href="http://www.libspark.org/svn/as3/LiveChromaKey/trunk/examples/pyramid.html" target="_blank"><img src="http://4.bp.blogspot.com/_cgZUdkW7lzE/ShePjCCK4GI/AAAAAAAAAj0/pnHvemVpdFU/s400/livechromakey.jpg"></a></div><br />An webcam is needed to try this. Blue background screen is not needed. At first, hide out from the camera for LiveChromaKey to recognize the background view. After few seconds, the pyramid of Khafre will be shown. It's time to play it! Now you can feel free you are travelling in Egypt. :)<br /><br />In case you move camera, click the screen to re-recognize background on demand. Then hide out and wait for few seconds again. You may need to turn off your camera's intelligent features like automatic white balance, automatic exposure compensation, etc. LiveChromaKey does not like such tunings.<br /><br /><h2>Demo #2</h2>Try: <a href="http://www.libspark.org/svn/as3/LiveChromaKey/trunk/examples/minority.html">Minority Report-like Demo</a><br />Source: <a href="http://www.libspark.org/svn/as3/LiveChromaKey/trunk/examples/Minority.as">Minority.as</a><br /><br /><div align="center"><a href="http://www.libspark.org/svn/as3/LiveChromaKey/trunk/examples/minority.html" target="_blank"><img src="http://4.bp.blogspot.com/_cgZUdkW7lzE/ShePjQrdz9I/AAAAAAAAAkE/A17WSztwNgo/s400/lck-minority.jpg"></a></div><br />This demo floats some photos in your back. <a href="http://movies.foxjapan.com/minority/video/trailer_9_lg.html">Finger pointing reorganization like the Minority Report movie</a> is not implemented at this time.<br /><br /><h2>Demo #3</h2>Try: <a href="http://www.libspark.org/svn/as3/LiveChromaKey/trunk/examples/panels.html">Four Sprites Of LiveChromaKey</a><br />Source: <a href="http://www.libspark.org/svn/as3/LiveChromaKey/trunk/examples/Panels.as">Panels.as</a><br /><br /><div align="center"><a href="http://www.libspark.org/svn/as3/LiveChromaKey/trunk/examples/panels.html" target="_blank"><img src="http://3.bp.blogspot.com/_cgZUdkW7lzE/ShePjdugaxI/AAAAAAAAAj8/unFgte_71dc/s400/lck-planes.jpg"></a></div><br />This demo shows the four sprites which LiveChromaKey provides.<br /><br /><h2>LiveChromaKey Sample Code</h2><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">var chromakey:LCK_Core = new LCK_Core();<br />chromakey.init();<br /><br />var spLive:Sprite = chromakey.getLive();<br />var spBack:Sprite = chromakey.getBackground();<br />var spMask:Sprite = chromakey.getMask();<br />var spFore:Sprite = chromakey.getForeground();<br /><br />this.addChild( spLive );<br />this.addChild( spBack );<br />this.addChild( spMask );<br />this.addChild( spFore );</pre><br />The getLive() method returns a sprite which shows the live video. You can use it as a background for your app.<br /><br />The getBackground() method returns a sprite which shows the stationary background image. You can use it as a background for your app as well.<br /><br />The getMask() method returns a transparent sprite which shows the blue mask image. You may not use it normally.<br /><br />The getForeground() method returns a transparent sprite which shows the dynamic foreground image. It would contain a person or objects in front of camera. You can use it as a foreground for your app.<br /><br /><h2>LiveChromaKey Properties</h2>Set properties below before call init() method.<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">chromakey.captureX = 320;<br />chromakey.captureY = 240;<br />chromakey.captureFPS = 30;</pre>Web camera input source's resolution and frame rate<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">chromakey.displayX = 640;<br />chromakey.displayY = 480;<br />chromakey.smoothing = false;</pre>Output sprites' resolution and smoothing.<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">chromakey.workX = 80;<br />chromakey.workY = 60;</pre>Working resolution by pixel.<br /><br />The following method and property is for after it started.<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">chromakey.runDetector()</pre>Method to re-recognize stationary background.<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">chromakey.ready</pre>Boolean value for stationary background is detected.<br /><br /><h2>How To Compile It</h2>Download LiveChromaKey source code from the Spark project.<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">svn&nbsp;co&nbsp;http://www.libspark.org/svn/as3/LiveChromaKey/trunk/ livechromakey</pre><br /><br /><i>* Original posts for <a href="http://kawa.at.webry.info/200905/article_8.html">demo #1</a>, <a href="http://kawa.at.webry.info/200905/article_9.html">demo #2</a> and <a href="http://kawa.at.webry.info/200905/article_10.html">demo #3</a> are written in Japanese.</i><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-8176688269788818575?l=kawanet.blogspot.com'/></div> Tokyo Cloud Developers Meetup #02 feat. Google App Engine http://kawanet.blogspot.com/2009/05/tokyo-cloud-developers-meetup-02-feat.html Yusuke Kawasaki 2009-05-29T14:37:36.610+09:00 0 <a href="http://atnd.org/events/757"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 80px;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/Sh9y1g8R1EI/AAAAAAAAAkM/bpDGDDdGjMA/s400/124357437150516403869%5B1%5D.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5341113946786092098" /></a><br />We'll welcome Fred Sauer, Google Developer Advocate,as the special guest of the second Tokyo Cloud Developers Meetup on June 10. Come over on June 10 to enjoy the latest topics around Google App Engine.<br /><br /><span style="font-weight:bold;">Register now! <a href="http://atnd.org/events/757">http://atnd.org/events/757</a> <br /></span><br /><h3>EVENT</h3><ul><li>Date and Time: June 10, 2009 from 19:00 to 21:00 (doors open 18:30)</li><li>Location: Recruit Annex 1 (B1F)</li><li>Address: 7-2-6 Ginza, Chuo-ku, Tokyo</li><li>Map: <a href="http://maps.google.com/maps?ll=35.6708,139.7605&z=19">http://tinyurl.com/nsfcfn</a></li><li>Registration: <a href="http://atnd.org/events/757">http://atnd.org/events/757</a> (free)</li></ul><br /><h3>SPEAKERS</h3><ul><li>Special Guest: Fred Sauer</li><li>Takashi Matsuo (Python) <a href="http://takashi-matsuo.blogspot.com/">http://takashi-matsuo.blogspot.com/</a></li><li>Taigo Yamada (Python)</li><li>Tsutomu Yano (Java/Wicket) <a href="http://d.hatena.ne.jp/t_yano/">http://d.hatena.ne.jp/t_yano/</a></li><li>Yasuo Higa (Java/Slim3) <a href="http://d.hatena.ne.jp/higayasuo/">http://d.hatena.ne.jp/higayasuo/</a></li><li>Yasushi Ando (Rails) <a href="http://d.hatena.ne.jp/technohippy/">http://d.hatena.ne.jp/technohippy/</a></li><li>Moriyoshi Koizumi (PHP) <a href="http://d.hatena.ne.jp/moriyoshi/">http://d.hatena.ne.jp/moriyoshi/</a></li></ul><br /><h3>VENUE</h3><center><iframe src="http://map.doko.jp/blogparts/b/sc=1141072/sz=2/zm=12/" width="320" height="400" frameborder="0" scrolling="no"><a href="http://www.doko.jp/search/shop/sc1141072/">リクルートアネックス1ビル(アネックス)[ドコイク?]</a></iframe></center><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-2032745082162116653?l=kawanet.blogspot.com'/></div> HTML5.Audio - JavaScript MP3 Player Library (HTML5-like) http://kawanet.blogspot.com/2009/05/html5audio-javascript-mp3-player.html Yusuke Kawasaki 2009-05-23T12:02:44.600+09:00 javascript mp3 html5 1 <a href="http://dev.w3.org/html5/spec/Overview.html#audio">HTML5 allows &lt;audio&gt; element</a> to play MP3 and other sound formats by HTML and JavaScript. But HTML5 is still not in major. So I wrote <a href="http://svn.coderepos.org/share/lang/javascript/HTML5.Audio/trunk/">HTML5.Audio</a> which is a JavaScript library to play MP3 music via Flash.<br /><br />Demo #1: <a href="http://svn.coderepos.org/share/lang/javascript/HTML5.Audio/trunk/examples/simple.html">Play sound by HTML5.Audio</a><br /><br />Demo #2: <a href="http://svn.coderepos.org/share/lang/javascript/HTML5.Audio/trunk/examples/player.html">MP3 player</a><br /><br /><h3>Before Using It</h3><br />You can manipulate HTML5.Audio object like HTML5's Audio object.<br />To prepare it, load three JavaScript files on HTML header.<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">&lt;script type="text/javascript" src="js/swfobject.js"&gt;&lt;/script&gt; <br />&lt;script type="text/javascript" src="js/jkl-js2as.js"&gt;&lt;/script&gt; <br />&lt;script type="text/javascript" src="js/html5-audio.js"&gt;&lt;/script&gt;</pre><br /><h3>Plat MP3</h3><br />Create HTML5.Audio instance with MP3 file URL. Then, call play() method to play it. It totally simple like HTML5's Audio object.<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">&lt;script type="text/javascript"&gt;&lt;!--<br /><br />music = new HTML5.Audio('sound.mp3');<br />music.play();<br /><br />--&gt;&lt;/script&gt;</pre>Note that HTML5.Audio library support MP3 files at this time.<br />WAV file and other sound formats are not supported. ActionScript's Sound class limits it.<br /><br /><h3>Properties</h3><br />HTML5.Audio library supports some properties imported from HTML5's Audio object: currentTime, volume, paused, ended, loop and duration<br />You need to call set()/get() method to set/get properties.<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">var ctime = music.get('currentTime');<br /><br />music.set('volume',0.8);</pre>Note that currentTime property will be updated only when playing music is started and paused.<br /><br /><h3>Events</h3><br />HTML5.Audio library supports some of events callbacked: onloadstart, onload, onplay, onpause and onended<br />You need to call set() method to set callback function for event property.<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">var onended = function () {<br /> alert( 'sound ended' );<br />}<br /><br />music.set( 'onended', onended );<br /></pre><br /><h3>Options</h3><br />HTML5.Audio library loads <tt>html5-audio.swf</tt> flash file which was written by ActionScript 3.0.<br />To set path for <tt>html5-audio.swf</tt>, call <tt>getProxy()</tt> method before creating the first instance of HTML5.Audio.<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">&lt;script type="text/javascript"&gt;&lt;!--<br /><br />HTML5.Audio.Proxy.getProxy({swfPath:'./html5-audio.swf',onready: init});<br /><br />--&gt;&lt;/script&gt;</pre>Note that onready property is an event which will invoked when HTML5.Audio library was ready to play. You can call getProxy() method before window.onload event was invoked.<br /><br /><h3>Files</h3><ul><li>js/html5-audio.js - HTML5.Audio library core (JS part)</li><li>js/jkl-js2as.js - JS-AS bridge (JS part)</li><li>js/swfobject.js - Library to load flash file</li><li>swf/html5-audio.swf - HTML5.Audio library Flash binary</li><li>swf/expressInstall.swf - Says install/update Flash!</li></ul><br /><h3>Download</h3><br />Check out files from the Spark project repository:<br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">svn&nbsp;co&nbsp;<a href="http://svn.coderepos.org/share/lang/javascript/HTML5.Audio/trunk" target="_blank">http://svn.coderepos.org/share/lang/javascript/HTML5.Audio/trunk</a> html5-audio</pre><br /><br /><i>* <a href="http://kawa.at.webry.info/200905/article_7.html">Original post of this</a> was written in Japanese at 2009/05/17 17:40</i><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-197316472656038002?l=kawanet.blogspot.com'/></div> JSARToolKit - AR (Augmented Reality) by JavaScript http://kawanet.blogspot.com/2009/05/jsartoolkit-ar-augmented-reality-by.html Yusuke Kawasaki 2009-05-23T12:02:16.792+09:00 javascript actionscript flash ar 0 After <a href="">my talk at OSDC.TW 2009 in Taipei</a>, I've released JSAR's source code on <a href="http://www.libspark.org/">the Spark project</a>'s repository:<br /><a href="http://www.libspark.org/svn/js/JSARToolKit/trunk">http://www.libspark.org/svn/js/JSARToolKit/trunk</a><br /><br />JSARToolKit is a JavaScript library to run AR (augmented reality).<br />This is the first JavaScript project on the Spark. :)<br /><br /><div align="center"><a href="http://www.libspark.org/svn/js/JSARToolKit/trunk/examples/jsarlogo.html" target="_blank"><img src="http://4.bp.blogspot.com/_cgZUdkW7lzE/ShdesV5pKOI/AAAAAAAAAjs/g2ejBsXUm3o/s400/124145510665716332295_jsar-red%5B1%5D.jpg" height="240" width="320"></a></div><br /><h3>Demo #1 - Show Logo</h3>Try: <a href="http://www.libspark.org/svn/js/JSARToolKit/trunk/examples/jsarlogo.html">JSAR Logo Demo</a><br />Download and print marker pdf: <a href="http://www.libspark.org/svn/js/JSARToolKit/trunk/pdf/jsarlogo.pdf">Maker PDF (JSAR Logo Only)</a><br /><br />Demo #1 shows a label "JSAR" in DIV element overlayed on Flash. Red square border on marker was drawn by canvas. It means both of label and lines are controlled by JavaScript not by ActionScript.<br /><br /><h3>Demo #2 - Mic Volume</h3>Try: <a href="http://www.libspark.org/svn/js/JSARToolKit/trunk/examples/micvolume.html">Mic Volume Demo</a> <br />Download and print markers pdf: <a href="http://www.libspark.org/svn/js/JSARToolKit/trunk/pdf/jsar-markers.pdf">Makrers PDF (4 patterns)</a><br /><br />Demo #2 shows a label for each markers and changes its font size effected by microphone volume inputed.<br /><br /><h3>Sample Code</h3><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">&lt;script type="text/javascript" src="../js/swfobject.js"&gt;&lt;/script&gt;<br />&lt;script type="text/javascript" src="../js/jsar.js"&gt;&lt;/script&gt; <br />&lt;script type="text/javascript"&gt;&lt;!--<br /><br />&nbsp;&nbsp;var jsar;<br />&nbsp;&nbsp;function init () {<br />&nbsp;&nbsp;&nbsp;&nbsp;jsar = new JSAR( 'jsar_here' );<br />&nbsp;&nbsp;&nbsp;&nbsp;jsar.drawMarkerRect = true;<br />&nbsp;&nbsp;&nbsp;&nbsp;jsar.onDetected = function ( result ) { ... };<br />&nbsp;&nbsp;&nbsp;&nbsp;jsar.onLost = function ( result ) { ... };<br />&nbsp;&nbsp;&nbsp;&nbsp;jsar.captureX = 320;<br />&nbsp;&nbsp;&nbsp;&nbsp;jsar.captureY = 240;<br />&nbsp;&nbsp;&nbsp;&nbsp;jsar.displayX = 640;<br />&nbsp;&nbsp;&nbsp;&nbsp;jsar.displayY = 480;<br />&nbsp;&nbsp;&nbsp;&nbsp;jsar.init();<br />&nbsp;&nbsp;&nbsp;&nbsp;jsar.setMarker( [ '../code/jsarlogo.pat' ] );<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;window.onload = init;<br />--&gt;&lt;/script&gt; <br />&lt;div id="jsar_here"&gt;&lt;/div&gt; </pre><br /><h3>How To Compile It</h3>JSARToolKit uses FLARToolKit in it. This means JSAR is not pure JavaScript, but flash powered. Download JSARToolKit from the Spark project by svn command, and compile it by Flash CS4 or by FlashDevelop + Flex SDK.<br /><br /><pre style="border: 1px solid gray; padding: 8px; line-height: 1.2em; background: #EEEEEE;">svn&nbsp;co&nbsp;http://www.libspark.org/svn/js/JSARToolKit/trunk&nbsp;jsar<br />mkdir&nbsp;-p&nbsp;jsar/src/org/libspark<br />svn&nbsp;co&nbsp;http://www.libspark.org/svn/as3/FLARToolKit/trunk/src/org/libspark/flartoolkit&nbsp;jsar/src/org/libspark/flartoolkit</pre><br />In fact, you can use <a href="http://www.libspark.org/svn/js/JSARToolKit/trunk/swf/jsar.swf">jsar.swf</a> pre-compiled. So you don't need to compile it by your self.<br /><br />I need say thank you to <a href="http://saqoosha.net/en/">Saqoosha</a> who has developed FLARToolKit.<br /><br /><i>* <a href="http://kawa.at.webry.info/200905/article_4.html">Original post of this</a> was written in Japanese at 2009/05/05 01:46.</i><br />&nbsp;<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-5384733389303215028?l=kawanet.blogspot.com'/></div> JSAR (JavaScript Augmented Reality) at OSDC.TW 2009 Taipei http://kawanet.blogspot.com/2009/04/jsar-javascript-argumented-reality-at.html Yusuke Kawasaki 2009-05-23T11:09:49.669+09:00 javascript jsar osdctw2009 0 Last weekend, I flew to Taipei to attend the OSDC.TW 2009, OpenSource Developers Conference in Taiwan. I had a talk titled <a href="http://blog.hcchien.org/OSDCTW/2009/03/schedule_the_jui_digest_javasc.html">"The JUI Digest Taipei"</a> there. JUI means JavaScript User Interface:<br /><br /><a href="http://kawanet.blogspot.com/2008/06/jui-2008-tokyo-was-over.html">The JUI 2008 Tokyo</a> (first)<br /><a href="http://kawanet.blogspot.com/2009/03/2nd-jui-conference-in-adobe-max-japan.html">The 2nd JUI Conference in Adobe MAX Japan 2009</a><br /><br />In addition to the recent topics in the 2nd JUI, I showed the JASR (JavaScript Augmented Reality) demonstration.<br /><br /><a href="http://www.flickr.com/photos/u-suke/3459075143/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_cgZUdkW7lzE/SfNnHO5U0iI/AAAAAAAAAjM/8IwCbKnMSPE/s400/jsar-title.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5328716158064710178" /></a>JSARToolKit is a library to run AR by JavaScript. It works as a proxy wrapper for a bridge application using FLARToolKit.<br /><br />Try it : <a href="http://www.kawa.net/works/js/jsar/demo1.html">JSAR Demo #1</a><br />Get marker PDF : <a href="http://www.kawa.net/works/js/jsar/pdf/jsar-logo.pdf">JSAR logo for print</a><br />Get marker PDF : <a href="http://www.kawa.net/works/js/jsar/pdf/jsar-star.pdf">4 markers for print</a><br /><br /><a href="http://www.flickr.com/photos/u-suke/3459967838/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/SfNnMg29VgI/AAAAAAAAAjc/p0M_MNsGigc/s400/jsar-xiaolongbao.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5328716248785966594" /></a>Then, today's main dish was <b>"AiR Xiaolongbao"</b>.<br />A dozen XiaoLongBao (小籠包) were shown on the table by JavaScript!<br /><br />Try it : <a href="http://www.kawa.net/works/js/jsar/demo3-xiao.html">AiR Xiaolongbao Demo</a><br />Get marker PDF : <a href="http://www.kawa.net/works/js/jsar/pdf/jsar-xiaolongbao.pdf">XiaoLongbao markers for print</a> (free)<br /><br />This was a hommage for <a href="http://www.youtube.com/watch?v=OR-oM3ZWR2g">Air Yakiniku (Air焼肉)</a> as a Chinese version.<br /><br /><a href="http://www.flickr.com/photos/u-suke/3459075595/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/SfNnJ6VM_PI/AAAAAAAAAjU/OKc2tUfBtJY/s400/jsar-try.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5328716204084100338" /></a>Some of front-row seated attendees helped me to show that JSAR supports multiple markers. <a href="http://twitter.com/obra">Jesse</a> drew his improvisatorial "JSAR" marker whis was fainally recognized at the last of my talk.<br /><br />See <a href="http://www.slideshare.net/kawa0117/the-jui-digest-taipei-jsar-osdctw-2009">my slides on slideshare</a>.<br /><div style="text-align:center" id="__ss_1321342"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/kawa0117/the-jui-digest-taipei-jsar-osdctw-2009?type=powerpoint" title="The JUI Digest Taipei (JSAR) - OSDC.TW 2009">The JUI Digest Taipei (JSAR) - OSDC.TW 2009</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=cdocumentsandsettingsu-sukejuijui-osdctw2009-090421093442-phpapp01&rel=0&stripped_title=the-jui-digest-taipei-jsar-osdctw-2009" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=cdocumentsandsettingsu-sukejuijui-osdctw2009-090421093442-phpapp01&rel=0&stripped_title=the-jui-digest-taipei-jsar-osdctw-2009" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div><br />This was my sencond trip to Taipei. We really enjoyed there again. Last year, I gave another talk titled <a href="http://kawanet.blogspot.com/2008/05/osdctw-2008-dom-manipulation-by.html">DOM manipulation by Wiimote/Gainer over HTTP</a> in OSDC.TW 2008. That was also first time for me to talk about Wii Remote. I evolved it later and talked it in some other YAPCs places. I guess I will talk the JSAR again for other conferences this year as well. See you soon!<br /><br />BTW, JSARToolKit uses FLARToolKit internally. I must say thank you for Saqoosha who is one of the most cool Japanese Flash guys. And <a href="http://saqoosha.net/2009/03/18/1725/">he will give a talk about FLARToolKit</a> in the <a href="http://www.fitc.ca/events/presentations/presentation.cfm?event=79&presentation_id=880">FITC Tronto 2009</a> conference this weekend. Don't miss it!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-259357087157144974?l=kawanet.blogspot.com'/></div> Re: XML::TreePP behavior change between 0.19 and 0.38 http://tech.groups.yahoo.com/group/xml-treepp/message/31 Kawasaki Yusuke 2009-05-08T15:29:11Z Jon, Thanks for your reporting and using it long. I rarely do change the default behavior of my module. But it's true that it seems that it's changed at tdserver - An Experimental HTTP Interface for Tokyo Dystopia http://kawanet.blogspot.com/2009/05/tdserver-experimental-http-interface.html Yusuke Kawasaki 2009-05-02T02:35:57.742+09:00 tokyocabinet http tokyotyrant tokyodystopia 1 <a style="float:right; margin:0 0 10px 10px;" href="http://tokyocabinet.sourceforge.net/"><img src="http://2.bp.blogspot.com/_cgZUdkW7lzE/SfswUoXe8HI/AAAAAAAAAjk/HIkQTTuPtdE/s400/logo%5B1%5D.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5330907714914545778" /></a>I just wrote an experimental HTTP interface for <a href="http://tokyocabinet.sourceforge.net/dystopiadoc/">Tokyo Dystopia</a>. Tokyo Dystopia is an open source full-text search system using <a href="http://tokyocabinet.sourceforge.net/">Tokyo Cabinet</a> which is very fast key-value storage by Mikio Hirabayashi. Some code is derived from <a href="http://tokyocabinet.sourceforge.net/tyrantdoc/">Tokyo Tyrant</a> which is a network interface of Tokyo Cabinet.<br /><br />tdserver is also an open source project on CodeRepose.<br /><a href="http://svn.coderepos.org/share/lang/c/tdserver/trunk/">http://svn.coderepos.org/share/lang/c/tdserver/trunk/</a><br /><br /><h3>1. COMPILE</h3><br />Compile Tokyo Cabinet, Tyrant, Dystopia and then tdserver.<br />You don't need to install them at this time.<br /><pre style="border: 1px solid green; padding: 8px 4px 8px 8px; line-height: 1.2em; background: #FFEEFF;">wget&nbsp;http://tokyocabinet.sourceforge.net/tokyocabinet-1.4.17.tar.gz<br />wget&nbsp;http://tokyocabinet.sourceforge.net/tyrantpkg/tokyotyrant-1.1.23.tar.gz<br />wget&nbsp;http://tokyocabinet.sourceforge.net/dystopiapkg/tokyodystopia-0.9.11.tar.gz<br /><br />tar zxvf tokyocabinet-1.4.17.tar.gz<br />tar zxvf tokyotyrant-1.1.23.tar.gz<br />tar zxvf tokyodystopia-0.9.11.tar.gz<br /><br />cd tokyocabinet-1.4.17<br />./configure && make<br />cd ..<br /><br />cd tokyotyrant-1.1.23<br />CFLAGS=-I../tokyocabinet-1.4.17 LDFLAGS=-L../tokyocabinet-1.4.17 ./configure && make<br />cd ..<br /><br />cd tokyodystopia-0.9.11<br />CFLAGS=-I../tokyocabinet-1.4.17 LDFLAGS=-L../tokyocabinet-1.4.17 ./configure && make<br />cd ..<br /><br />svn co http://svn.coderepos.org/share/lang/c/tdserver/trunk/ tdserver<br />cd tdserver<br />make</pre><br /><h3>2. USAGE</h3><br />See help message by -h option.<br /><pre style="border: 1px solid green; padding: 8px 4px 8px 8px; line-height: 1.2em; background: #FFEEFF;">./tdserver -h<br />./tdserver: A server of Tokyo Dystopia<br /><br />usage:<br /> ./tdserver [-host name] [-port num] [-thnum num] [-tout num] [-dmn] [-pid path] [-kl] [-log path] [-ld|-le] [-sid num] [-mask expr] [-unmask expr] [dbname]</pre><br /><h3>3. START DAEMON</h3><br />tdserver will create <tt>td_base</tt> directory then listen port 1977 as a HTTP server.<br /><pre style="border: 1px solid green; padding: 8px 4px 8px 8px; line-height: 1.2em; background: #FFEEFF;">./tdserver -port 1977 td_base</pre><br /><h3>4. ACCESS RESTfully</h3><br /><br />Three HTTP methods, GET, PUT and DELETE are accepted as RESTful interface.<br />Try it by Perl as follows.<br /><br />* Insert (PUT method)<pre style="border: 1px solid green; padding: 8px 4px 8px 8px; line-height: 1.2em; background: #FFEEFF;">perl -MLWP::UserAgent -MHTTP::Request::Common -e 'print LWP::UserAgent-&gt;new-&gt;request(PUT "http://localhost:1977/<b>1</b>",Content=&gt;"<b>hello world</b>")-&gt;as_string;'</pre>This inserts a text "hello world" as a document #1.<br />ID# must be a positive numeric.<br /><br />* Fetch (GET method)<pre style="border: 1px solid green; padding: 8px 4px 8px 8px; line-height: 1.2em; background: #FFEEFF;">perl -MLWP::UserAgent -MHTTP::Request::Common -e 'print LWP::UserAgent-&gt;new-&gt;request(GET "http://localhost:1977/<b>1</b>")-&gt;as_string;'</pre>This returns document #1 directly.<br /><br />* Search (GET method with query string)<pre style="border: 1px solid green; padding: 8px 4px 8px 8px; line-height: 1.2em; background: #FFEEFF;">perl -MLWP::UserAgent -MHTTP::Request::Common -e 'print LWP::UserAgent-&gt;new-&gt;request(GET "http://localhost:1977/?q=<b>hello</b>")-&gt;as_string;'</pre>This searchs documents which contain phrase "hello" and returns ID numbers comma separated.<br /><br />* Remove (DELETE method)<pre style="border: 1px solid green; padding: 8px 4px 8px 8px; line-height: 1.2em; background: #FFEEFF;">perl -MLWP::UserAgent -MHTTP::Request::Common -e 'print LWP::UserAgent-&gt;new-&gt;request(HTTP::Request::Common::DELETE "http://localhost:1977/<b>1</b>")-&gt;as_string;'</pre>This removes document #1.<br /><br />Feed backs and patches on CodeRepos are really welcomed.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-1548642448461650139?l=kawanet.blogspot.com'/></div> Re: Interest in following up on the XML-FeedPP-0.40 http://tech.groups.yahoo.com/group/xml-feedpp/message/61 Kawasaki Yusuke 2009-04-28T01:35:13Z Hello Joao, Thanks for your mail. ... Yes. Term "RDF" in the module means RSS1. ... Yes, mostly. Rare special format of content body would be hard to parse by Re: Item description replaced with item summary and item content http://tech.groups.yahoo.com/group/xml-feedpp/message/60 Kawasaki Yusuke 2009-04-20T21:50:12Z Hi Victor, XML::TreePP loses some sort of xml elements' order even if "use_ixhash" => 1 option is used. This would not have any problem for parsing/writing XML The First Tokyo Cloud Developers Meetup was over. http://kawanet.blogspot.com/2009/04/first-tokyo-cloud-developers-meetup-was.html Yusuke Kawasaki 2009-04-12T10:12:37.401+09:00 event cloud amazon tokyocloud 0 <a href="http://kawanet.blogspot.com/2009/03/tokyo-cloud-developers-meetup-on-april.html">As I mentioned</a>, we had the first <a href="http://atnd.org/events/481">Tokyo Cloud Developers Meetup</a> this Thursday with great success. It's got 64 registrants which is over capacity for the seminar room in Amazon Japan K.K. We'd like to have the next meetup. <a href="http://groups.google.com/group/tokyocloud">Join the group</a> and stay tuned.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://atnd.org/events/481"><img style="display:block; margin:0px auto 0px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/SeE-QJhRwJI/AAAAAAAAAi8/mMipQZJC_GI/s400/123943865994116128315_tokyo-cloud-title%5B1%5D.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5323604681682960530" /></a><br />Photo by Gui Trento <a href="http://www.flickr.com/photos/guitrento/2564986045/">"Blue sky over the monday morning"</a><br /><br />Above was the opening slide for the event. I love the picture of the beautiful blue sky with clouds. Thanks, Gui.<br /><br /><h3>Keynote</h3>Jeff Barr (Amazon) <a href="http://www.jeff-barr.com/" target="_blank">http://www.jeff-barr.com/</a><br /><br />He gave us a talk in English without interpretation.<br />I guess most of Japanese attendees could understand most of what he said with help of his slides and demos.<br />He talked a bit faster in last half though. :-)<br /><br />The busy evangelist had other conferences in Japan, the <a href="http://qcontokyo.com/">QCon Tokyo 2009</a> and an <a href="http://itpro.nikkeibp.co.jp/article/EVENTS/20090309/326164/">ITpro Technology Conference</a> for Amazon Cloud Services. They cost JPY 30,000 for each, approximately $300. The guys who attended the more techy meetup were lucky because it's free of charge.<br /><br />After his talk, Japanese developers gave lightening talks.<br /><br /><h3>Tightening Talks</h3>1. Yamazaki Yasuhiro - <a href="http://www.slideshare.net/yasuhiro_yamazaki/lightning-talk-wakame-on-9-april-2009">slideshare</a><br />2. Yuki Namikawa<br />3. Takao Funami - <a href="http://www.slideshare.net/funami/amazon-lt">slideshare</a><br />4. Manabu Igarashi<br />5. Yukio Ando - <a href="http://www.slideshare.net/yukio.andoh/tokyo-cloud-yukio-ando-20090409">slideshare</a><br /><br />These were more techy and interesting.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.flickr.com/photos/u-suke/3426843446/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_cgZUdkW7lzE/SeE-EN7Qz6I/AAAAAAAAAi0/QPm9TxIuDE4/s400/3426843446_8322a2b7d2%5B1%5D.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5323604476707262370" /></a><br />This was my first time to come into Amazon's place in Japan. Nonetheless they provide the most popular cloud services in the world, they don't provide a connection to the cloud from the conference room in due to their security policy though. :-)<br />Anyway, most attendees surprised and regarded Amazon's nice office.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.flickr.com/photos/u-suke/3426847734/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SeE-e3S80zI/AAAAAAAAAjE/YTePb4Bdgpk/s400/3426847734_87a8920c7b%5B1%5D.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5323604934489068338" /></a><br />At last, I must say again thank you to Jeff Barr.<br />We're longingly awaiting the news from Amazon that provides the EC2 Asia region service with Japan zone servers.<br />&nbsp;<br />&nbsp;<br /><i style="font-size:80%"><a href="http://kawa.at.webry.info/200904/article_1.html">Original post of this</a> was written in Japanese.</i><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-7969839712238894196?l=kawanet.blogspot.com'/></div> Re: possible bug in XML::FeedPP http://tech.groups.yahoo.com/group/xml-feedpp/message/55 Kawasaki Yusuke 2009-04-08T05:45:01Z Hi Haidut, I got another error "Loading failed" with XML::FeedPP v0.40. In the case, it seems that it need more time to be connected. Try with timeout option 0.40 released http://tech.groups.yahoo.com/group/xml-feedpp/message/54 Kawasaki Yusuke 2009-04-06T21:37:58Z XML::FeedPP version 0.40 was released. http://www.kawa.net/works/perl/feedpp/feedpp-e.html http://search.cpan.org/dist/XML-FeedPP/ [Perl] XML::FeedPP - Parse/write/merge/edit RSS/RDF/Atom syndication feeds http://www.kawa.net/works/perl/feedpp/feedpp-e.html 2009-04-07T06:32:00+09:00 Perl XML::FeedPP is an all-purpose syndication utility that parses and publishes RSS 2.0, RSS 1.0 (RDF), Atom 0.3 and 1.0 feeds. It allows you to add new content, merge feeds, and convert among various formats. It is a pure Perl implementation and does not require any other module except for XML::TreePP. Released version: XML-FeedPP-0.40.tar.gz TARGZ CPAN Subversion repository: http://xml-treepp.googlecode.com/svn/trunk/XML-FeedPP/ SVN Documents: README README Changes Changes Tokyo Cloud Developers Meetup on April 9 http://kawanet.blogspot.com/2009/03/tokyo-cloud-developers-meetup-on-april.html Yusuke Kawasaki 2009-03-28T15:50:55.994+09:00 event cloud amazon ec2 0 <center><a href="http://atnd.org/events/481"><img style="display:block; padding: 0; margin: 0; border: 0;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/Sc3FkxpyQhI/AAAAAAAAAig/WfZf2NduhGM/s400/tokyo-cloud-500x100.jpg" alt="Jeff Barr" id="BLOGGER_PHOTO_ID_5318123970588983826" /></a></center><br />Jeff Barr, Amazon's Senior Manager of Cloud Computing Solutions, will be visiting Tokyo April 9-13 as part of his Asia-tour. Come over on April 9 to hear the latest news on Amazon's plans Web Services at an informal developer meetup. Peter and me are the organizers of the event.<br />&nbsp;<h3>EVENT</h3><ul><li>Date and Time: April 9, 2009 from 19:30 to 21:00 (doors open 19:00)</li><li>Location: Amazon Japan K.K. <a href="http://maps.google.com/maps?q=%22Amazon+Japan%22&f=l&sll=35.66,139.70&iwloc=A">[map]</a></li><li>Address: Shibuya Cross Tower, 2-15-1 Shibuya, Shibuya-ku. Tokyo</li></ul><h3>AGENDA</h3><a href="http://www.jeff-barr.com/"><img style="float:right; margin: 1em; padding: 0; border: 0; width: 107px; height: 150px;" src="http://2.bp.blogspot.com/_cgZUdkW7lzE/Sc3FnpsARHI/AAAAAAAAAio/iI7kakcQQk0/s400/jeff_barr.jpg" alt="Tokyo Cloud" id="BLOGGER_PHOTO_ID_5318124019990414450" /></a><ul><li>Keynote by Jeff Barr, Senior Amazon Evangelist (<a href="http://www.jeff-barr.com/">http://www.jeff-barr.com/</a>)</li><li>Lightning talks by AWS experts in Japan (We're looking for speakers!)</li><li>Q&amp;A / Free discussion</li></ul>After the meetup, we'll have a nomikai at Tengu in Shibuya. <a href="http://www.mapion.co.jp/c/f?uc=4&pg=1&grp=teng&ino=BA577595">[map]</a><br />The cost will be split amongst all participants, probably around 3-4,000 yen per person.<br /><br />Only 40 seats available so sign up quickly!<br /><a href="http://atnd.org/events/481">Register now by ATND</a> or just send an email for us:<br /><tt>tokyo-cloud@googlegroups.com</tt><br />Oh, and please let us know beforehand if you would like to join the nomikai or not.<br /><br />* Note that this is <b>NOT</b> an official event by Amazon Japan K.K.<br />&nbsp;<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-4023200775187468729?l=kawanet.blogspot.com'/></div> Re: Enclosures and images support ready - test it http://tech.groups.yahoo.com/group/xml-feedpp/message/53 Kawasaki Yusuke 2009-03-23T12:27:40Z Hi Victor, XML::TreePP module does nothing about namespaces actually. xmlns:rdf="" is treated just an attribute in root element. The module never validate Re: Enclosures and images support ready - test it http://tech.groups.yahoo.com/group/xml-feedpp/message/51 Kawasaki Yusuke 2009-03-21T14:22:23Z Hey Vicror, I mean we need care more for users. I would not like to change the default behavior in the minor updates. You must know that many users are already Re: Enclosures and images support ready - test it http://tech.groups.yahoo.com/group/xml-feedpp/message/49 Kawasaki Yusuke 2009-03-21T13:11:36Z Victor, Thanks for your nice work. I don't think XML::FeedPP's multimedia support is best at this time, so it could be help many users. I was away last week to The 2nd JUI Conference in Adobe MAX Japan 2009 http://kawanet.blogspot.com/2009/03/2nd-jui-conference-in-adobe-max-japan.html Yusuke Kawasaki 2009-03-18T09:31:03.330+09:00 javascript adobe flash 0 Almost one year has been past since we held <a href="http://kawanet.blogspot.com/2008/06/jui-2008-tokyo-was-over.html">the 1st JUI conference</a> in Tokyo. The JUI is a conference forcused into user interface techs using JavaScript. At he end of this January, we held the JUI again in <a href="http://jp.max.adobe.com/">Adobe MAX Japan 2009</a> conference as a sub conference. I think it's definitely true that Adobe is really big-hearted company. Five of JavaScript guys could talked only about JavaScript at the session which has the sub-title of "we don't need FLash any more!" in Japanese.<br /><br />At first, I gave an introduction talk.<br /><br /><div align="center"><object width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=jui-kawasaki-at-adobe-max-japan-2009-1234668436617463-1&rel=0&stripped_title=jui-flash"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=jui-kawasaki-at-adobe-max-japan-2009-1234668436617463-1&rel=0&stripped_title=jui-flash" type="application/x-shockwave-flash" width="425" height="355"></embed></object><br /><a style="font-size:75%; font-weight:normal;" href="http://www.slideshare.net/kawa0117/jui-flash">http://www.slideshare.net/kawa0117/jui-flash</a></div><br /><b>JavaScript Hot Topics 2008</b> (Adobe MAX Edition)<br />#10 - 10th Anniversary of MM_SwapImage()<br />#9 - Shibuya.js comes to Kyoto<br />#8 - ECMAScript 4 failed. Now 3.1 instead.<br />#7 - Adobe launches Flash 10<br />#6 - iPhone 3G integrated with JavaScript<br />#5 - Many companies switching to JavaScript<br />#4 - Microsoft follows web standards by IE8<br />#3 - Varieties of JavaScript libraries<br />#2 - Playing .swf by JavaScript on the scene<br />#1 - Too Rapid JavaScript. No JIT, No Life.<br /><br />The 2nd speaker was <a href="http://d.hatena.ne.jp/yukoba/">Yu Kobayashi</a> a.k.a. yukoba who was the author of <a href="http://hotruby.yukoba.jp/">HotRuby</a> virtual machine. His talk was about <b>"How to implement a Flash Player."</b><br /><br /><div align="center"><object width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=FlashPlayer-090223213304-phpapp01&rel=0&stripped_title=flash-player"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=FlashPlayer-090223213304-phpapp01&rel=0&stripped_title=flash-player" type="application/x-shockwave-flash" width="425" height="355"></embed></object><br /><a style="font-size:75%; font-weight:normal;" href="http://www.slideshare.net/yukoba/flash-player">http://www.slideshare.net/yukoba/flash-player</a></div><br />The next was <a href="http://d.hatena.ne.jp/gyuque/">Satoshi Ueyama</a> a.k.a. gyuque. He also implemented another Flash Player named <b>"JSplash"</b> which had a trick to translate ActionScript code to JavaScript code. This pre-compiling feature gave it enough performance compared to Adobe's native Flash Player. That means we don't need flash player any more.<br /><br /><div align="center"><object width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=max2009fin-1233559547008468-1&rel=0&stripped_title=jsplash-adobe-max-2009"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=max2009fin-1233559547008468-1&rel=0&stripped_title=jsplash-adobe-max-2009" type="application/x-shockwave-flash" width="425" height="355"></embed></object><br /><a style="font-size:75%; font-weight:normal;" href="http://www.slideshare.net/gyuque/jsplash-adobe-max-2009">http://www.slideshare.net/gyuque/jsplash-adobe-max-2009</a></div><br />The 4th was <a href="http://d.hatena.ne.jp/moriyoshi/">Moriyoshi Koizumi</a> who was one of Japanese PHP committers. He gave a talk about <b>"JavaScript's Sound Generation"</b> using <a href="http://www.kawa.net/works/js/data-scheme/base64-e.html">data scheme</a>.<br /><br /><div align="center"><object width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=MAX-090223075638-phpapp02&rel=0&stripped_title=adobe-max-japan-2009-jui-javascript"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=MAX-090223075638-phpapp02&rel=0&stripped_title=adobe-max-japan-2009-jui-javascript" type="application/x-shockwave-flash" width="425" height="355"></embed></object><br /><a style="font-size:75%; font-weight:normal;" href="http://www.slideshare.net/moriyoshi/adobe-max-japan-2009-jui-javascript">http://www.slideshare.net/moriyoshi/adobe-max-japan-2009-jui-javascript</a></div><br />The last was <a href="http://d.hatena.ne.jp/amachang/">Hotoshi Amano</a> a.k.a. amachang. He always starts to develop new presentation tool before he writes slides for each conferences. Now he made it in 3D. Note that only nightly build of WebKits <i>- at that time, now Safari 4 is available -</i> could show his slides. His talk itself was about <b>"DOM Performance Tuning."</b><br /><br /><div align="center"><a href="http://amachang.sakura.ne.jp/misc/max/"><img src="http://2.bp.blogspot.com/_cgZUdkW7lzE/ScA-Bsppa9I/AAAAAAAAAiQ/uatB19Q-AfE/s400/123557210619116127804_amachang-max_20090225232826%5B1%5D.jpg" style="border:0;padding:0;margin:0;"></a><br /><a style="font-size:75%; font-weight:normal;" href="http://amachang.sakura.ne.jp/misc/max/">http://amachang.sakura.ne.jp/misc/max/</a></div><br />Anyway, in the Adobe's conference, we're happy to let them know these <i>crazy</i> JavaScript guys're existing and working hard for the high level of techniques and user experience.<br /><br /><div align="center"><a href="http://www.flickr.com/photos/u-suke/archives/date-taken/2009/01/30/"><img src="http://3.bp.blogspot.com/_cgZUdkW7lzE/ScBAlTVfwkI/AAAAAAAAAiY/yVIgrWaKRz8/s400/123468204728916415491%5B1%5D.jpg" style="border:0;padding:0;margin:0;"></a><br />The 2nd JUI Speakers</div><br /><a href="http://kawa.at.webry.info/200902/article_4.html">The original post</a> of this was written in Japanese.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-7220492254034823573?l=kawanet.blogspot.com'/></div> The history of JavaScript's 3D tech development http://kawanet.blogspot.com/2009/03/history-of-javascripts-3d-tech.html Yusuke Kawasaki 2009-03-17T11:06:34.989+09:00 javascript 3d 1 Before most of popular browsers start to support canvas "3d" context, we JavaScript developers have struggled how to implement to enable 3D by JavaScript without any extensions like Java, Flash, etc. Here is a part of the history of JavaScript's 3D tech development.<br /><h3 style="padding:0; margin: 1em 0 0 0; border-bottom: 1px solid blue;">Animation.Cube - April 2006</h3><br /><center><a href="http://www.kawa.net/works/js/animation/cube-e.html"><img src="http://1.bp.blogspot.com/_cgZUdkW7lzE/Sb8BitjlabI/AAAAAAAAAhI/4Tff4skzZ7c/s400/1-cube.jpg" style="border: 0; padding: 0; margin: 0;" id="BLOGGER_PHOTO_ID_5313967781176502706"></a></center> Three years ago, I wrote a library named <a href="http://www.kawa.net/works/js/animation/cube-e.html">Animation.Cube</a> which slices images into many vertical lines to show rotating cube. I demonstrated this at <a href="http://shibuyajs.org/articles/2006/03/27/shibuya-js-technical-talk-1">the first technical talks of Shibuya.js</a> community. The code is on <a href="http://www.openjsan.org/doc/k/ka/kawasaki/Animation/Cube/">JSAN</a>. See also <a href="http://digg.com/programming/Javascript_Rotating_Cube_Animation_Slideshow_Effect">digg</a>.<br /><h3 style="padding:0; margin: 1em 0 0 0; border-bottom: 1px solid blue;">Triangles by Border of Div - October 2006</h3><br /><center><a href="http://www.uselesspickles.com/triangles/demo.html"><img height="200" src="http://2.bp.blogspot.com/_cgZUdkW7lzE/Sb8BnPjILdI/AAAAAAAAAhQ/NWzO71VtmBU/s400/2-triangles.jpg" style="border: 0; padding: 0; margin: 0;" id="BLOGGER_PHOTO_ID_5313967859020869074"> <img height="200" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/Sb8BprTpnyI/AAAAAAAAAhY/j3iqLyHOJmM/s400/3-div-triangle.gif" style="border: 0; padding: 0; margin: 0;" id="BLOGGER_PHOTO_ID_5313967900831883042"></a></center><br /><a href="http://www.uselesspickles.com/blog/2006/10/18/javascript-triangles-and-real-time-3d/">Useless Pickles (Jeff Lau)</a> shows polygons drawn by many triangles made by &lt;div&gt; elements using trick of borders. It means we <b>could</b> develop <a href="http://en.wikipedia.org/wiki/Virtua_Fighter">Virtua Fighter (1)</a> by JavaScript.<br /><h3 style="padding:0; margin: 1em 0 0 0; border-bottom: 1px solid blue;">3D by Canvas - March 2008</h3><br /><center><a href="http://www.kawa.net/works/js/wire3d/v2/wiimote3d.html"><img src="http://3.bp.blogspot.com/_cgZUdkW7lzE/Sb8BtLpVEFI/AAAAAAAAAhg/msQcxl7xlyM/s400/4-wii-painted.jpg" style="border: 0; padding: 0; margin: 0;" id="BLOGGER_PHOTO_ID_5313967961052352594"></a></center> Again, I wrote a new demo using &lt;canvas&gt; element to draw <a href="http://kawa.at.webry.info/200803/article_3.html">wireframe image</a> and <a href="http://kawa.at.webry.info/200804/article_1.html">polygons</a> as well. The code was written for another demo to manipulate Wii Remote controllers, I had sessions talked at <a href="http://kawanet.blogspot.com/2008/05/osdctw-2008-dom-manipulation-by.html">OSDC.TW 2008</a> (Taipei), <a href="http://kawanet.blogspot.com/2008/05/yapcasia-2008-tokyo-dom-manipulation-by.html">YAPC::Asia 2008</a> (Tokyo), <a href="http://kawanet.blogspot.com/2008/06/yapcna-2008-in-chicago.html">YAPC::NA 2008</a> (Chicago), and <a href="http://kawa.at.webry.info/200808/article_6.html">YAPC::Europe 2008</a> (Copenhagen) conferences.<br /><h3 style="padding:0; margin: 1em 0 0 0; border-bottom: 1px solid blue;">3D Renderer with Textures - March 2008</h3><br /><center><a href="http://www.nihilogic.dk/labs/canvas3dtexture_0.2/"><img src="http://4.bp.blogspot.com/_cgZUdkW7lzE/Sb8BvcctUiI/AAAAAAAAAho/deBlP0H7NS0/s400/5-earth.jpg" style="border: 0; padding: 0; margin: 0;" id="BLOGGER_PHOTO_ID_5313967999922557474"></a></center> At just about the same time, <a href="http://blog.nihilogic.dk/">Jacob Seidelin</a> gave a <a href="http://www.nihilogic.dk/labs/canvas3dtexture_0.2/">great demo with texture mapped polygons</a> using &lt;canvas&gt; element.<br /><h3 style="padding:0; margin: 1em 0 0 0; border-bottom: 1px solid blue;">Triangle Texture Mapping on Wii - April 2008</h3><br /><center><a href="http://wiioperasdk.com/texturemap.html"><img src="http://2.bp.blogspot.com/_cgZUdkW7lzE/Sb8B6qLiOaI/AAAAAAAAAiI/s3VyQLvThLo/s400/9-wii-opera.jpg" style="border: 0; padding: 0; margin: 0;" id="BLOGGER_PHOTO_ID_5313968192587184546"></a></center><br /><a href="http://my.opera.com/wiioperasdk/blog/2008/04/29/triangle-texture-mapping-now-in-the-wii-opera-sdk">Daniel Gump</a> released Wii Opera SDK which had triangle texture-mapping feature. It is a SDK for Nintendo Wii's Internet Channel. He said it could show 500 textured triangles per second on Wii.<br /><h3 style="padding:0; margin: 1em 0 0 0; border-bottom: 1px solid blue;">Motion Blur - May (maybe) 2008</h3><br /><center><a href="http://www.kaarellumi.com/asylum/html/dyn10_3.htm"><img height="200" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/Sb8Bxls1qdI/AAAAAAAAAhw/wiluii9dGFI/s400/6-blur.jpg" style="border: 0; padding: 0; margin: 0;" id="BLOGGER_PHOTO_ID_5313968036765870546"></a></center><br /><a href="http://www.kaarellumi.com/">Kaarel Lumi</a> represented a beautiful <a href="http://en.wikipedia.org/wiki/Motion_blur">motion blur</a> using alpha blending tech by fillStyle. Thanks, <a href="http://twitter.com/moriyoshi/status/1211744785">@moriyoshi</a>.<br /><h3 style="padding:0; margin: 1em 0 0 0; border-bottom: 1px solid blue;">Projective Texturing - November 2008</h3><br /><center><a href="http://acko.net/files/projective/index.html"><img src="http://3.bp.blogspot.com/_cgZUdkW7lzE/Sb8B2Vjo7MI/AAAAAAAAAh4/grPvdrtJZDA/s400/7-index.jpg" style="border: 0; padding: 0; margin: 0;" id="BLOGGER_PHOTO_ID_5313968118331665602"></a></center><br /><a href="http://acko.net/">Steven Wittens</a> also wrote <a href="http://acko.net/files/projective/index.html">projective transform renderer</a>. I'm interested in the tech which make an adjustment on size of the image cutted. It makes many cuts for front pieces.<br /><h3 style="padding:0; margin: 1em 0 0 0; border-bottom: 1px solid blue;">Sphere Environment Mapping - February 2009</h3><br /><center><a href="http://d.hatena.ne.jp/gyuque/20090211#1234364019"><img src="http://3.bp.blogspot.com/_cgZUdkW7lzE/Sb8B4lQT42I/AAAAAAAAAiA/qsYEUUAjyI0/s400/8-touch.jpg" style="border: 0; padding: 0; margin: 0;" id="BLOGGER_PHOTO_ID_5313968156905300834"></a></center><br /><a href="http://d.hatena.ne.jp/gyuque/">Satoshi Ueyama</a> reported that Chrome had extremely fast canvas rendering engine named Skia by demonstrating <a href="http://d.hatena.ne.jp/gyuque/20090211#1234364019">his demos and benchmarks</a>. He also described in detail how to implement texture mapping by canvas in <a href="http://d.hatena.ne.jp/gyuque/20090211#1234364019">his post</a>. He also implemented physical computing and sphere environment mapping feature on it. His demos showed us that now we could run JavaScript 3D by real-time / daily-usable performance on Chrome. And I guess rest of popular browsers will soon come to the stage. See also <a href="http://kawanet.blogspot.com/2009/02/incredible-javascriptcanvas-3d-demos.html">my post</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-5408712324519479705?l=kawanet.blogspot.com'/></div> [Perl] XML::TreePP - A pure Perl implementation for parsing/writing xml file http://www.kawa.net/works/perl/treepp/treepp-e.html 2009-03-01T23:06:00+09:00 Perl XML::TreePP module parses XML file and expand it for a hash tree. And also this generates XML file from a hash tree. This module is a pure Perl implementation. You can also fetch an XML file from remote web server like an XMLHttpRequest object in JavaScript language. I think that XML::TreePP is enough fast and easy to use! Released version: XML-TreePP-0.38.tar.gz TARGZ CPAN Subversion repository: http://xml-treepp.googlecode.com/svn/trunk/XML-TreePP/ SVN Documents: README README Changes Changes Tweet this - a bookmarklet to post URL to Twitter http://kawanet.blogspot.com/2009/02/tweet-this-bookmarklet-to-post-url-to.html Yusuke Kawasaki 2009-02-26T18:31:04.926+09:00 bookmarklet twitter 1 <a href="http://twitter.com/kawa0117"><img style="cursor:pointer; cursor:hand; float:right; width: 125px; height: 29px;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SaZgdJLCMYI/AAAAAAAAAgQ/oThjquiwKNg/s400/twitter_logo_125x29%5B1%5D.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5307035264697381250" /></a>This is my first bookmarklet.<br />The bookmarklet posts the current page's title and URL to <a href="http://twitter.com/kawa0117">Twitter</a>. I guess many of similar bookmarklets would be found somewhere though.<br /><br /><b><a href="javascript:(function(){f='http://twitter.com/home?status='+encodeURIComponent(document.title+' '+window.location.href+' ');a=function(){if(!window.open(f,'_blank'))location.href=f};if(/Firefox/.test(navigator.userAgent)){setTimeout(a,0)}else{a()}})()">Tweet this</a></b><br /><br />Drag &amp; drop the link above to your browser's bookmark toolbar.<br />Its code is referred to <a href="http://delicious.com/help/bookmarklets">delicous's bookmarklet</a>.<br /><blockquote style="word-break: break-all; font-size: 120%; font-family: monospace;">javascript:(function(){f='http://twitter.com/home?status='+encodeURIComponent(document.title+' '+window.location.href+' ');a=function(){if(!window.open(f,'_blank'))location.href=f};if(/Firefox/.test(navigator.userAgent)){setTimeout(a,0)}else{a()}})()</blockquote><br />Thanks, <a href="http://delicious.com/kawa.net">delicious</a>!<br />I don't know the license type of the code snippet, however. ;-)<br /> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-4312829731318577159?l=kawanet.blogspot.com'/></div> Incredible JavaScript+Canvas 3D demos from Japan! http://kawanet.blogspot.com/2009/02/incredible-javascriptcanvas-3d-demos.html Yusuke Kawasaki 2009-02-24T02:59:31.389+09:00 javascript 3d canvas 9 <a href="http://d.hatena.ne.jp/gyuque/20090211#1234364019">Mr. Satoshi Ueyama hacked out</a> the new era of JavaScript 3D tech by unveiling the real of Google Chrome's power. Satoshi is one of the great JavaScript hackers in Japan, and also known as <a href="http://d.hatena.ne.jp/gyuque/">gyuque</a> listed on the article of <a href="http://hemiolia.com/blog/200902/000150">30 Japanese geeks you should follow on Twitter</a>. (<a href="http://www.google.com/search?q=cache:hemiolia.com/blog/200902/000150">cached</a>) <br /><br />He has introduced the brand new JavaScript technique using Canvas for 3D on <a href="http://d.hatena.ne.jp/gyuque/20090211#1234364019">his post</a>. Browsing with <strong><a href="http://www.google.com/chrome">Google Chrome</a> is strongly recommended</strong> for all demos below.<br /><br />I'm sure this could be one giant leap for JavaScript user interface technologies.<br /><br /><h3>Demo #1: 3D texture mapped with physical computing</h3>This is his first demo which shows 3D textured by Canvas. You can click on the cloth to make it waved.<br /><br /><a href="http://gyu.que.jp/jscloth/" style="display:block; margin: 0 auto; text-decoration: none; text-align: center;"><img style="border: none;" src="http://2.bp.blogspot.com/_cgZUdkW7lzE/SaLd07KOc7I/AAAAAAAAAfo/fXiU7AZn66I/s400/jscloth.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5306047212299383730" /><br />http://gyu.que.jp/jscloth/</a><br /><h3>Demo #2: Hatsune Miku 3D with OOP</h3>The 3D Miku is OO-style implemented as an object which has swing() method. This means she swings green onion in her hand when swing() method is called. Click on her.<br /><br /><a href="http://gyu.que.jp/jscloth/miku.html" style="display:block; margin: 0 auto; text-decoration: none; text-align: center;"><img style="border: none;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SaLd7ec5OHI/AAAAAAAAAfw/Qdb-9siruqs/s400/miku.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5306047324852140146" /><br />http://gyu.que.jp/jscloth/miku.html</a><br />She wears hundreds of polygons. The demo was created for <a href="http://paulbakaus.com/">Paul Bakaus</a>, jQuery UI lib's lead, visiting Japan.<br /><br /><a href="http://www.flickr.com/photos/u-suke/3255465226/in/datetaken/" style="display:block; margin: 0 auto; text-decoration: none; text-align: center;"><img style="border: none;" src="http://2.bp.blogspot.com/_cgZUdkW7lzE/SaLdl3meLjI/AAAAAAAAAfg/DCHp3NXiDP0/s400/paul-bakaus-3d.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5306046953646075442" /></a><br /><h3>Demo #3: 3D iPod touch with environment mapping</h3>You may find the all demos above have the same width as 480px. Yes, it is definitely same as the horizontal viewport size which iPhone and iPod touch have. Now you can see iPod touch displayed on your iPod touch by the demo #3!<br /><br />It could be slightly slow on ITSELF, however, it's still cool. These demos show us that we rarely need Flash anymore on the mobile platform, right? ;)<br /><br /><a href="http://gyu.que.jp/jscloth/touch.html" style="display:block; margin: 0 auto; text-decoration: none; text-align: center;"><img style="border: none;" src="http://4.bp.blogspot.com/_cgZUdkW7lzE/SaLd_b2-m2I/AAAAAAAAAf4/eacqsGnUydY/s400/touch-front.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5306047392875715426" /><br />http://gyu.que.jp/jscloth/touch.html</a><br />But the most important point of the demo is not its width. You need to see behind of it. He also implemented the reflection mapping feature on his lib.<br /><br /><a href="http://gyu.que.jp/jscloth/touch.html" style="display:block; margin: 0 auto; text-decoration: none; text-align: center;"><img style="border: none;" src="http://4.bp.blogspot.com/_cgZUdkW7lzE/SaLeDb1mWpI/AAAAAAAAAgA/1vr2AXn02qA/s400/touch-back.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5306047461589408402" /><br />http://gyu.que.jp/jscloth/touch.html</a><br />The all demos above are coded only by pure JavaScript using Canvas. Here are no Java, Flash, ActionScript etc. but just the Web standards.<br /><br />You can see Google Chrome runs all demos much faster than any other browsers. It has a great rendering engine named Skia. CPUs are already enough fast to calculate most things, you know, and now JITs are implemented as well. But canvas renderers admit of their performance. Skia is special. Safari is also fine. Firefox, 3.0 and 3.1 JIT-ed, are seem to be slower, unfortunately. We don't have to say that IE have no capability to run these.<br /><br />Gyuque runs several benchmarks to describe Skia has significant advantage on its canvas rendering engine.<br /><br /><a href="http://d.hatena.ne.jp/gyuque/20090211#1234364019" style="display:block; margin: 0 auto; text-decoration: none; text-align: center;"><img style="border: none;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SaLf_gbwmoI/AAAAAAAAAgI/Wo3w2b5BYA8/s400/skia-vs-cairo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5306049593126984322" /><br />http://d.hatena.ne.jp/gyuque/20090211#1234364019</a><br />The 3D JavaScript tech could be one of the killer applications of Chrome now. I guess the next generation of browsers will soon compete on Canvas performance.<br /><br /><a href="http://kawa.at.webry.info/200902/article_5.html">Original of this post</a> was written for my Japanese blog.<br />You must see more detail on <a href="http://d.hatena.ne.jp/gyuque/20090211#1234364019">gyuque's post</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-7493255322043273800?l=kawanet.blogspot.com'/></div> XML::TreePP version 0.37 http://tech.groups.yahoo.com/group/xml-treepp/message/29 Kawasaki Yusuke 2009-01-17T17:13:28Z XML::TreePP version 0.37 was shipped. http://search.cpan.org/dist/XML-TreePP/ http://www.kawa.net/works/perl/treepp/dist/XML-TreePP-0.37.tar.gz A path to Ganga Fuji Home in Varanasi / バラナシのガンガー・フジ・ホームの行き方 http://www.youtube.com/watch?v=Pcn1Unf34zE 2009-06-28T20:02:49.000Z YusukeKawasaki 2009-01-11T06:31:33+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=Pcn1Unf34zE"><img alt="" src="http://i.ytimg.com/vi/Pcn1Unf34zE/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=Pcn1Unf34zE">A path to Ganga Fuji Home in Varanasi / バラナシのガンガー・フジ・ホームの行き方</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>路地は細く、牛糞だらけ。Desaswamedh Ghatから歩いて5分くらい。</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 388</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"></div> <div style="font-size: 11px;">0 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">05:46</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=19">Travel &amp; Events</a></td></tr></tbody></table></div> Pop Pop Boat / ポンポン船 http://www.youtube.com/watch?v=axskKB9surs 2009-06-29T09:13:13.000Z YusukeKawasaki 2009-01-10T17:56:19+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=axskKB9surs"><img alt="" src="http://i.ytimg.com/vi/axskKB9surs/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=axskKB9surs">Pop Pop Boat / ポンポン船</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>『崖の上のポニョ』に出てきた玩具のボート。 インド・バラナシ(旧:ベナレス)の玩具屋の店頭で撮影。 Rs.25 (50円)。 交渉すれば、もうちょっと安く買えた気がする。</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 215</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"></div> <div style="font-size: 11px;">0 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">01:10</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=28">Science &amp; Technology</a></td></tr></tbody></table></div> Snake charming in Varanasi / バラナシのヘビ使い http://www.youtube.com/watch?v=VBkIuBMG72o 2009-06-29T11:24:29.000Z YusukeKawasaki 2009-01-10T17:53:07+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=VBkIuBMG72o"><img alt="" src="http://i.ytimg.com/vi/VBkIuBMG72o/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=VBkIuBMG72o">Snake charming in Varanasi / バラナシのヘビ使い</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>Rs.10 (20円) あんまりウマくなかったので、安めに。 ときどき、笛や手でヘビを叩いてる。撮影前には一度、噛まれそうになっていた。</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 398</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"></div> <div style="font-size: 11px;">1 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">01:06</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=24">Entertainment</a></td></tr></tbody></table></div> Massaging on Ganga River shore / ガンジス河の岸でマッサージ http://www.youtube.com/watch?v=iEZUIEkSnEA 2009-06-28T07:17:24.000Z YusukeKawasaki 2009-01-10T17:34:48+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=iEZUIEkSnEA"><img alt="" src="http://i.ytimg.com/vi/iEZUIEkSnEA/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=iEZUIEkSnEA">Massaging on Ganga River shore / ガンジス河の岸でマッサージ</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>Rs.50 for 20 min / 20分100円</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 156</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"></div> <div style="font-size: 11px;">0 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">00:52</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=19">Travel &amp; Events</a></td></tr></tbody></table></div> How to wear a turban in India / インドのターバンの巻き方 http://www.youtube.com/watch?v=yOnfgZ4mnAY 2009-06-29T11:21:38.000Z YusukeKawasaki 2009-01-10T17:16:59+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=yOnfgZ4mnAY"><img alt="" src="http://i.ytimg.com/vi/yOnfgZ4mnAY/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=yOnfgZ4mnAY">How to wear a turban in India / インドのターバンの巻き方</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>Rs.50 (100円) バラナシ(旧:ベナレス)で店主さんにターバンの巻き方を教えてもらった。</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 1152</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"></div> <div style="font-size: 11px;">0 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">00:14</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=26">Howto &amp; Style</a></td></tr></tbody></table></div> OSDC.TW 2008 - DOM manipulation by Wiimote/Gainer over HTTP http://kawanet.blogspot.com/2008/05/osdctw-2008-dom-manipulation-by.html Yusuke Kawasaki 2008-11-13T20:09:39.105+09:00 event 0 12th April, I gave a new talk titled <a href="http://www.kawa.net/text/osdc.tw/2008/wiimote-dom.html">"DOM manipulation by Wiimote/Gainer over HTTP"</a> for the <a href="http://www.osdc.tw/osdc2008/english/news_1/">OSDC.TW 2008</a> at Taipei.<br /><br /><a href="http://www.kawa.net/text/osdc.tw/2008/wiimote-dom.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SBs89pi_1nI/AAAAAAAAARk/lQW5LYi6brc/s400/osdc-tw-title%5B1%5D.gif" border="0" id="BLOGGER_PHOTO_ID_5195813624924329586" /></a><br />I think manipulating DOM is a bother. That is why I have developed the <a href="http://www.kawa.net/works/js/jkl/parsexml-e.html">JKL.ParseXML</a> and <a href="http://www.kawa.net/works/js/xml/objtree-e.html">XML.ObjTree</a> libraries for my use. And I was involved in kinds of <a href="http://kawanet.blogspot.com/2008/02/gainer-over-http-and-devicegainer.html">real device web service</a> techs in these days. The presentation could be an answer from me about DOM manipulation. ;-)<br /><br />The same titled talk will be soon made again in both of the <a href="http://conferences.yapcasia.org/ya2008/">YAPC::Asia 2008 Tokyo</a> and the <a href="http://conferences.mongueurs.net/yn2008/">YAPC::NA 2008</a> at Chicago.<br /><br /><i>Special thanks:</i><br /> * Hiroshi Nemoto - <a href="http://code.google.com/p/wiimote-over-http/">Wiimote HTTPd</a>'s co-author<br /> * Hitoshi Amano (a.k.a. amachang) - <a href="http://amachang.art-code.org/pr/">S6 presentation tool</a>'s author<br /> * Shuhei Terai (a.k.a. <a href="http://www.trick7.com/blog/">trick7</a>) - Gainer's maestro<br /><br /><a href="http://mtl.recruit.co.jp/blog/2008/04/osdctw_2008.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/SBs9yJi_1oI/AAAAAAAAARs/qvRcJ6tYmeQ/s400/2407054836_4b2ab4b3d0%5B1%5D.jpg" border="0" id="BLOGGER_PHOTO_ID_5195814526867461762" /></a><br />Anyway, this was my first time to get to Taiwan. I must say that the Formosa was the great island of good foods and kind full people. <br /><br /><a href="http://www.flickr.com/photos/u-suke/sets/72157604481600832/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/SBtG1Ji_1pI/AAAAAAAAAR0/1GPfaHvd10I/s400/2408870275_95f88cc6b5%5B1%5D.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5195824474011719314" /></a><br />After the conference, I moved to <a href="http://blog.gugod.org/">gugod</a>'s office in the Jhubei City which is next to Hsinchu. I love 小籠包 (Xiaolongbao) above, however, 潤餅 (Taiwanese crepe) at a street stand was really tasty.<br /><br /><a href="http://mtl.recruit.co.jp/blog/2008/04/osdctwsocialtext.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_cgZUdkW7lzE/SBtR0Zi_1qI/AAAAAAAAAR8/qf3fFPGollk/s400/2417340057_1e66043e0b%5B1%5D.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5195836555754722978" /></a><br />I'd love to back to Taiwan again next year. <a href="http://www.flickr.com/photos/u-suke/sets/72157604481600832/">More photos...</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-4782104825559101257?l=kawanet.blogspot.com'/></div> [Event] OpenSocial - Google JAPAN's developer roundtable #5 http://kawanet.blogspot.com/2008/04/event-opensocial-google-japans.html Yusuke Kawasaki 2008-11-13T20:09:39.302+09:00 0 At 14th March, I have participated in the Google JAPAN's developer roundtable as a panel member.<br /><br /><a href="http://www.flickr.com/photos/u-suke/2332475169/in/datetaken/"><img src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SAGuyvvplwI/AAAAAAAAARc/0zq6bSmKY7M/s400/2332475169_d04a297de9%5B1%5D.jpg" border="0" alt="" /></a><br />The the great venue was the Aoyama Diamond Hall, Omote-Sando.<br /><br />The official report from Google is out:<br /><a href="http://www.google.co.jp/developer/prg/events/5-vol1.html">Google JAPAN's developer roundtable #5 - OpenSocial</a><br /><br />I introduced the <a href="http://beta.doko.jp/sandbox/get_shop.html">Dokoiku's experimental OpenSocial container</a> implemented with <a href="http://incubator.apache.org/shindig/">Shindig</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-2494893476356925756?l=kawanet.blogspot.com'/></div> "Gainer over HTTP" and the Device::Gainer module for Perl http://kawanet.blogspot.com/2008/02/gainer-over-http-and-devicegainer.html Yusuke Kawasaki 2008-11-13T20:09:39.655+09:00 0 <a href="http://gainer.cc/">Gainer</a> is one of the hottest gadgets now.<br />This weekend, I got the module lent by <a href="http://trick7.com/blog/">Shuhei Terai</a>, my colleague and a great Flash/ActionScript developer a.k.a. <i>Trick7</i>.<br /><blockquote>Gainer is an environment for user interfaces and media installations. By using the Gainer environment, the user can handle sensors and/or actuators with a PC on various programming environments such as Flash, Max/MSP, Processing and so on.<br /><i><a href="http://gainer.cc/Main/HomePage?userlang=en">http://gainer.cc/Main/HomePage?userlang=en</a></i></blockquote><br />Gainer supports some of LLs, ActionScript and Ruby (with <a href="http://funnel.cc/Main/HomePage?userlang=en">Funnel</a>).<br />Perl is not supported yet unfortunately.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cgZUdkW7lzE/R62j9zpQSyI/AAAAAAAAAQs/cADQPVT-paQ/s1600-h/120250204019616321477%5B1%5D.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/R62j9zpQSyI/AAAAAAAAAQs/cADQPVT-paQ/s400/120250204019616321477%5B1%5D.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5164964629894417186" /></a><br />So I wrote a Perl module named Device::Gainer and submitted on CodeRepos:<br /><a href="http://svn.coderepos.org/share/lang/perl/Device-Gainer/trunk/lib/Device/Gainer.pm">http://svn.coderepos.org/share/lang/perl/Device-Gainer/trunk/lib/Device/Gainer.pm</a><br /><br />SYNOPSIS:<pre>use Device::Gainer;<br />my $gainer = Device::Gainer-&gt;new( host =&gt; '192.168.1.xx' );<br />$gainer-&gt;on_pressed( sub { print "PRESS\n"; } );<br />$gainer-&gt;on_released( sub { print "RELEASE\n"; } );<br />$gainer-&gt;turn_on_led();<br />$gainer-&gt;turn_off_led();</pre>The module has enough functionality for my purpose, however,<br />it's not completed especially for documents and tests.<br />The following methods are supported currently:<br /><br /><table><tbody><tr><td>Method</td><td>Command</td></tr><tr><td><tt>turn_on_led</tt></td><td>h*</td></tr><tr><td><tt>turn_off_led</tt></td><td>l*</td></tr><tr><td><tt>digital_output</tt></td><td>D____*</td></tr><tr><td><tt>set_high</tt></td><td>H_*</td></tr><tr><td><tt>set_low</tt></td><td>L_*</td></tr><tr><td><tt>peek_digital_input</tt></td><td>R*</td></tr><tr><td><tt>analog_output</tt></td><td>a___*</td></tr><tr><td><tt>peek_analog_input</tt></td><td>I*</td></tr><tr><td><tt>on_pressed</tt></td><td>N*</td></tr><tr><td><tt>on_released</tt></td><td>F*</td></tr></tbody></table><br />Anyway, I wrote a proxy server for "<span style="font-weight:bold;">Gainer over HTTP</span>" using the Device::Gainer and <a href="http://naoya.g.hatena.ne.jp/naoya/20061113/1163418064">POE::Component::Server::HTTP</a> module.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_cgZUdkW7lzE/R62kCTpQSzI/AAAAAAAAAQ0/X54qjTOLyCk/s1600-h/gainer-httpd%5B1%5D.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/R62kCTpQSzI/AAAAAAAAAQ0/X54qjTOLyCk/s400/gainer-httpd%5B1%5D.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5164964707203828530" /></a><br />Now we can use the Gainer through the Internet!<br />This means the <b>Gainer Ajax</b> tech can be the hot topics in the Ajax/JavaScript developers as well...<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_cgZUdkW7lzE/R62kGzpQS0I/AAAAAAAAAQ8/rPWtH7S5aIY/s1600-h/gainer-over-http%5B1%5D.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/R62kGzpQS0I/AAAAAAAAAQ8/rPWtH7S5aIY/s400/gainer-over-http%5B1%5D.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5164964784513239874" /></a><br />I failed to use <a href="http://search.cpan.org/dist/Win32-SerialPort/lib/Win32/SerialPort.pm">Win32::SerialPort</a> module to connect to Gainer module directly.<br /><br /><i>The <a href="http://kawa.at.webry.info/200802/article_1.html">original</a> <a href="http://kawa.at.webry.info/200802/article_2.html">posts</a> of this were written in Japanese.</i><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-7160690705070037127?l=kawanet.blogspot.com'/></div> [Event] Tokyo ActionScript Meetup 2008 F/ Colin Moock http://kawanet.blogspot.com/2008/01/event-tokyo-actionscript-meetup-2008-f.html Yusuke Kawasaki 2008-11-13T20:09:39.784+09:00 0 When I heard that <a href="http://moock.org/blog/">Colin Moock</a> would come to Japan to make a talk in <a href="http://www.event-web.net/as3/">a seminar event</a> sponsored by Adobe Systems Inc., it hit me that we could welcome and <i>counter</i> him with top ActionScript engineers in Japan!<br />I'd like to show him the cutting-edge ActionScript techs developed in Japan, are not introduced yet to the world in English, unfortunately.<br /><br />As the result, at the day of January 16, the <strong>Tokyo ActionScript Meetup 2008 F/ Colin Moock</strong> was taken a place in Adobe Japan.<br />Very deep tech talks about ActionScript 2, 3 &amp; also 4(!) were told.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.flickr.com/photos/u-suke/2197961384/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/R47Ecjg8tcI/AAAAAAAAAO8/6a0sjl3JK90/s400/120050616053016410803%5B1%5D.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5156274618234615234" /></a><div style="text-align:center">Colin (left) and Ota-san.</div><br />The last of all, I asked him some of questions invited by the audiences on ahead.<br /><br />I think the most of audiences including me would surprised that he could speak Japanese much fluently. <br />As <a href="http://www.wall.org/~larry/">Larry Wall</a> could speak JavaScript as well, such great programmers would be good at speaking multiple natural languages as well as programming languages.<br /><br /><hr><h3>Tokyo ActionScript Meetup 2008 F/ Colin Moock</h3><span style="font-weight:bold;">KEYNOTE </span><br /> * Colin Moock <a href="http://moock.org/<br />">http://moock.org/</a><br /><br /><span style="font-weight:bold;">MAIN TALKS</span><br /> * yossy <a href="http://www.be-interactive.org/<br />">http://www.be-interactive.org/</a><br /> * munegon <a href="http://void.heteml.jp/blog/<br />">http://void.heteml.jp/blog/</a><br /> * id:secondlife <a href="http://d.hatena.ne.jp/secondlife/<br />">http://d.hatena.ne.jp/secondlife/</a><br /><br /><span style="font-weight:bold;">LIGHTNING TALKS</span><br /> * Muraken <a href="http://www.muraken.biz/">http://www.muraken.biz/</a> &amp; tera <a href="http://www.trick7.com/blog/<br />">http://www.trick7.com/blog/</a><br /> * Iwasaki <a href="http://www.cosmo-int.com/<br />">http://www.cosmo-int.com/</a><br /> * Kobayashi <a href="http://d.hatena.ne.jp/yukoba/<br />">http://d.hatena.ne.jp/yukoba/</a><br /><br /><span style="font-weight:bold;">QUESTIONS AND ANSWERS</span><br /> * Q: Kawasaki <a href="http://www.kawa.net/">http://www.kawa.net/</a> on behalf of the all audiences<br /> * A: Colin Moock <a href="http://moock.org/<br />">http://moock.org/</a><br /><br /><br />We much enjoyed the session with you.<br />Thank you, Colin! See you again!<br /><br /><hr><i>* The <a href="http://kawa.at.webry.info/200801/article_12.html">original longer post</a> of this was written in Japanese.</i><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-6949765036214806242?l=kawanet.blogspot.com'/></div> Hatsumode at the Sanno Hie Shrine http://kawanet.blogspot.com/2008/01/hatsumode-at-sanno-hie-shrine.html Yusuke Kawasaki 2008-11-13T20:09:39.946+09:00 0 At the first business day of this year, I and my all colleagues went to the Sanno Hie Shrine for <a href="http://en.wikipedia.org/wiki/Hatsum%C5%8Dde">Hatsumode</a>.<br />This is the most important ritual on the begging of new year, I think.<br />We prayed for our fine health and also our success in business.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.flickr.com/photos/u-suke/2187620662/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/R47BXjg8tbI/AAAAAAAAAO0/uou8RO6Ek68/s400/2187620662_03b5d87c1c%5B1%5D.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5156271233800385970" /></a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-845663856140697515?l=kawanet.blogspot.com'/></div> Translatable presentation with the S6 JavaScript library http://kawanet.blogspot.com/2008/05/translatable-presentation-with-s6.html Yusuke Kawasaki 2008-11-13T20:09:38.111+09:00 javascript library 0 For <a href="http://kawanet.blogspot.com/2008/05/osdctw-2008-dom-manipulation-by.html">my talk at OSDC.TW 2008</a> in Taiwan, I have added a couple of features to the <a href="http://amachang.art-code.org/pr/">S6</a>. The S6 is a great presentation tool developed by <a href="http://d.hatena.ne.jp/amachang/">amachang</a>, based on HTML/Web standards and implemented in pure JavaScript. (<a href="http://www.kawa.net/works/js/s6/oneclick.html">demo</a>)<br /><br /><a href="http://www.kawa.net/works/js/s6/oneclick.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SBta8pi_1rI/AAAAAAAAASE/89-kTO3l9QI/s400/one-click-1%5B1%5D.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5195846593093293746" /></a><br />Writing a slide with the lib is entirely easy:<br /><pre>&lt;div class="s6_fadeScale"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;h3&gt;page title here&lt;/h3&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;page body here&lt;/p&gt;<br />&lt;/div&gt;</pre><tt>class="s6_fadeScale"</tt> means <a href="http://www.kawa.net/works/js/s6/oneclick.html#page=6">the fading/scaling effect </a> on paging.<br /><br /><a name="translation"></a>And the most noteworthy feature of this special version of the S6 is automatic translation feature which is powered by <a href="http://code.google.com/apis/ajaxlanguage/">Google AJAX Language API</a>.<br /><br />Just clicking a text node on the slide, it's translated into Japanese or another language in a moment. This is efficient for I18N, M17N and native language support. (<a href="http://www.kawa.net/works/js/s6/oneclick.html#page=3">demo</a>)<br /><br /><a href="http://www.kawa.net/works/js/s6/oneclick.html#page=2"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/SBtc1Ji_1sI/AAAAAAAAASM/UAqEtRgweWU/s400/one-click-2%5B1%5D.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5195848663267530434" /></a><br /><a href="http://www.kawa.net/works/js/s6/oneclick.html#page=2">13 languages</a>, <span style="font-style:italic;">Japanese, Korean, Traditional Chinese, Simplified Chinese, Arabic, Russian, Greek, German, Italian, Dutch, French, Spanish and Portuguese</span>, are supported to be translated into. The number of languages is depend on it of the <a href="http://translate.google.com/translate_t">Google Translate</a>. Reverse translation, ex. translating from Japanese to English, is also supported for granted.<br /><br />This means, with the lib, your presentation would get more familiar for the people who could not read the language of it.<br />I'll welcome you giving cool talks in Japan with the lib. We Japanese don't need to be afraid of slides written in English anymore! :-)<br /><br /><a href="http://www.kawa.net/works/js/s6/s6-translate.zip">Download it now</a> and enjoy!<br /><br /><small><i>* The <a href="http://kawa.at.webry.info/200804/article_7.html">original post</a> of this was written in Japanese and was <a href="http://translate.google.com/translate?u=http://kawa.at.webry.info/200804/article_7.html&langpair=ja%7Cen">translatable</a>.</i></small><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-7978821903456180701?l=kawanet.blogspot.com'/></div> YAPC::Asia 2008 Tokyo - DOM manipulation by Wiimote/Gainer over HTTP http://kawanet.blogspot.com/2008/05/yapcasia-2008-tokyo-dom-manipulation-by.html Yusuke Kawasaki 2008-11-13T20:09:37.571+09:00 0 I love YAPC::Asia which is really exciting Perl conference.<br />At <a href="http://conferences.yapcasia.org/ya2008/">YAPC::Asia 2008 Tokyo</a> of this week, I got first chance to give a talk in the conference.<br /><br /><a href="http://www.kawa.net/text/yapcasia/2008/tokyo.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_cgZUdkW7lzE/SC6Tfwi0wQI/AAAAAAAAASc/e18cibjzPn8/s400/yapc-wiimote.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5201256793475694850" /></a><br />My talk was titled <b><a href="http://userdisk.webry.biglobe.ne.jp/001/614/44/N000/000/000/yapc-wiimote.gif">DOM manipulation by Wiimote/Gainer over HTTP</a></b>.<br />Some slides are updated from <a href="http://kawanet.blogspot.com/2008/05/osdctw-2008-dom-manipulation-by.html">OSDC.TW 2008</a>'s one.<br />I'll give this talk again for <a href="http://conferences.mongueurs.net/yn2008/">YAPC::NA 2008</a> in Chicago next month.<br /><br /><a href="http://userdisk.webry.biglobe.ne.jp/001/614/44/N000/000/000/2494352683_448ec2de59.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_cgZUdkW7lzE/SC6TuQi0wRI/AAAAAAAAASk/rhKYPOPf7Js/s400/2494352683_448ec2de59.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5201257042583798034" /></a><br />The room was almost full and had some standees at last!<br />Thank you for coming to listen my talk.<br /><br /><a href="http://www.flickr.com/photos/u-suke/sets/72157605070697124/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SC6T5gi0wSI/AAAAAAAAASs/7tU3zYVN5Io/s400/2494351825_d0c9a8c112.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5201257235857326370" /></a><br />The venue of the conference was <a href="http://www.titech.ac.jp/home.html">Tokyo Institute of Technology</a> at Ookayama, Tokyo.<br />It had many trees in the campus and was really nice venue.<br />The number of attendees was counted as more than 500 people.<br />The committee announced that the conference cost <a href="http://module.jp/dist/yapcasia2008-LT-oyama.pdf">about three million yen</a> (about USD 30,000) in total.<br />I'd love to say thank you for organizers and volunteers.<br /><br />As an aside, <a href="http://www.recruit.co.jp/corporate/english/">RECRUIT Co., Ltd.</a> was one of the gold sponsors of the conference. It was honor of us. The <a href="http://mtl.recruit.co.jp/about-en.html">Media Technology Labs</a> have a plan to back up such open source related conference and projects.<br />&nbsp;<br /><small>* Translated version of the <a href="http://kawa.at.webry.info/200805/article_2.html">original post</a> of this is <a href="http://translate.google.com/translate?langpair=ja%7Cen&amp;u=http://kawa.at.webry.info/200805/article_2.html">here</a>.</small><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-9163294930761692670?l=kawanet.blogspot.com'/></div> Announcement: The JUI 2008 Tokyo http://kawanet.blogspot.com/2008/05/announcement-jui-2008-tokyo.html Yusuke Kawasaki 2008-11-13T20:09:37.734+09:00 1 <a href="http://www.facebook.com/event.php?eid=11240373854"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/SBuCEJi_1tI/AAAAAAAAASU/rXgQR4gwJKY/s400/jui_logo%5B1%5D.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5195889602895795922" /></a>Today I'm proudly announcing the first JUI conference. JavaScript techs enhancing user interface on the web is getting more important not only for developers/engineers but also for general users. The JUI is the conference forcused on JavaScript User Interface techs.<br /><br /><a href="http://paulbakaus.com/?p=4">Paul Bakaus</a>, the jQuery UI Lead, will come from Germany. The leading Japanese JavaScript hackers will <i>counter (welcome)</i> him. <a href="http://translate.google.com/translate?u=http://mtl.recruit.co.jp/jui/form/&langpair=ja%7Cen">Register now!</a><br /><br /><br clear="all"><u><strong>The JUI 2008 Tokyo</strong></u><br /><br />* Date: Monday, May 19, 2008<br />* Time: 6:30pm - 9:00pm<br />* Venue: 8-4-17 Ginza, Chuo-ku, Tokyo, JAPAN <a href="http://map.doko.jp/m/sc=1141065/">[map]</a> <a href="http://maps.google.com/?q=%93%8C%8B%9E%93s%92%86%89%9B%8B%E6%8B%E2%8D%C08-4-17%20JAPAN">[map]</a> <br />* Host: The JUI Committee<br />* Sponsor: RECRUIT Media Technology Labs<br />* Contact: jui-committee [at] googlegroups.com<br />* Facebook: <a href="http://www.facebook.com/event.php?eid=11240373854">http://www.facebook.com/event.php?eid=11240373854</a><br /><br /><b>[ MAIN SPEAKERS ]</b><br />* Paul Bakaus (from Germany) - <a href="http://ui.jquery.com/">http://ui.jquery.com/</a><br />* amachang - <a href="http://d.hatena.ne.jp/amachang/">http://d.hatena.ne.jp/amachang/</a><br />* inucara - <a href="http://inucara.net/">http://inucara.net/</a><br />* iandeth - <a href="http://iandeth.dyndns.org/mt/ian/">http://iandeth.dyndns.org/mt/ian/</a><br /><br /><b>[ LIGHTNING TALKS ]</b> <sup style="color:red;">updated</sup><br /> * monjudoh - <a href="http://d.hatena.ne.jp/monjudoh/">http://d.hatena.ne.jp/monjudoh/</a><br /> * noriaki - <a href="http://blog.fulltext-search.biz/">http://blog.fulltext-search.biz/</a><br /> * Yoshiomi KURISU - <a href="http://dev.chrisryu.com/">http://dev.chrisryu.com/</a><br /> * gugod (from Taiwan) - <a href="http://blog.gugod.org/">http://blog.gugod.org/</a><br /><br /><b>[ REGISTRATION ]</b> (free of charge)<br /><a href="http://mtl.recruit.co.jp/jui/form/">http://mtl.recruit.co.jp/jui/form/</a><br /><a href="http://translate.google.com/translate?u=http://mtl.recruit.co.jp/jui/form/&langpair=ja%7Cen">English translated version</a> of the form is also tested and available.<br /><br /><b>[ CONTACT ]</b><br />* jui-committee [at] googlegroups.com<br /><br /><center><iframe src="http://map.doko.jp/blogparts/b/sc=1141065/sz=1/" width="240" height="400" frameborder="0" scrolling="no"><a href="http://www.doko.jp/search/shop/sc1141065/">RECRUIT Ginza 8 Bldg.(G8)[Dokoiku?]</a></iframe></center><br /><small>* Translated version of the <a href="http://kawa.at.webry.info/200804/article_8.html">original post</a> of this is <a href="http://translate.google.com/translate?langpair=ja%7Cen&u=http://kawa.at.webry.info/200804/article_8.html">here</a>.</small><br /><br /><hr><br />2008.05.19 LT speakers updated<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-1836012660616362513?l=kawanet.blogspot.com'/></div> YAPC::NA 2008 in Chicago http://kawanet.blogspot.com/2008/06/yapcna-2008-in-chicago.html Yusuke Kawasaki 2008-11-13T20:09:36.102+09:00 yapcna yapc perl yapcna2008 1 I have proudly attended YAPC::NA 2008 in Chicago and enjoyed that.<br />YAPC::NA is original yet another Perl conference since 1999.<br /><img style="display:block; margin:0.5em auto 0.5em; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SF6EU0xPxKI/AAAAAAAAAUE/t3I0iICH2Fg/s400/yapcna1-larry.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5214750911839061154">You can see more <a href="http://www.flickr.com/photos/u-suke/sets/72157605619931487/">my photos in Chicago</a> on flickr.<br /><br /><h3 style="margin-top: 0; margin-bottom: 0;"><a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_2008.html">YAPC::NA 2008 Pre-Conference Dinner</a></h3><br />Ingy bring me to the restaurant by his motorcycle. ingy++<br /><img style="display:block; margin:0.5em auto 0.5em; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SF6EMK1OV_I/AAAAAAAAAT0/mrvXFeCRt7I/s400/yapcna0-preconf.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5214750763142502386"><br /><h3 style="margin-top: 0; margin-bottom: 0;"><a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20081_1.html">YAPC::NA 2008 (Day 1) Get it started</a></h3><br />I attended every YAPC::Asias which were exciting and held three times in Tokyo. However, this is my first time to come to YAPC::NA.<br /><img style="display:block; margin:0.5em auto 0.5em; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_cgZUdkW7lzE/SF6EQh6_T7I/AAAAAAAAAT8/v9fA4hDredw/s400/yapcna1-hall.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5214750838060175282"><br /><h3 style="margin-top: 0; margin-bottom: 0;"><a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20082moose.html">YAPC::NA 2008 (Day 2) Just two seconds to generate .pm by WSST</a></h3><br />I gave my first talk titled:<br /><b>WSS - WebService Specification Schema and LL libraries</b><br />I still used JavaScript-powered S6 presentation tool with <a href="http://kawanet.blogspot.com/2008/05/translatable-presentation-with-s6.html">one-click translation feature</a> for my slides.<br /><img style="display:block; margin:0.5em auto 0.5em; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_cgZUdkW7lzE/SF6FCH91sLI/AAAAAAAAAVE/HvMKNpacq5Q/s400/yapcna2-wsst-title.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5214751690086265010"><br /><h3 style="margin-top: 0; margin-bottom: 0;"><a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20082stevan_littlemoose.html">YAPC::NA 2008 (Day 2) "Moose" by Stevan Little</a></h3><br />Stevan Little gave a general talk about Moose:<br /><b>Moose - A post modern object system for Perl 5</b><br />Moose is getting much popular also in Japan this year.<br /><img style="display:block; margin:0.5em auto 0.5em; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_cgZUdkW7lzE/SF6E-0DkoWI/AAAAAAAAAU8/tyjPj7NTUIs/s400/yapcna2-moose.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5214751633201996130"><br /><h3 style="margin-top: 0; margin-bottom: 0;"><a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20082ingyuse_the_moose.html">YAPC::NA 2008 (Day 2) "use the Moose;" by Ingy</a></h3><br />Ingy döt Net gave an interesting talk about:<br /><b>Perl and JavaScript</b><br />I like teh incredible <a href="http://search.cpan.org/dist/the/">the.pm</a> module.<br /><img style="display:block; margin:0.5em auto 0.5em; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_cgZUdkW7lzE/SF6EYa20tLI/AAAAAAAAAUM/tAS3QH8_LKo/s400/yapcna2-ingy3.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5214750973602608306"><br /><h3 style="margin-top: 0; margin-bottom: 0;"><a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20083lightning_talks.html">YAPC::NA 2008 (Day 3) Lightning Talks!</a></h3><br />I gave another talk titled:<br /><b>DOM manipulation by Gainer/Wiimote over HTTP</b>.<br />Before starting presentation, I had a technical trouble with my real device gadgets, however I made it.<br />I'll give this talk again at <a href="http://www.yapceurope2008.org/ye2008/">YAPC::Europe 2008</a> in Copenhagen, Denmark.<br /><img style="display:block; margin:0.5em auto 0.5em; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SF6FE84zekI/AAAAAAAAAVM/HF7bmDkA21c/s400/yapcna3-dom-wii-title.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5214751738651966018"><br /><h3 style="margin-top: 0; margin-bottom: 0;"><a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20083improvised_lightni.html">YAPC::NA 2008 (Day 3) Improvised Lightning Talks</a></h3><br />This is a brand-new style of lightning talk.<br />It's absolutely fantastic that Ingy's one thing which he'd never do in Perl.<br />He's true entertainer!<br /><img style="display:block; margin:0.5em auto 0.5em; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_cgZUdkW7lzE/SF6Eo1rc3AI/AAAAAAAAAU0/T6V9EV00ZqA/s400/ingy-strips.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5214751255680572418"><br /><h3 style="margin-top: 0; margin-bottom: 0;"><a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_2008_1.html">YAPC::NA 2008 is over</a></h3><br />I appreciate the organizer Josh McAdams's hospitality. jmcada++<br /><img style="display:block; margin:0.5em auto 0.5em; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_cgZUdkW7lzE/SF6FOG7b58I/AAAAAAAAAVU/bJqtZtLwgnE/s400/yapcna3-hackers.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5214751895966181314"><br /><h3 style="margin-top: 0; margin-bottom: 0;">Differences between YAPC::NA and YAPC::Asia</h3><br />I could find some of interesting differences between the conference and other conferences in Japan including YAPC::Asia.<br />&nbsp;<br />* <b>More foods and drinks</b><br />YAPC::Asia started to provide lunch and snacks this year.<br />Here are free drinks and delightful fruits provided in YAPC::NA.<br />&nbsp;<br />* <b>More interruptions</b><br />I think it's not common for Japanese audiences to interrupt speaker's talk to ask something. <a href="http://blog.livedoor.jp/dankogai/">Dan-san</a> could be probably only Japanese hacker who can do that? ;-)<br />&nbsp;<br />* <b>More chats in hall</b><br />Not only few people here prefer to stay at entrance to chat with another perl hackers rather than just listen presentations.<br />&nbsp;<br />* <b>More BOFs</b><br />I don't see such concurrent meetings which occur naturally in Japan.<br />&nbsp;<br />* <b>More women</b><br />Josh said that there were 17 women in second day's conference dinner.<br />It's definitely rare that we could have two-digit numbers of women attend such technical conference in Japan.<br />&nbsp;<br />* <b>Less technological previews, more productive solutions</b><br />Personally, I love talks about cutting-edge technologies, future glances, ingenious topics etc. We can see such "I-Made-It!"-styled talks in Japan.<br />Here, more speakers provide solutions for attendees' daily production.<br />&nbsp;<br />* <b>Few Japanese attendees</b><br />I was only Japanese attendee come from Japan.<br />I hope more Japanese hackers could come to give their techs out for global.<br />&nbsp;<br /><h3 style="margin-top: 0; margin-bottom: 0;">My reports written in Japanese</h3>* <a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_2008.html">YAPC::NA 2008 Pre-Conference Dinner</a><br />* <a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20081_1.html">YAPC::NA 2008 (Day 1) Get it started</a><br />* <a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20082moose.html">YAPC::NA 2008 (Day 2) Just two seconds to generate .pm by WSST</a><br />* <a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20082stevan_littlemoose.html">YAPC::NA 2008 (Day 2) "Moose" by Stevan Little</a><br />* <a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20082ingyuse_the_moose.html">YAPC::NA 2008 (Day 2) "use the Moose;" by Ingy</a><br />* <a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20083lightning_talks.html">YAPC::NA 2008 (Day 3) Lightning Talks!</a><br />* <a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_20083improvised_lightni.html">YAPC::NA 2008 (Day 3) Improvised Lightning Talks</a><br />* <a href="http://mtl.recruit.co.jp/blog/2008/06/yapcna_2008_1.html">YAPC::NA 2008 was over</a><br />* <a href="http://kawa.at.webry.info/200806/article_3.html">YAPC::NA 2008 summary report</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-507321323195705332?l=kawanet.blogspot.com'/></div> "Mashup Application and Google API" @ GDD http://kawanet.blogspot.com/2008/06/mashup-application-and-google-api-gdd.html Yusuke Kawasaki 2008-11-13T20:09:36.635+09:00 0 Last Tuesday, I gave a talk titled <a href="http://www.kawa.net/text/google/gdd2008/japan.html">"Mashup Application and Google API"</a> for <a href="http://code.google.com/intl/ja/events/developerday/2008/about.html">Google Developer Day 2008 in Japan</a>.<br /><br /><a href="http://www.flickr.com/photos/27556134@N03/2570005005/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SFbahwLLO9I/AAAAAAAAATE/5yNAtAauZvE/s400/2570005005_de8edaac95.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5212593892130241490" /></a><br /><b>[Topics]</b><br />* Google provides 60 APIs!<br />* Translatable presentation with Google AJAX Language API<br />* Organizing Mashup Award 4th with 100+ APIs in Japan<br />* Mashup of Google Maps API and Recruit Web Service UI Library<br />* Growth of Google Maps family (embeddable、static、flash)<br />* Google Char API (blank map!)<br />* AJAX Libraries API (cache for Prototype, jQuery, etc.)<br />* Brand New APIs (real device web services)<br /><br />My slides using S6 again is below. (written in Japanese)<br /><a href="http://www.kawa.net/text/google/gdd2008/japan.html">http://www.kawa.net/text/google/gdd2008/japan.html</a><br /><br /><a href="http://www.kawa.net/text/google/gdd2008/japan.html"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SFbaqdXR0OI/AAAAAAAAATM/x6Y8Q1xxttA/s400/google-title.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5212594041699553506" /></a><br />The conference was completely for developers who love Google. I am not Google's employee, you know, but I have surprised that more than 100 attendees have nevertheless come to my room.<br /><br /><a href="http://www.flickr.com/photos/27556134@N03/2570003655/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/SFbazkeKogI/AAAAAAAAATU/gLnVKnazwcc/s400/2570003655_0872ec9277.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5212594198226313730" /></a><br />In addition to my talk above, I took the platform of keynote to demonstrate in favor for OpenSocial.<br />We provides a trial service which uses an OpenSocial's container of Shindig.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-8293665723923317707?l=kawanet.blogspot.com'/></div> The JUI 2008 Tokyo was over http://kawanet.blogspot.com/2008/06/jui-2008-tokyo-was-over.html Yusuke Kawasaki 2008-11-13T20:09:36.922+09:00 0 The JUI 2008 Tokyo conference was over with great success.<br />More than 100 attendees came to the venue!<br />We really enjoyed JavaScript tech talks in depth.<br /><br /><a href="http://www.flickr.com/photos/iandeth/2510326040/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_cgZUdkW7lzE/SFbVfC8CLaI/AAAAAAAAAS0/cwsUMQ4PqRA/s400/JUI.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5212588348069260706" /></a><br /><b>The JUI 2008 Tokyo</b><br />* Date: 18:30pm, Monday, March 19, 2008<br />* Venue: Recruit Ginza 8 Bldg., Tokyo, Japan<br /><br /><b>[Main Talks]</b><br />* Paul Bakaus (from Germany) - An in-depth look at jQuery UI<br />* amachang - S6<br />* inucara - <a href="http://inucara.net/presentation/about-inucara.net/">inucara.net</a><br />* iandeth - <a href="http://iandeth.dyndns.org/mt/ian/archives/000674.html">Recruit WEB Service UI Library</a><br /><br /><b>[Lightning Talks]</b><br />* gugod (from Taiwan) - <a href="http://blog.gugod.org/2008/05/jui-lightning-talk-jformino.html">jFormino</a><br />* noriaki - <a href="http://doko.r08.jp/jui/tokyo.html">jQuery on Greasemonkey</a><br />* Yoshiomi KURISU - <a href="http://dev.chrisryu.com/2008/05/join_and_enjyoy_jui_tokyo_2008.html">Colors in jQuery</a><br />* monjudoh - Twitter client with jQuery<br /><br /><b>[Special Guests]</b><br />* Ingy (from Seattle/Taipei) - Jemplate<br />* mala - use DOM<br />* TAKESAKO - YAPC::Asia 2008 Tokyo<br /><br /><b>[Pictures]</b><br /><a href="http://www.flickr.com/photos/gugod/archives/date-posted/2008/05/21/">gugod</a>/<a href="http://www.flickr.com/photos/iandeth/sets/72157605165868154/">iandeth</a>/<a href="http://www.flickr.com/photos/u-suke/archives/date-taken/2008/05/19/">kawanet</a>/<a href="http://www.flickr.com/photos/26789009@N04/archives/date-taken/2008/05/19/">taigo</a>/<a href="http://www.flickr.com/photos/takesako/sets/72157605145039667/">takesako</a><br /><br />We got special guests to give us additional lightning talks!<br />We also had an after-party with almost half of all attendees.<br /><br /><a href="http://www.flickr.com/photos/u-suke/2506248584/"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_cgZUdkW7lzE/SFbV1bzPOuI/AAAAAAAAAS8/6Qfnr7sISQA/s400/JUI-dinner.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5212588732700375778" /></a><br />Amachang, Paul and other great JS hackers're talking about past talks in <a href="http://shibuyajs.org/">Shibuya.js</a> user group.<br />I hope I could host such a great conference again.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-6953187302997711317?l=kawanet.blogspot.com'/></div> Re: TreePP issue http://tech.groups.yahoo.com/group/xml-treepp/message/28 Kawasaki Yusuke 2008-10-26T06:47:22Z Marcin, The problem you told me was a bug on Perl 5.10.0. http://rt.perl.org/rt3/Public/Bug/Display.html?id=59516 Anyway, as many installed environments would Mashup Awards 4 授賞式オープニングムービー http://www.youtube.com/watch?v=FUFOWlhnS1Y 2009-06-23T07:53:59.000Z YusukeKawasaki 2008-10-24T06:37:46+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=FUFOWlhnS1Y"><img alt="" src="http://i.ytimg.com/vi/FUFOWlhnS1Y/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=FUFOWlhnS1Y">Mashup Awards 4 授賞式オープニングムービー</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>2008年10月19日(日)マッシュアップアワード4授賞式オープニングムービーです。 mashupaward.jp</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 172</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"></div> <div style="font-size: 11px;">0 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">01:11</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=19">Travel &amp; Events</a></td></tr></tbody></table></div> [JSONP-SE] JSONP Static Emulation http://kawanet.blogspot.com/2008/01/jsonp-se-jsonp-static-emulation.html Yusuke Kawasaki 2008-01-26T03:48:41.099+09:00 0 JSONP, JSON with Padding, is available not only with dynamic contents from server-side CGI etc., but also with static contents, just static files.<br /><br />However, such static JSONP files do NOT allow to change Padding, name of callback function.<br />JSON with FIXED padding is a kind of JSONP? It's just a mere JavaScript file?<br /><pre>callback(<br />&nbsp;&nbsp;&nbsp;&nbsp;{ foo: 'HOGE', bar: 'POMU' } // JSON content<br />);</pre>You may need to manage a queue when you handle multiple JSONP calls.<br /><br />Now, the JSONP-SE is the solution for this.<br />JSON-SE means JSON Static Emulation.<br />Change the padding, "callback" in code above, to the six lines below:<br /><pre>( function (data) {<br />&nbsp;&nbsp;&nbsp;&nbsp;var list = document.getElementsByTagName( 'script' );<br />&nbsp;&nbsp;&nbsp;&nbsp;var temp = list[list.length-1].src.match( /[\?\&]callback=([A-Za-z0-9\_\.\[\]]*)/ );<br />&nbsp;&nbsp;&nbsp;&nbsp;var func = temp ? temp[1] : 'callback';<br />&nbsp;&nbsp;&nbsp;&nbsp;eval( func+"(data)" );<br />})(<br />&nbsp;&nbsp;&nbsp;&nbsp;{ foo: 'HOGE', bar: 'POMU' } // JSON content<br />);</pre><br />This is still a static file, however, you could specify any callback function name you like.<br />The JSON content in JSON-SE is exactly the same as it in JSON.<br /><br />You could load JSONP-SE file via &lt;script&gt; element in &lt;body&gt; element.<br /><pre>&lt;script type="text/javascript" src="test.js?callback=hello"&gt;&lt;/script&gt;</pre>The callback function "hello" would be called.<br /><pre>&lt;script type="text/javascript" src="test.js"&gt;&lt;/script&gt;</pre>Without <tt>?callback=...</tt> argument is not specified, the default function "callback" would be called instead.<br /><br />You could generate &lt;script&gt; element via DOM.<br /><pre>&nbsp;&nbsp;&nbsp;&nbsp;var script = document.createElement( 'script' );<br />&nbsp;&nbsp;&nbsp;&nbsp;script.charset = 'utf-8';<br />&nbsp;&nbsp;&nbsp;&nbsp;script.type = 'text/javascript';<br />&nbsp;&nbsp;&nbsp;&nbsp;script.src = 'test.js?callback=hello';<br />&nbsp;&nbsp;&nbsp;&nbsp;document.lastChild.appendChild( script );</pre>JSONP-SE must be loaded in the bottom of the dom tree.<br /><br /><br />Such trick, fetching argument from the src attribute of the script element loaded, is used in <a href="http://script.aculo.us/">script.aculo.us</a> as well.<br /><br /><hr><i>* The <a href="http://kawa.at.webry.info/200801/article_13.html">original post</a> of this was written in Japanese.</i><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20062264-1404766774795610794?l=kawanet.blogspot.com'/></div> [Perl] Lingua::*::Romanize::* - Romanization of CJK characters http://www.kawa.net/works/perl/romanize/romanize-e.html 2008-01-20T19:30:00+09:00 Perl Lingua::*::Romanize::* modules generate roman letteres from CJK characters. Lingua::ZH::Romanize::Pinyin module parses Chinese characters, both of Mandarin and Cantonese. Lingua::JA::Romanize::Japanese module parses Japanese characters, both of Kanji and Kana. Lingua::KO::Romanize::Hangul module parses Korean characters, Hangul. [Ajax] Romanization of Korean language (Hangul) http://www.kawa.net/works/ajax/romanize/hangul-e.html 2008-01-14T02:11:00+09:00 Ajax Hangul is phonemic characters used in Korea. Enter some Korean phrases and push the button below. E.g. you can now sing songs which lyrics are written in Korean! This page is implemented by ajax and POX over HTTP. Re: [rt.cpan.org #30187] Encoding error with uncommon XML data http://tech.groups.yahoo.com/group/xml-treepp/message/25 Kawasaki Yusuke 2007-11-11T10:25:51Z @xatrix thank you for your feature requesting! I released XML::TreePP version 0.32. http://www.kawa.net/works/perl/treepp/treepp-e.html Re: XML::TreePP encoding problem http://tech.groups.yahoo.com/group/xml-treepp/message/24 Kawasaki Yusuke 2007-10-30T16:40:34Z Neik, "return if($from eq $to)" in encode_from_to is exactly simple, however, that explicit encoding/decoding is required in order to support utf8 flag. We do XML::TreePP 0.31 Released _o_ http://tech.groups.yahoo.com/group/xml-treepp/message/21 Kawasaki Yusuke 2007-09-25T19:15:25Z I announce that XML::TreePP version 0.31 was released last weekend. Previous versions had a problem in writefile() method used without utf8_flag => 1. I XML::TreePP 0.27 Released! http://tech.groups.yahoo.com/group/xml-treepp/message/20 Kawasaki Yusuke 2007-08-13T10:25:12Z I announce that XML::TreePP version 0.27 is released WITHOUT new features. You don't need to update to this if you're already using 0.25 or above. [Perl] XML::OverHTTP - A base class for XML over HTTP-styled web service interface http://www.kawa.net/works/perl/overhttp/overhttp-e.html 2007-08-12T22:15:00+09:00 Perl XML::OverHTTP is a base class for XML over HTTP-styled web service interface. This is not used directly from end-users. As a child class of this, module authors can easily write own interface module for XML over HTTP-styled web service. Current version: XML-OverHTTP-0.07.tar.gz TARGZ CPAN XML::TreePP 0.25 Released! http://tech.groups.yahoo.com/group/xml-treepp/message/19 Kawasaki Yusuke 2007-08-06T14:28:52Z I announce that XML::TreePP version 0.25 is now released with new features below: ======================================================================== # XML::TreePP 0.22 Released! http://tech.groups.yahoo.com/group/xml-treepp/message/18 Kawasaki Yusuke 2007-07-28T15:30:55Z I announce that XML::TreePP version 0.22 is released with new features below: ======================================================================== # [Perl] HTML::TagParser - Yet another HTML tag parser by pure Perl implementation http://www.kawa.net/works/perl/html/tagparser-e.html 2007-04-06T19:57:00+09:00 Perl HTML::TagParser is a pure Perl implementaion for parsing HTML files. This module provides some methods like DOM. This module is not strict about XHTML format because many of HTML pages are not strict. You know, many pages use <br> elemtents instead of <br/> and have <p> elements which are not closed. Re: xotree http://tech.groups.yahoo.com/group/xml-objtree/message/8 Kawasaki Yusuke 2007-03-11T05:05:10Z Mark, You mean your script retrieves the same content twice or more? Opera could make problems with its strong content caching though. IE and Firefox does not [JavaScript] Animation.Cube - Rotating Cube Animation Effect http://www.kawa.net/works/js/animation/cube-e.html 2007-01-08T17:19:00+09:00 JavaScript Animation.Cube class is a JavaScript library for a rotating cube animation effect. This effect needs CPU speed faster than Animation.Raster class. Yakushima Macaque - Inuyama Monkey Park #3 http://www.youtube.com/watch?v=TBM_WFDkftM 2009-06-29T06:35:07.000Z YusukeKawasaki 2007-01-06T01:53:38+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=TBM_WFDkftM"><img alt="" src="http://i.ytimg.com/vi/TBM_WFDkftM/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=TBM_WFDkftM">Yakushima Macaque - Inuyama Monkey Park #3</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>Yakushima Macaque, species of Japanese Macaque, are flocking around bonfire and eating baked sweet potato. (ヤクニホンザル@犬山モンキーパーク)</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 1236</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"></div> <div style="font-size: 11px;">0 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">01:47</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=15">Pets &amp; Animals</a></td></tr></tbody></table></div> Black Capped Squirrel Monkey - Inuyama Monkey Park #2 http://www.youtube.com/watch?v=LeF95hWgJOE 2009-06-29T07:41:04.000Z YusukeKawasaki 2007-01-06T01:44:16+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=LeF95hWgJOE"><img alt="" src="http://i.ytimg.com/vi/LeF95hWgJOE/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=LeF95hWgJOE">Black Capped Squirrel Monkey - Inuyama Monkey Park #2</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>Black Capped Squirrel Monkeys are digging feed. (ボリビアリスザル@犬山モンキーパーク)</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 2116</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_half_11x11.gif"></div> <div style="font-size: 11px;">3 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">01:33</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=15">Pets &amp; Animals</a></td></tr></tbody></table></div> [ajax] JKL.ParseXML - XML Parsing Library for JavaScript http://www.kawa.net/works/js/jkl/parsexml-e.html 2007-01-05T01:05:00+09:00 ajax JKL.ParseXML is a JavaScript library that let you convert an XML into a JavaScript object (JSON). See also XML.ObjTree class. Black Handed Spider Monkey - Inuyama Monkey Park #1 http://www.youtube.com/watch?v=5R_7-58IOF8 2009-06-29T17:28:28.000Z YusukeKawasaki 2007-01-01T23:37:59+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=5R_7-58IOF8"><img alt="" src="http://i.ytimg.com/vi/5R_7-58IOF8/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=5R_7-58IOF8">Black Handed Spider Monkey - Inuyama Monkey Park #1</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>Black Handed Spider Monkeys are catching nats. (ジェフロイクモザル@犬山モンキーパーク)</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 1929</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"></div> <div style="font-size: 11px;">1 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">01:58</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=15">Pets &amp; Animals</a></td></tr></tbody></table></div> Re: Can I read remote XML files? http://tech.groups.yahoo.com/group/xml-objtree/message/6 Kawasaki Yusuke 2006-11-27T07:41:46Z Hi Michael, Talking about Perl modules, I think JSON.pm would be good choice. This is a pure Perl implemented module which doesn't require compiling to use it. Ruby on Chinese Pinyin http://www.kawa.net/works/cantonese/canton.html 2006-11-10T10:33:00+09:00 Ajax-ized web service version of this is also available. Try it! NEW Type (or copy&paste) some chinese characters and push the button. [Perl] Lingua::*::Romanize::* - Online Demo http://www.kawa.net/works/perl/romanize/roman-demo-e.html 2006-11-06T00:46:00+09:00 Perl This page is online-demo of Lingua::*::Romanize::* modules for Perl. Enter some CJK phrases and push the button below. Chinese, Japanese and Korean characters are available. This is not a translation system but to get phonemic notation by roman letters. [ajax] AjaxTB - a pluggable trackback feature in static HTML page http://www.kawa.net/works/ajax/ajaxtb/ajaxtb-e.html 2006-09-19T00:38:00+09:00 ajax AjaxTB provides your static pages with trackback feature. AjaxTB' CGI part works to receive a trackback which is sent by visiters. AjaxTB' JavaScript part works to display trackbacks received. CMS is not needed. PHP is not required. AjaxTB is really pluggable and easy to use. Indexed RSS and JSON files are also generated when a trackback is posted. [ajax] AjaxCom - one line comment box in static HTML page http://www.kawa.net/works/ajax/ajaxcom/ajaxcom-e.html 2006-09-19T00:34:00+09:00 ajax AjaxCom provides your pages with one line comment box. You and your visiters can write comments in your static page! You know, ajax is used here. CMS is not required. PHP is not required. Ajaxcom is pluggable and easy to use. Perl/CGI works only when comments are entered. A plain text file is loaded when comments are displayed. Nakanobu Nebuta Matsuri(中延ねぶた祭り)2/2 http://www.youtube.com/watch?v=zxZfobdGbA4 2009-06-29T17:04:58.000Z YusukeKawasaki 2006-09-17T02:45:10+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=zxZfobdGbA4"><img alt="" src="http://i.ytimg.com/vi/zxZfobdGbA4/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=zxZfobdGbA4">Nakanobu Nebuta Matsuri(中延ねぶた祭り)2/2</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>Nine floats parade at Nakanobu shopping mall. This is an yet another nebuta-matsuri in Tokyo.</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 2340</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"></div> <div style="font-size: 11px;">1 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">01:00</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=24">Entertainment</a></td></tr></tbody></table></div> Nakanobu Nebuta Matsuri(中延ねぶた祭り)1/2 http://www.youtube.com/watch?v=pnks8-4O1_8 2009-06-27T16:16:40.000Z YusukeKawasaki 2006-09-17T02:37:25+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=pnks8-4O1_8"><img alt="" src="http://i.ytimg.com/vi/pnks8-4O1_8/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=pnks8-4O1_8">Nakanobu Nebuta Matsuri(中延ねぶた祭り)1/2</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>Nine floats parade at Nakanobu shopping mall. This is an yet another nebuta-matsuri in Tokyo.</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 716</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_empty_11x11.gif"></div> <div style="font-size: 11px;">0 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">00:36</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=24">Entertainment</a></td></tr></tbody></table></div> [JavaScript] XML.ObjTree - XML source code from/to JavaScript object like E4X http://www.kawa.net/works/js/xml/objtree-e.html 2006-08-18T03:14:00+09:00 JavaScript XML.ObjTree class is a parser/generater for XML source code and JavaScript object. This is a JavaScript version of XML::TreePP for Perl. This also works as a wrapper for XMLHTTPRequest and successor to JKL.ParseXML class when using with prototype.js or JSAN's HTTP.Request class. Attributes' prefix '@' like E4X (ECMAScript for XML) is also available. Safari for Intel Mac is supported. XML.ObjTree Group is now opened on Yahoo! Groups. Welcome to XML.ObjTree Group http://tech.groups.yahoo.com/group/xml-objtree/message/1 Kawasaki Yusuke 2006-08-17T18:11:06Z This group is a community for XML.ObjTree users and developers. If you have a question about the library, let us share it. Of course, your patches and Miraremakuccha - SH902i's bug http://www.youtube.com/watch?v=eE4fCbCZsU4 2009-06-29T09:47:47.000Z YusukeKawasaki 2006-07-08T02:42:44+00:00 http://gdata.youtube.com/schemas/2007#video <div style="color: #000000;font-family: Arial, Helvetica, sans-serif; font-size:12px; font-size: 12px; width: 555px;"> <table cellspacing="0" cellpadding="0" border="0"><tbody><tr><td width="140" valign="top" rowspan="2"><div style="border: 1px solid #999999; margin: 0px 10px 5px 0px;"><a href="http://www.youtube.com/watch?v=eE4fCbCZsU4"><img alt="" src="http://i.ytimg.com/vi/eE4fCbCZsU4/default.jpg"></a></div></td> <td width="256" valign="top"><div style="font-size: 12px; font-weight: bold;"><a style="font-size: 15px; font-weight: bold; font-decoration: none;" href="http://www.youtube.com/watch?v=eE4fCbCZsU4">Miraremakuccha - SH902i's bug</a> <br></div> <div style="font-size: 12px; margin: 3px 0px;"><span>Entering a phrase &quot;miraremakuccha&quot;, NTT docomo/SHARP sh902i's bug makes my phone crashed!</span></div></td> <td style="font-size: 11px; line-height: 1.4em; padding-left: 20px; padding-top: 1px;" width="146" valign="top"><div><span style="color: #666666; font-size: 11px;">From:</span> <a href="http://www.youtube.com/profile?user=YusukeKawasaki">YusukeKawasaki</a></div> <div><span style="color: #666666; font-size: 11px;">Views:</span> 1695</div> <div style="white-space: nowrap;text-align: left"><img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"> <img style="border: 0px none; margin: 0px; padding: 0px; vertical-align: middle; font-size: 11px;" align="top" alt="" src="http://gdata.youtube.com/static/images/icn_star_full_11x11.gif"></div> <div style="font-size: 11px;">1 <span style="color: #666666; font-size: 11px;">ratings</span></div></td></tr> <tr><td><span style="color: #666666; font-size: 11px;">Time:</span> <span style="color: #000000; font-size: 11px; font-weight: bold;">00:34</span></td> <td style="font-size: 11px; padding-left: 20px;"><span style="color: #666666; font-size: 11px;">More in</span> <a href="http://www.youtube.com/categories_portal?c=26">Howto &amp; Style</a></td></tr></tbody></table></div> [YUI] Link tooltip with website's thumbnail screenshot http://www.kawa.net/works/js/tips/yui-tooltips-e.html 2006-06-27T00:06:00+09:00 YUI This is a mash-up demonstration using Yahoo! UI Library's YAHOO.widget.Tooltip object with Simple API's thumbnail generating service. Try to move your mouse cursor onto the links below: [Ajax] Romanization of Chinese language (Pinyin) http://www.kawa.net/works/ajax/romanize/chinese-e.html 2006-06-13T20:13:00+09:00 Ajax Pinyin is a romanization system (phonemic notation) of Chinese characters. Enter some Chinese phrases and push the button below. Both of Simplified Chinese (GB2312) and Traditional Chinese (BIG5) are allowed. This page is implemented by ajax and POX over HTTP. See also Lingua::ZH::Romanize::Pinyin module page. [Mac] One click to crash Safari for Intel Mac http://www.kawa.net/works/ajax/tips/crash-safari/intelmac-e.html 2006-05-14T00:40:00+09:00 Mac Do you know any differences between Safari for Intel Mac and for PowerPC? Just two lines of JavaScript code below crashes Safari for Intel Mac. But Safari for PowerPC and other browsers are never crased. [Ajax] Romanization of Japanese language (Kanji and Kana) http://www.kawa.net/works/ajax/romanize/japanese-e.html 2006-05-08T04:07:00+09:00 Ajax Japanese language is written with a mix of Kanji and Kana characters. Most of Kanji characters used in Japan were imported from China. Two types of Kana characters, called Katakana and Hiragana, were created in Japan. Kana characters are general terms for the syllabic Japanese scripts. Enter some Japanese phrases and push the button below. This page is implemented by ajax and POX over HTTP. JSAN Search - JavaScript Libraries Database http://www.kawa.net/service/jsan/search/index.html 2006-05-03T20:53:00+09:00 A yet another search engine for JavaScript libraries registered on JSAN. [JavaScript] Animation.Raster - Virtual Raster Scrolling Effect http://www.kawa.net/works/js/animation/raster-e.html 2006-04-30T08:25:00+09:00 JavaScript This library provides a virtual raster scrolling's effect for images and block elements. Tested on Internet Explorer 7.0, Firefox 1.5, Opera 8.5, Safari 2.0.3 and OmniWeb 5.1.3. [Sudoku] Quick Sudoku Solving by JavaScript http://www.kawa.net/works/js/game/ncross-e.html 2006-04-18T21:54:00+09:00 Sudoku I think the most important thing of Sudoku is not getting its answer but is solving it. However, ... [JSAN] Date.W3CDTF - JavaScript Date object's W3CDTF extension http://www.kawa.net/works/js/date/w3cdtf-e.html 2006-04-05T22:49:00+09:00 JSAN Date.W3CDTF class understands the W3CDTF date/time format, an ISO 8601 profile, defined by W3C. This date/time format is the native date format of RSS 1.0. It can be used to parse these formats in order to create the appropriate objects. This is my first library to be contributed to JSAN. Date.W3CDTF class supports two types of formats below: 2005-04-23T17:20:00+09:00 (with timezone) 2005-04-23T17:20:00Z (without timezone) [ajax] Expanding DOM tree (cross browser DOM inspector) http://www.kawa.net/works/ajax/tips/dump/dom-tree.html 2006-03-21T02:41:00+09:00 ajax XML URL: [ajax] XML parser bug on iCab and OmniWeb http://www.kawa.net/works/ajax/tips/dump/icab-omniweb-bug.html 2006-03-21T02:40:00+09:00 ajax Source XML file: Flickr's RSS 2.0 file (as example) Demonstration: Expanding DOM tree (cross browser DOM inspector) CCDICT - Chinese Dictionary Search http://www.kawa.net/works/cantonese/ccdict.html 2006-03-08T16:20:00+09:00 Enter (or copy&paste) some chinese characters and push the button. [JavaScript] data: scheme URI generator / base64-encoded image file http://www.kawa.net/works/js/data-scheme/base64-e.html 2006-03-05T08:56:00+09:00 JavaScript The data: scheme can contain binary data such as image. Firefox and Opera supports the data: scheme, but IE doesn't yet. [Greasemonkey] User Scripts by kawa.net http://www.kawa.net/works/greasemonkey/myscripts-e.html 2006-02-13T21:14:00+09:00 Greasemonkey Here are my User Scripts for Greasemonkey. [ajax] Content-Type: availablity on XMLHttpRequest http://www.kawa.net/works/ajax/tips/mimetype/content-type-e.html 2006-02-09T01:05:00+09:00 ajax Some of content-types are only available on many browsers' XMLHttpRequest. [ajax] RSS BOX in your website http://www.kawa.net/works/ajax/rss/rss-box-e.html 2006-02-09T01:04:00+09:00 ajax How to put a RSS BOX in your website. JavaScript: Generating Random Passwords http://www.kawa.net/works/js/passwd/gen-passwds-e.html 2005-10-27T01:10:00+09:00 KCatch.pm - Catch warn and die to avoid "Internal Server Error" http://www.kawa.net/works/perl/catch/KCatch.pm.html 2004-11-24T00:47:00+09:00 NAME XML-TreePP-0.39/t/example/hello-en-nodecl-bom.xml0000644000175100017510000000011010737371043020605 0ustar u-sukeu-suke Hello, World! §±×÷ XML-TreePP-0.39/t/example/hello-en-latin1.xml0000644000175100017510000000015710431663515017770 0ustar u-sukeu-suke Hello, World! XML-TreePP-0.39/t/example/hello-en-noenc.xml0000644000175100017510000000013510431663522017674 0ustar u-sukeu-suke Hello, World! §±×÷ XML-TreePP-0.39/t/28_http-lwp-force.t0000755000175100017510000000505610655240324016276 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- SKIP: { local $@; eval { require HTTP::Lite; } unless defined $HTTP::Lite::VERSION; if ( ! defined $HTTP::Lite::VERSION ) { # ok } eval { require LWP::UserAgent; } unless defined $LWP::UserAgent::VERSION; if ( ! defined $LWP::UserAgent::VERSION ) { plan skip_all => 'LWP::UserAgent is not loaded.'; } if ( ! defined $ENV{MORE_TESTS} ) { plan skip_all => 'define $MORE_TESTS to test this.'; } plan tests => 26; use_ok('XML::TreePP'); my $name = ( $0 =~ m#([^/:\\]+)$# )[0]; my $url = "http://www.kawa.net/works/perl/treepp/example/envxml.cgi"; my $query = time(); { my $tpp = XML::TreePP->new(); my $http = LWP::UserAgent->new(); ok( ref $http, 'LWP::UserAgent->new()' ); $tpp->set( lwp_useragent => $http ); &test_http_req( $tpp, 'libwww-perl', POST => $url, $query ); } { my $tpp = XML::TreePP->new(); my $http = LWP::UserAgent->new(); ok( ref $http, 'LWP::UserAgent->new()' ); $tpp->set( lwp_useragent => $http ); $http->agent( "$name " ); &test_http_req( $tpp, $name, POST => $url, $query ); } { my $tpp = XML::TreePP->new(); my $http = LWP::UserAgent->new(); ok( ref $http, 'LWP::UserAgent->new()' ); $tpp->set( user_agent => "$name " ); &test_http_req( $tpp, $name, POST => $url, $query ); } { my $tpp = XML::TreePP->new(); my $http = LWP::UserAgent->new(); ok( ref $http, 'LWP::UserAgent->new()' ); $tpp->set( user_agent => "$name " ); my $ret = &test_http_req( $tpp, $name, GET => "$url?$query" ); is( $ret, $query, "QUERY_STRING: $query" ); } } # ---------------------------------------------------------------- sub test_http_req { my $tpp = shift; my $name = shift; my( $tree, $xml, $code ) = $tpp->parsehttp( @_ ); ok( ref $tree, "parsehttp: $_[1]" ); my $decl = ( $xml =~ /(<\?xml[^>]+>)/ )[0]; like( $xml, qr/(<\?xml[^>]+>)/, "XML Decl: $decl" ); is( $code, 200, "HTTP Status: $code" ); my $agent = $tree->{env}->{HTTP_USER_AGENT}; ok( $agent, "User-Agent: $agent" ); like( $agent, qr/\Q$name\E/, "Match: $name" ); $tree->{env}->{QUERY_STRING}; } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/40_writefile_jcode.t0000755000175100017510000000456410676257171016571 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { local $@; eval { require Jcode; }; plan skip_all => 'Jcode is not loaded.' if $@; eval { require File::Temp; }; plan skip_all => 'File::Temp is not loaded.' if $@; my $writable = &test_filetemp(); plan skip_all => 'temp file is not writable.' unless $writable; plan tests => 31; use_ok('XML::TreePP'); &test_writefile( 'UTF-8', 'utf8' ); &test_writefile( 'Shift_JIS', 'sjis' ); &test_writefile( 'EUC-JP', 'euc' ); } # ---------------------------------------------------------------- sub test_writefile { my $encode = shift; my $jcode = shift; ok( $encode, 'encode:'.$encode ); my $file = File::Temp->new->filename; ok( $file, "file:".$file ); my $foo_utf8 = 'こんにちは世界'; # UTF-8 my $bar_utf8 = '8÷4=2±0'; # UTF-8 my $foo_test = $foo_utf8; my $bar_test = $bar_utf8; Jcode::convert( \$foo_test, $jcode, 'utf8' ); Jcode::convert( \$bar_test, $jcode, 'utf8' ); ok( length($foo_test), 'foo length' ); ok( length($bar_test), 'bar length' ); my $tpp = XML::TreePP->new(); my $tree = { root => { foo => $foo_utf8, bar => $bar_utf8 }}; $tpp->writefile( $file, $tree, $encode ); ok( (-s $file), 'writefile' ); my $out = &read_file( $file ); like( $out, qr/\Q$foo_test\E/, 'foo raw' ); like( $out, qr/\Q$bar_test\E/, 'bar raw' ); my $check = $tpp->parsefile( $file ); ok( ref $check, 'parsefile' ); is( $check->{root}{foo}, $foo_utf8, 'foo tree' ); is( $check->{root}{bar}, $bar_utf8, 'bar tree' ); unlink( $file ); } # ---------------------------------------------------------------- sub test_filetemp { my $file = File::Temp->new->filename or return; open( TEMP, "> $file" ) or return; print TEMP "EOT\n"; close( TEMP ); my $size = ( -s $file ); unlink( $file ); $size; } # ---------------------------------------------------------------- sub read_file { my $file = shift or return; open( TEMP, $file ) or return; local $/ = undef; my $body = ; close( TEMP ); $body; } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/07_attr_prefix.t0000755000175100017510000000237010522537531015745 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 15; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $source = ''; my $tpp = XML::TreePP->new(); my $tree1 = $tpp->parse( $source ); is( $tree1->{root}->{foo}->{'-bar'}, 'hoge', "parse: default" ); my $test = $source; $test =~ s/\s+//sg; foreach my $prefix ( '-', '@', '__', '?}{][)(', '$*@^%+&', '0' ) { my $vprefix = defined $prefix ? ( length($prefix) ? $prefix : '""' ) : 'undef'; $tpp->set( attr_prefix => $prefix ); my $tree = $tpp->parse( $source ); is( $tree->{root}->{foo}->{$prefix.'bar'}, 'hoge', "parse: $vprefix" ); my $back = $tpp->write( $tree ); $back =~ s/\s+//sg; $back =~ s/<\?.*?\?>//s; is( $test, $back, "write: $vprefix" ); } $tpp->set( "attr_prefix" ); # remove attr_prefix my $tree2 = $tpp->parse( $source ); is( $tree2->{root}->{foo}->{'-bar'}, 'hoge', "parse: default (again)" ); # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/13_encoding_en.t0000755000175100017510000000236210737406415015670 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 15; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $FILES = [qw( t/example/hello-en-utf8.xml t/example/hello-en-nodecl.xml t/example/hello-en-noenc.xml t/example/hello-en-latin1.xml t/example/hello-en-utf8-bom.xml t/example/hello-en-nodecl-bom.xml t/example/hello-en-noenc-bom.xml )]; &test_main(); # ---------------------------------------------------------------- sub test_main { my $tpp = XML::TreePP->new(); my $prev; foreach my $file ( @$FILES ) { my $tree = $tpp->parsefile( $file ); if ( defined $prev ) { is( $tree->{root}->{text}, $prev, "same ".$file ); } else { like( $tree->{root}->{text}, qr/^Hello, World\!\s\S{4}/, "first ".$file ); $prev = $tree->{root}->{text}; } my $xml = $tpp->write( $tree ); like( $xml, qr/^\s*<\?xml[^<>]+encoding="UTF-8"/is, "write encoding" ); } } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/33_indent.t0000755000175100017510000000624210652637315014705 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- { plan tests => 73; use_ok('XML::TreePP'); &test_indent( undef ); &test_indent( 1 ); &test_indent( 4 ); } # ---------------------------------------------------------------- sub test_indent { my $indent = shift; my $order = [qw( one two three four five six seven eight nine )]; my $tpp = XML::TreePP->new( first_out => $order, indent => $indent ); my $nine = '9'; my $tree = { root => { one => '1', two => { '#text' => '2', three => undef, }, four => [{ five => '5', six => { '#text' => '6', }, }, { seven => { '#text' => '7', -eight => '8', }, }], nine => \$nine, }, }; my $xml = $tpp->write( $tree ); my $space = $indent ? '\040' x $indent : ''; $indent ||= 0; like( $xml, qr{ 1 }x, "[$indent] text node" ); like( $xml, qr{ 2 }x, "[$indent] text node after empty node" ); like( $xml, qr{ 6 }x, "[$indent] explicit text node" ); like( $xml, qr{ >7 }x, "[$indent] text node after attribute" ); like( $xml, qr{ }x, "[$indent] cdata node" ); like( $xml, qr{ ^ }mx, "[$indent] no-indent root" ); like( $xml, qr{ ^$space }mx, "[$indent] indent one" ); like( $xml, qr{ ^$space }mx, "[$indent] indent two" ); like( $xml, qr{ ^$space }mx, "[$indent] indent four" ); like( $xml, qr{ ^$space }mx, "[$indent] indent four end" ); like( $xml, qr{ ^$space$space }mx, "[$indent] indent five" ); like( $xml, qr{ ^$space$space }mx, "[$indent] indent six" ); like( $xml, qr{ ^$space$space }mx, "[$indent] indent nine" ); like( $xml, qr{ ^ }mx, "[$indent] no-indent root end" ); like( $xml, qr{ \n }x, "[$indent] line root" ); like( $xml, qr{ \n }x, "[$indent] line one" ); like( $xml, qr{ \n }x, "[$indent] line two" ); like( $xml, qr{ \n }x, "[$indent] line five" ); like( $xml, qr{ \n }x, "[$indent] line six" ); like( $xml, qr{ \n }x, "[$indent] line four" ); like( $xml, qr{ \n }x, "[$indent] line nine" ); like( $xml, qr{ \n }x, "[$indent] line root" ); } # ---------------------------------------------------------------- =example 1 2 5 6 7 =cut # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/06_cdata.t0000755000175100017510000000453110435104454014467 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 13; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- { my $cdatal = '
bar'; my $cdatar = ']]>
'; my $tpp = XML::TreePP->new(); my $xml1 = join( "", $cdatal, $test, $cdatar ); $tpp->set( cdata_scalar_ref => 1 ); my $tree1 = $tpp->parse( $xml1 ); my $cdata1 = $tree1->{cdata}; ok( ref $cdata1, "cdata as reference" ); is( $$cdata1, $test, "cdata escaping" ); my $xml2 = $tpp->write( $tree1 ); ok( $xml2 =~ /\Q$cdatal$test$cdatar\E/, "round trip: source" ); $tpp->set( cdata_scalar_ref => undef ); my $tree2 = $tpp->parse( $xml2 ); my $cdata2 = $tree2->{cdata}; ok( ! ref $cdata2, "round trip: cdata as scalar" ); is( $cdata2, $test, "round trip: text node escaping" ); $tree2->{cdata} = \$cdata2; my $xml3 = $tpp->write( $tree2 ); ok( $xml2 =~ /\Q$cdatal$test$cdatar\E/, "round trip: again" ); } # ---------------------------------------------------------------- { my $root1 = ''; my $root2 = ''; my $cdatal = '
bar'; my $cdatar = ']]>'; my $root3 = '
'; my $tpp = XML::TreePP->new(); my $xml1 = join( '', $root1, $root2, $cdatal, $test, $cdatar, $root3 ); $tpp->set( cdata_scalar_ref => 1 ); my $tree1 = $tpp->parse( $xml1 ); my $cdata1 = $tree1->{cdata}{'#text'}; ok( ref $cdata1, 'cdata as reference B' ); is( $$cdata1, $test, 'cdata escaping B' ); my $xml2 = $tpp->write( $tree1 ); ok( $xml2 =~ /\Q$cdatal$test$cdatar\E/, 'round trip: source B' ); $tpp->set( cdata_scalar_ref => undef ); my $tree2 = $tpp->parse( $xml2 ); my $cdata2 = $tree2->{cdata}{'#text'}; ok( ! ref $cdata2, 'round trip: cdata as scalar B' ); is( $cdata2, $test, 'round trip: text node escaping B' ); $tree2->{cdata} = \$cdata2; my $xml3 = $tpp->write( $tree2 ); ok( $xml2 =~ /\Q$cdatal$test$cdatar\E/, 'round trip: again B' ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/10_http-lwp.t0000755000175100017510000000317610467560301015173 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More; # ---------------------------------------------------------------- SKIP: { local $@; eval { require LWP::UserAgent; } unless defined $LWP::UserAgent::VERSION; if ( ! defined $LWP::UserAgent::VERSION ) { plan skip_all => 'LWP::UserAgent is not loaded.'; } if ( ! defined $ENV{MORE_TESTS} ) { plan skip_all => 'define $MORE_TESTS to test LWP::UserAgent.'; } plan tests => 5; use_ok('XML::TreePP'); &parsehttp_get(); &parsehttp_post(); } # ---------------------------------------------------------------- sub parsehttp_get { my $tpp = XML::TreePP->new(); my $name = ( $0 =~ m#([^/:\\]+)$# )[0]; $tpp->set( user_agent => "$name " ); my $url = "http://use.perl.org/index.rss"; my $tree = $tpp->parsehttp( GET => $url ); ok( ref $tree, $url ); like( $tree->{"rdf:RDF"}->{channel}->{link}, qr{^http://}, "$url link" ); } # ---------------------------------------------------------------- sub parsehttp_post { my $tpp = XML::TreePP->new( force_array => [qw( item )] ); my $name = ( $0 =~ m#([^/:\\]+)$# )[0]; $tpp->set( user_agent => "$name " ); my $url = "http://search.hatena.ne.jp/keyword"; my $query = "ajax"; my $body = "mode=rss2&word=".$query; my $tree = $tpp->parsehttp( POST => $url, $body ); ok( ref $tree, $url ); like( $tree->{rss}->{channel}->{item}->[0]->{link}, qr{^http://}, "$url link" ); } # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/t/01_parse.t0000755000175100017510000000140511101003240014473 0ustar u-sukeu-suke# ---------------------------------------------------------------- use strict; use Test::More tests => 4; BEGIN { use_ok('XML::TreePP') }; # ---------------------------------------------------------------- my $tpp = XML::TreePP->new(); my $source = 'BBB'; my $tree = $tpp->parse( $source ); is( $tree->{root}->{"#text"}, "BBB", "text node" ); is( $tree->{root}->{"-attr"}, "AAA", "attributes" ); my $back = $tpp->write( $tree ); my $test = $source; $back =~ s/\s+//sg; $back =~ s/<\?.*?\?>//s; $test =~ s/\s+//sg; is( $back, $test, "parse and write" ); # ---------------------------------------------------------------- ;1; # ---------------------------------------------------------------- XML-TreePP-0.39/make-dist.sh0000755000175100017510000000240211222012662014655 0ustar u-sukeu-suke#!/bin/sh die () { echo "$*" >&2 exit 1 } doit () { echo "\$ $*" >&2 $* || die "[ERROR:$?]" } rdf=t/example/index.rdf doit wget -O $rdf~ http://www.kawa.net/rss/index-e.rdf diff $rdf $rdf~ > /dev/null || doit /bin/mv -f $rdf~ $rdf /bin/rm -f $rdf~ [ -f Makefile ] && doit make clean [ -f META.yml ] || doit touch META.yml egrep -v '^(lib/.*\.pm|t/.*\.t)$' MANIFEST > MANIFEST~ ls Makefile.PL README Changes MANIFEST META.yml COPYING >> MANIFEST~ 2> /dev/null find lib -type f -name '*.pm' >> MANIFEST~ ls t/*.t >> MANIFEST~ sort MANIFEST~ | uniq > MANIFEST~~ /bin/mv -f MANIFEST~~ MANIFEST~ diff MANIFEST MANIFEST~ > /dev/null || doit /bin/mv -f MANIFEST~ MANIFEST /bin/rm -f MANIFEST~ doit perl Makefile.PL doit make metafile newmeta=`ls -t */META.yml | head -1` diff META.yml $newmeta > /dev/null || doit /bin/cp -f $newmeta META.yml doit make disttest main=`grep 'lib/.*pm$' < MANIFEST | head -1` [ "$main" == "" ] && die "main module is not found in MANIFEST" doit pod2text $main > README~ diff README README~ > /dev/null || doit /bin/mv -f README~ README /bin/rm -f README~ doit make dist [ -d blib ] && doit /bin/rm -fr blib [ -f pm_to_blib ] && doit /bin/rm -f pm_to_blib [ -f Makefile.old ] && doit /bin/rm -f Makefile.old ls -lt *.tar.gz | head -1 XML-TreePP-0.39/lib/0000755000175100017510000000000011222330343013207 5ustar u-sukeu-sukeXML-TreePP-0.39/lib/XML/0000755000175100017510000000000011222330343013647 5ustar u-sukeu-sukeXML-TreePP-0.39/lib/XML/TreePP.pm0000755000175100017510000011441211222330303015346 0ustar u-sukeu-suke=head1 NAME XML::TreePP -- Pure Perl implementation for parsing/writing XML documents =head1 SYNOPSIS parse an XML document from file into hash tree: use XML::TreePP; my $tpp = XML::TreePP->new(); my $tree = $tpp->parsefile( "index.rdf" ); print "Title: ", $tree->{"rdf:RDF"}->{item}->[0]->{title}, "\n"; print "URL: ", $tree->{"rdf:RDF"}->{item}->[0]->{link}, "\n"; write an XML document as string from hash tree: use XML::TreePP; my $tpp = XML::TreePP->new(); my $tree = { rss => { channel => { item => [ { title => "The Perl Directory", link => "http://www.perl.org/", }, { title => "The Comprehensive Perl Archive Network", link => "http://cpan.perl.org/", } ] } } }; my $xml = $tpp->write( $tree ); print $xml; get a remote XML document by HTTP-GET and parse it into hash tree: use XML::TreePP; my $tpp = XML::TreePP->new(); my $tree = $tpp->parsehttp( GET => "http://use.perl.org/index.rss" ); print "Title: ", $tree->{"rdf:RDF"}->{channel}->{title}, "\n"; print "URL: ", $tree->{"rdf:RDF"}->{channel}->{link}, "\n"; get a remote XML document by HTTP-POST and parse it into hash tree: use XML::TreePP; my $tpp = XML::TreePP->new( force_array => [qw( item )] ); my $cgiurl = "http://search.hatena.ne.jp/keyword"; my $keyword = "ajax"; my $cgiquery = "mode=rss2&word=".$keyword; my $tree = $tpp->parsehttp( POST => $cgiurl, $cgiquery ); print "Link: ", $tree->{rss}->{channel}->{item}->[0]->{link}, "\n"; print "Desc: ", $tree->{rss}->{channel}->{item}->[0]->{description}, "\n"; =head1 DESCRIPTION XML::TreePP module parses an XML document and expands it for a hash tree. This generates an XML document from a hash tree as the opposite way around. This is a pure Perl implementation and requires no modules depended. This can also fetch and parse an XML document from remote web server like the XMLHttpRequest object does at JavaScript language. =head1 EXAMPLES =head2 Parse XML file Sample XML document: Yasuhisa Chizuko Shiori Yusuke Kairi Sample program to read a xml file and dump it: use XML::TreePP; use Data::Dumper; my $tpp = XML::TreePP->new(); my $tree = $tpp->parsefile( "family.xml" ); my $text = Dumper( $tree ); print $text; Result dumped: $VAR1 = { 'family' => { '-name' => 'Kawasaki', 'father' => 'Yasuhisa', 'mother' => 'Chizuko', 'children' => { 'girl' => 'Shiori' 'boy' => [ 'Yusuke', 'Kairi' ], } } }; Details: print $tree->{family}->{father}; # the father's given name. The prefix '-' is added on every attribute's name. print $tree->{family}->{"-name"}; # the family name of the family The array is used because the family has two boys. print $tree->{family}->{children}->{boy}->[1]; # The second boy's name print $tree->{family}->{children}->{girl}; # The girl's name =head2 Text node and attributes: If a element has both of a text node and attributes or both of a text node and other child nodes, value of a text node is moved to C<#text> like child nodes. use XML::TreePP; use Data::Dumper; my $tpp = XML::TreePP->new(); my $source = 'Kawasaki Yusuke'; my $tree = $tpp->parse( $source ); my $text = Dumper( $tree ); print $text; The result dumped is following: $VAR1 = { 'span' => { '-class' => 'author', '#text' => 'Kawasaki Yusuke' } }; The special node name of C<#text> is used because this elements has attribute(s) in addition to the text node. See also L option. =head1 METHODS =head2 new This constructor method returns a new XML::TreePP object with C<%options>. $tpp = XML::TreePP->new( %options ); =head2 set This method sets a option value for C. If C<$option_value> is not defined, its option is deleted. $tpp->set( option_name => $option_value ); See OPTIONS section below for details. =head2 get This method returns a current option value for C. $tpp->get( 'option_name' ); =head2 parse This method reads an XML document by string and returns a hash tree converted. The first argument is a scalar or a reference to a scalar. $tree = $tpp->parse( $source ); =head2 parsefile This method reads an XML document by file and returns a hash tree converted. The first argument is a filename. $tree = $tpp->parsefile( $file ); =head2 parsehttp This method receives an XML document from a remote server via HTTP and returns a hash tree converted. $tree = $tpp->parsehttp( $method, $url, $body, $head ); C<$method> is a method of HTTP connection: GET/POST/PUT/DELETE C<$url> is an URI of an XML file. C<$body> is a request body when you use POST method. C<$head> is a request headers as a hash ref. L module or L module is required to fetch a file. ( $tree, $xml, $code ) = $tpp->parsehttp( $method, $url, $body, $head ); In array context, This method returns also raw XML document received and HTTP response's status code. =head2 write This method parses a hash tree and returns an XML document as a string. $source = $tpp->write( $tree, $encode ); C<$tree> is a reference to a hash tree. =head2 writefile This method parses a hash tree and writes an XML document into a file. $tpp->writefile( $file, $tree, $encode ); C<$file> is a filename to create. C<$tree> is a reference to a hash tree. =head1 OPTIONS FOR PARSING XML This module accepts option parameters following: =head2 force_array This option allows you to specify a list of element names which should always be forced into an array representation. $tpp->set( force_array => [ 'rdf:li', 'item', '-xmlns' ] ); The default value is null, it means that context of the elements will determine to make array or to keep it scalar or hash. Note that the special wildcard name C<'*'> means all elements. =head2 force_hash This option allows you to specify a list of element names which should always be forced into an hash representation. $tpp->set( force_hash => [ 'item', 'image' ] ); The default value is null, it means that context of the elements will determine to make hash or to keep it scalar as a text node. See also L option below. Note that the special wildcard name C<'*'> means all elements. =head2 cdata_scalar_ref This option allows you to convert a cdata section into a reference for scalar on parsing an XML document. $tpp->set( cdata_scalar_ref => 1 ); The default value is false, it means that each cdata section is converted into a scalar. =head2 user_agent This option allows you to specify a HTTP_USER_AGENT string which is used by parsehttp() method. $tpp->set( user_agent => 'Mozilla/4.0 (compatible; ...)' ); The default string is C<'XML-TreePP/#.##'>, where C<'#.##'> is substituted with the version number of this library. =head2 http_lite This option forces pasrsehttp() method to use a L instance. my $http = HTTP::Lite->new(); $tpp->set( http_lite => $http ); =head2 lwp_useragent This option forces pasrsehttp() method to use a L instance. my $ua = LWP::UserAgent->new(); $ua->timeout( 60 ); $ua->env_proxy; $tpp->set( lwp_useragent => $ua ); You may use this with L. =head2 base_class This blesses class name for each element's hashref. Each class is named straight as a child class of it parent class. $tpp->set( base_class => 'MyElement' ); my $xml = 'text'; my $tree = $tpp->parse( $xml ); print ref $tree->{root}->{parent}->{child}, "\n"; A hash for element above is blessed to C class. You may use this with L. =head2 elem_class This blesses class name for each element's hashref. Each class is named horizontally under the direct child of C. $tpp->set( base_class => 'MyElement' ); my $xml = 'text'; my $tree = $tpp->parse( $xml ); print ref $tree->{root}->{parent}->{child}, "\n"; A hash for element above is blessed to C class. =head2 xml_deref This option dereferences the numeric character references, like ë, 漢, etc., in an XML document when this value is true. $tpp->set( xml_deref => 1 ); Note that, for security reasons and your convenient, this module dereferences the predefined character entity references, &, <, >, ' and ", and the numeric character references up to U+007F without xml_deref per default. =head1 OPTIONS FOR WRITING XML =head2 first_out This option allows you to specify a list of element/attribute names which should always appears at first on output XML document. $tpp->set( first_out => [ 'link', 'title', '-type' ] ); The default value is null, it means alphabetical order is used. =head2 last_out This option allows you to specify a list of element/attribute names which should always appears at last on output XML document. $tpp->set( last_out => [ 'items', 'item', 'entry' ] ); =head2 indent This makes the output more human readable by indenting appropriately. $tpp->set( indent => 2 ); This doesn't strictly follow the XML specification but does looks nice. =head2 xml_decl This module inserts an XML declaration on top of the XML document generated per default. This option forces to change it to another or just remove it. $tpp->set( xml_decl => '' ); =head2 output_encoding This option allows you to specify a encoding of the XML document generated by write/writefile methods. $tpp->set( output_encoding => 'UTF-8' ); On Perl 5.8.0 and later, you can select it from every encodings supported by Encode.pm. On Perl 5.6.x and before with Jcode.pm, you can use C, C, C and C. The default value is C which is recommended encoding. =head1 OPTIONS FOR BOTH =head2 utf8_flag This makes utf8 flag on for every element's value parsed and makes it on for the XML document generated as well. $tpp->set( utf8_flag => 1 ); Perl 5.8.1 or later is required to use this. =head2 attr_prefix This option allows you to specify a prefix character(s) which is inserted before each attribute names. $tpp->set( attr_prefix => '@' ); The default character is C<'-'>. Or set C<'@'> to access attribute values like E4X, ECMAScript for XML. Zero-length prefix C<''> is available as well, it means no prefix is added. =head2 text_node_key This option allows you to specify a hash key for text nodes. $tpp->set( text_node_key => '#text' ); The default key is C<#text>. =head2 ignore_error This module calls Carp::croak function on an error per default. This option makes all errors ignored and just returns. $tpp->set( ignore_error => 1 ); =head2 use_ixhash This option keeps the order for each element appeared in XML. L module is required. $tpp->set( use_ixhash => 1 ); This makes parsing performance slow. (about 100% slower than default) =head1 AUTHOR Yusuke Kawasaki, http://www.kawa.net/ =head1 COPYRIGHT AND LICENSE Copyright (c) 2006-2009 Yusuke Kawasaki. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut package XML::TreePP; use strict; use Carp; use Symbol; use vars qw( $VERSION ); $VERSION = '0.39'; my $XML_ENCODING = 'UTF-8'; my $INTERNAL_ENCODING = 'UTF-8'; my $USER_AGENT = 'XML-TreePP/'.$VERSION.' '; my $ATTR_PREFIX = '-'; my $TEXT_NODE_KEY = '#text'; my $USE_ENCODE_PM = ( $] >= 5.008 ); my $ALLOW_UTF8_FLAG = ( $] >= 5.008001 ); sub new { my $package = shift; my $self = {@_}; bless $self, $package; $self; } sub die { my $self = shift; my $mess = shift; return if $self->{ignore_error}; Carp::croak $mess; } sub warn { my $self = shift; my $mess = shift; return if $self->{ignore_error}; Carp::carp $mess; } sub set { my $self = shift; my $key = shift; my $val = shift; if ( defined $val ) { $self->{$key} = $val; } else { delete $self->{$key}; } } sub get { my $self = shift; my $key = shift; $self->{$key} if exists $self->{$key}; } sub writefile { my $self = shift; my $file = shift; my $tree = shift or return $self->die( 'Invalid tree' ); my $encode = shift; return $self->die( 'Invalid filename' ) unless defined $file; my $text = $self->write( $tree, $encode ); if ( $ALLOW_UTF8_FLAG && utf8::is_utf8( $text ) ) { utf8::encode( $text ); } $self->write_raw_xml( $file, $text ); } sub write { my $self = shift; my $tree = shift or return $self->die( 'Invalid tree' ); my $from = $self->{internal_encoding} || $INTERNAL_ENCODING; my $to = shift || $self->{output_encoding} || $XML_ENCODING; my $decl = $self->{xml_decl}; $decl = '' unless defined $decl; local $self->{__first_out}; if ( exists $self->{first_out} ) { my $keys = $self->{first_out}; $keys = [$keys] unless ref $keys; $self->{__first_out} = { map { $keys->[$_] => $_ } 0 .. $#$keys }; } local $self->{__last_out}; if ( exists $self->{last_out} ) { my $keys = $self->{last_out}; $keys = [$keys] unless ref $keys; $self->{__last_out} = { map { $keys->[$_] => $_ } 0 .. $#$keys }; } my $tnk = $self->{text_node_key} if exists $self->{text_node_key}; $tnk = $TEXT_NODE_KEY unless defined $tnk; local $self->{text_node_key} = $tnk; my $apre = $self->{attr_prefix} if exists $self->{attr_prefix}; $apre = $ATTR_PREFIX unless defined $apre; local $self->{__attr_prefix_len} = length($apre); # local $self->{__attr_prefix_rex} = defined $apre ? qr/^\Q$apre\E/s : undef; local $self->{__attr_prefix_rex} = $apre; local $self->{__indent}; if ( exists $self->{indent} && $self->{indent} ) { $self->{__indent} = ' ' x $self->{indent}; } if ( ! UNIVERSAL::isa( $tree, 'HASH' )) { return $self->die( 'Invalid tree' ); } my $text = $self->hash_to_xml( undef, $tree ); if ( $from && $to ) { my $stat = $self->encode_from_to( \$text, $from, $to ); return $self->die( "Unsupported encoding: $to" ) unless $stat; } return $text if ( $decl eq '' ); join( "\n", $decl, $text ); } sub parsehttp { my $self = shift; local $self->{__user_agent}; if ( exists $self->{user_agent} ) { my $agent = $self->{user_agent}; $agent .= $USER_AGENT if ( $agent =~ /\s$/s ); $self->{__user_agent} = $agent if ( $agent ne '' ); } else { $self->{__user_agent} = $USER_AGENT; } my $http = $self->{__http_module}; unless ( $http ) { $http = $self->find_http_module(@_); $self->{__http_module} = $http; } if ( $http eq 'LWP::UserAgent' ) { return $self->parsehttp_lwp(@_); } elsif ( $http eq 'HTTP::Lite' ) { return $self->parsehttp_lite(@_); } else { return $self->die( "LWP::UserAgent or HTTP::Lite is required: $_[1]" ); } } sub find_http_module { my $self = shift || {}; if ( exists $self->{lwp_useragent} && ref $self->{lwp_useragent} ) { return 'LWP::UserAgent' if defined $LWP::UserAgent::VERSION; return 'LWP::UserAgent' if &load_lwp_useragent(); return $self->die( "LWP::UserAgent is required: $_[1]" ); } if ( exists $self->{http_lite} && ref $self->{http_lite} ) { return 'HTTP::Lite' if defined $HTTP::Lite::VERSION; return 'HTTP::Lite' if &load_http_lite(); return $self->die( "HTTP::Lite is required: $_[1]" ); } return 'LWP::UserAgent' if defined $LWP::UserAgent::VERSION; return 'HTTP::Lite' if defined $HTTP::Lite::VERSION; return 'LWP::UserAgent' if &load_lwp_useragent(); return 'HTTP::Lite' if &load_http_lite(); return $self->die( "LWP::UserAgent or HTTP::Lite is required: $_[1]" ); } sub load_lwp_useragent { return $LWP::UserAgent::VERSION if defined $LWP::UserAgent::VERSION; local $@; eval { require LWP::UserAgent; }; $LWP::UserAgent::VERSION; } sub load_http_lite { return $HTTP::Lite::VERSION if defined $HTTP::Lite::VERSION; local $@; eval { require HTTP::Lite; }; $HTTP::Lite::VERSION; } sub load_tie_ixhash { return $Tie::IxHash::VERSION if defined $Tie::IxHash::VERSION; local $@; eval { require Tie::IxHash; }; $Tie::IxHash::VERSION; } sub parsehttp_lwp { my $self = shift; my $method = shift or return $self->die( 'Invalid HTTP method' ); my $url = shift or return $self->die( 'Invalid URL' ); my $body = shift; my $header = shift; my $ua = $self->{lwp_useragent} if exists $self->{lwp_useragent}; if ( ! ref $ua ) { $ua = LWP::UserAgent->new(); $ua->timeout(10); $ua->env_proxy(); $ua->agent( $self->{__user_agent} ) if defined $self->{__user_agent}; } else { $ua->agent( $self->{__user_agent} ) if exists $self->{user_agent}; } my $req = HTTP::Request->new( $method, $url ); my $ct = 0; if ( ref $header ) { foreach my $field ( sort keys %$header ) { my $value = $header->{$field}; $req->header( $field => $value ); $ct ++ if ( $field =~ /^Content-Type$/i ); } } if ( defined $body && ! $ct ) { $req->header( 'Content-Type' => 'application/x-www-form-urlencoded' ); } $req->content($body) if defined $body; my $res = $ua->request($req); my $code = $res->code(); my $text; if ( $res->can( 'decoded_content' )) { $text = $res->decoded_content( charset => 'none' ); } else { $text = $res->content(); # less than LWP 5.802 } my $tree = $self->parse( \$text ) if $res->is_success(); wantarray ? ( $tree, $text, $code ) : $tree; } sub parsehttp_lite { my $self = shift; my $method = shift or return $self->die( 'Invalid HTTP method' ); my $url = shift or return $self->die( 'Invalid URL' ); my $body = shift; my $header = shift; my $http = HTTP::Lite->new(); $http->method($method); my $ua = 0; if ( ref $header ) { foreach my $field ( sort keys %$header ) { my $value = $header->{$field}; $http->add_req_header( $field, $value ); $ua ++ if ( $field =~ /^User-Agent$/i ); } } if ( defined $self->{__user_agent} && ! $ua ) { $http->add_req_header( 'User-Agent', $self->{__user_agent} ); } $http->{content} = $body if defined $body; my $code = $http->request($url) or return; my $text = $http->body(); my $tree = $self->parse( \$text ); wantarray ? ( $tree, $text, $code ) : $tree; } sub parsefile { my $self = shift; my $file = shift; return $self->die( 'Invalid filename' ) unless defined $file; my $text = $self->read_raw_xml($file); $self->parse( \$text ); } sub parse { my $self = shift; my $text = ref $_[0] ? ${$_[0]} : $_[0]; return $self->die( 'Null XML source' ) unless defined $text; my $from = &xml_decl_encoding(\$text) || $XML_ENCODING; my $to = $self->{internal_encoding} || $INTERNAL_ENCODING; if ( $from && $to ) { my $stat = $self->encode_from_to( \$text, $from, $to ); return $self->die( "Unsupported encoding: $from" ) unless $stat; } local $self->{__force_array}; local $self->{__force_array_all}; if ( exists $self->{force_array} ) { my $force = $self->{force_array}; $force = [$force] unless ref $force; $self->{__force_array} = { map { $_ => 1 } @$force }; $self->{__force_array_all} = $self->{__force_array}->{'*'}; } local $self->{__force_hash}; local $self->{__force_hash_all}; if ( exists $self->{force_hash} ) { my $force = $self->{force_hash}; $force = [$force] unless ref $force; $self->{__force_hash} = { map { $_ => 1 } @$force }; $self->{__force_hash_all} = $self->{__force_hash}->{'*'}; } my $tnk = $self->{text_node_key} if exists $self->{text_node_key}; $tnk = $TEXT_NODE_KEY unless defined $tnk; local $self->{text_node_key} = $tnk; my $apre = $self->{attr_prefix} if exists $self->{attr_prefix}; $apre = $ATTR_PREFIX unless defined $apre; local $self->{attr_prefix} = $apre; if ( exists $self->{use_ixhash} && $self->{use_ixhash} ) { return $self->die( "Tie::IxHash is required." ) unless &load_tie_ixhash(); } my $flat = $self->xml_to_flat(\$text); my $class = $self->{base_class} if exists $self->{base_class}; my $tree = $self->flat_to_tree( $flat, '', $class ); if ( ref $tree ) { if ( defined $class ) { bless( $tree, $class ); } elsif ( exists $self->{elem_class} && $self->{elem_class} ) { bless( $tree, $self->{elem_class} ); } } wantarray ? ( $tree, $text ) : $tree; } sub xml_to_flat { my $self = shift; my $textref = shift; # reference my $flat = []; my $prefix = $self->{attr_prefix}; my $ixhash = ( exists $self->{use_ixhash} && $self->{use_ixhash} ); my $deref = \&xml_unescape; my $xml_deref = ( exists $self->{xml_deref} && $self->{xml_deref} ); if ( $xml_deref ) { if (( exists $self->{utf8_flag} && $self->{utf8_flag} ) || ( $ALLOW_UTF8_FLAG && utf8::is_utf8( $$textref ))) { $deref = \&xml_deref_string; } else { $deref = \&xml_deref_octet; } } while ( $$textref =~ m{ ([^<]*) < (( \? ([^<>]*) \? )|( \!\[CDATA\[(.*?)\]\] )|( \!DOCTYPE\s+([^\[\]<>]*(?:\[.*?\]\s*)?) )|( \!--(.*?)-- )|( ([^\!\?\s<>](?:"[^"]*"|'[^']*'|[^"'<>])*) )) > ([^<]*) }sxg ) { my ( $ahead, $match, $typePI, $contPI, $typeCDATA, $contCDATA, $typeDocT, $contDocT, $typeCmnt, $contCmnt, $typeElem, $contElem, $follow ) = ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13 ); if ( defined $ahead && $ahead =~ /\S/ ) { $ahead =~ s/([^\040-\076])/sprintf("\\x%02X",ord($1))/eg; $self->warn( "Invalid string: [$ahead] before <$match>" ); } if ($typeElem) { # Element my $node = {}; if ( $contElem =~ s#^/## ) { $node->{endTag}++; } elsif ( $contElem =~ s#/$## ) { $node->{emptyTag}++; } else { $node->{startTag}++; } $node->{tagName} = $1 if ( $contElem =~ s#^(\S+)\s*## ); unless ( $node->{endTag} ) { my $attr; while ( $contElem =~ m{ ([^\s\=\"\']+)\s*=\s*(?:(")(.*?)"|'(.*?)') }sxg ) { my $key = $1; my $val = &$deref( $2 ? $3 : $4 ); if ( ! ref $attr ) { $attr = {}; tie( %$attr, 'Tie::IxHash' ) if $ixhash; } $attr->{$prefix.$key} = $val; } $node->{attributes} = $attr if ref $attr; } push( @$flat, $node ); } elsif ($typeCDATA) { ## CDATASection if ( exists $self->{cdata_scalar_ref} && $self->{cdata_scalar_ref} ) { push( @$flat, \$contCDATA ); # as reference for scalar } else { push( @$flat, $contCDATA ); # as scalar like text node } } elsif ($typeCmnt) { # Comment (ignore) } elsif ($typeDocT) { # DocumentType (ignore) } elsif ($typePI) { # ProcessingInstruction (ignore) } else { $self->warn( "Invalid Tag: <$match>" ); } if ( $follow =~ /\S/ ) { # text node my $val = &$deref($follow); push( @$flat, $val ); } } $flat; } sub flat_to_tree { my $self = shift; my $source = shift; my $parent = shift; my $class = shift; my $tree = {}; my $text = []; if ( exists $self->{use_ixhash} && $self->{use_ixhash} ) { tie( %$tree, 'Tie::IxHash' ); } while ( scalar @$source ) { my $node = shift @$source; if ( !ref $node || UNIVERSAL::isa( $node, "SCALAR" ) ) { push( @$text, $node ); # cdata or text node next; } my $name = $node->{tagName}; if ( $node->{endTag} ) { last if ( $parent eq $name ); return $self->die( "Invalid tag sequence: <$parent>" ); } my $elem = $node->{attributes}; my $forcehash = $self->{__force_hash_all} || $self->{__force_hash}->{$name}; my $subclass; if ( defined $class ) { my $escname = $name; $escname =~ s/\W/_/sg; $subclass = $class.'::'.$escname; } if ( $node->{startTag} ) { # recursive call my $child = $self->flat_to_tree( $source, $name, $subclass ); next unless defined $child; my $hasattr = scalar keys %$elem if ref $elem; if ( UNIVERSAL::isa( $child, "HASH" ) ) { if ( $hasattr ) { # some attributes and some child nodes %$elem = ( %$elem, %$child ); } else { # some child nodes without attributes $elem = $child; } } else { if ( $hasattr ) { # some attributes and text node $elem->{$self->{text_node_key}} = $child; } elsif ( $forcehash ) { # only text node without attributes $elem = { $self->{text_node_key} => $child }; } else { # text node without attributes $elem = $child; } } } elsif ( $forcehash && ! ref $elem ) { $elem = {}; } # bless to a class by base_class or elem_class if ( ref $elem && UNIVERSAL::isa( $elem, "HASH" ) ) { if ( defined $subclass ) { bless( $elem, $subclass ); } elsif ( exists $self->{elem_class} && $self->{elem_class} ) { my $escname = $name; $escname =~ s/\W/_/sg; my $elmclass = $self->{elem_class}.'::'.$escname; bless( $elem, $elmclass ); } } # next unless defined $elem; $tree->{$name} ||= []; push( @{ $tree->{$name} }, $elem ); } if ( ! $self->{__force_array_all} ) { foreach my $key ( keys %$tree ) { next if $self->{__force_array}->{$key}; next if ( 1 < scalar @{ $tree->{$key} } ); $tree->{$key} = shift @{ $tree->{$key} }; } } my $haschild = scalar keys %$tree; if ( scalar @$text ) { if ( scalar @$text == 1 ) { # one text node (normal) $text = shift @$text; } elsif ( ! scalar grep {ref $_} @$text ) { # some text node splitted $text = join( '', @$text ); } else { # some cdata node my $join = join( '', map {ref $_ ? $$_ : $_} @$text ); $text = \$join; } if ( $haschild ) { # some child nodes and also text node $tree->{$self->{text_node_key}} = $text; } else { # only text node without child nodes $tree = $text; } } elsif ( ! $haschild ) { # no child and no text $tree = ""; } $tree; } sub hash_to_xml { my $self = shift; my $name = shift; my $hash = shift; my $out = []; my $attr = []; my $allkeys = [ keys %$hash ]; my $fo = $self->{__first_out} if ref $self->{__first_out}; my $lo = $self->{__last_out} if ref $self->{__last_out}; my $firstkeys = [ sort { $fo->{$a} <=> $fo->{$b} } grep { exists $fo->{$_} } @$allkeys ] if ref $fo; my $lastkeys = [ sort { $lo->{$a} <=> $lo->{$b} } grep { exists $lo->{$_} } @$allkeys ] if ref $lo; $allkeys = [ grep { ! exists $fo->{$_} } @$allkeys ] if ref $fo; $allkeys = [ grep { ! exists $lo->{$_} } @$allkeys ] if ref $lo; unless ( exists $self->{use_ixhash} && $self->{use_ixhash} ) { $allkeys = [ sort @$allkeys ]; } my $prelen = $self->{__attr_prefix_len}; my $pregex = $self->{__attr_prefix_rex}; foreach my $keys ( $firstkeys, $allkeys, $lastkeys ) { next unless ref $keys; my $elemkey = $prelen ? [ grep { substr($_,0,$prelen) ne $pregex } @$keys ] : $keys; my $attrkey = $prelen ? [ grep { substr($_,0,$prelen) eq $pregex } @$keys ] : []; foreach my $key ( @$elemkey ) { my $val = $hash->{$key}; if ( !defined $val ) { push( @$out, "<$key />" ); } elsif ( UNIVERSAL::isa( $val, 'HASH' ) ) { my $child = $self->hash_to_xml( $key, $val ); push( @$out, $child ); } elsif ( UNIVERSAL::isa( $val, 'ARRAY' ) ) { my $child = $self->array_to_xml( $key, $val ); push( @$out, $child ); } elsif ( UNIVERSAL::isa( $val, 'SCALAR' ) ) { my $child = $self->scalaref_to_cdata( $key, $val ); push( @$out, $child ); } else { my $ref = ref $val; $self->warn( "Unsupported reference type: $ref in $key" ) if $ref; my $child = $self->scalar_to_xml( $key, $val ); push( @$out, $child ); } } foreach my $key ( @$attrkey ) { my $name = substr( $key, $prelen ); my $val = &xml_escape( $hash->{$key} ); push( @$attr, ' ' . $name . '="' . $val . '"' ); } } my $jattr = join( '', @$attr ); if ( defined $name && scalar @$out && ! grep { ! /^{__indent} ) { s/^(\s*<)/$self->{__indent}$1/mg foreach @$out; } unshift( @$out, "\n" ); } my $text = join( '', @$out ); if ( defined $name ) { if ( scalar @$out ) { $text = "<$name$jattr>$text\n"; } else { $text = "<$name$jattr />\n"; } } $text; } sub array_to_xml { my $self = shift; my $name = shift; my $array = shift; my $out = []; foreach my $val (@$array) { if ( !defined $val ) { push( @$out, "<$name />\n" ); } elsif ( UNIVERSAL::isa( $val, 'HASH' ) ) { my $child = $self->hash_to_xml( $name, $val ); push( @$out, $child ); } elsif ( UNIVERSAL::isa( $val, 'ARRAY' ) ) { my $child = $self->array_to_xml( $name, $val ); push( @$out, $child ); } elsif ( UNIVERSAL::isa( $val, 'SCALAR' ) ) { my $child = $self->scalaref_to_cdata( $name, $val ); push( @$out, $child ); } else { my $ref = ref $val; $self->warn( "Unsupported reference type: $ref in $name" ) if $ref; my $child = $self->scalar_to_xml( $name, $val ); push( @$out, $child ); } } my $text = join( '', @$out ); $text; } sub scalaref_to_cdata { my $self = shift; my $name = shift; my $ref = shift; my $data = defined $$ref ? $$ref : ''; $data =~ s#(]])(>)#$1]]>'; $text = "<$name>$text\n" if ( $name ne $self->{text_node_key} ); $text; } sub scalar_to_xml { my $self = shift; my $name = shift; my $scalar = shift; my $copy = $scalar; my $text = &xml_escape($copy); $text = "<$name>$text\n" if ( $name ne $self->{text_node_key} ); $text; } sub write_raw_xml { my $self = shift; my $file = shift; my $fh = Symbol::gensym(); open( $fh, ">$file" ) or return $self->die( "$! - $file" ); print $fh @_; close($fh); } sub read_raw_xml { my $self = shift; my $file = shift; my $fh = Symbol::gensym(); open( $fh, $file ) or return $self->die( "$! - $file" ); local $/ = undef; my $text = <$fh>; close($fh); $text; } sub xml_decl_encoding { my $textref = shift; return unless defined $$textref; my $args = ( $$textref =~ /^(?:\s*\xEF\xBB\xBF)?\s*<\?xml(\s+\S.*)\?>/s )[0] or return; my $getcode = ( $args =~ /\s+encoding=(".*?"|'.*?')/ )[0] or return; $getcode =~ s/^['"]//; $getcode =~ s/['"]$//; $getcode; } sub encode_from_to { my $self = shift; my $txtref = shift or return; my $from = shift or return; my $to = shift or return; unless ( defined $Encode::EUCJPMS::VERSION ) { $from = 'EUC-JP' if ( $from =~ /\beuc-?jp-?(win|ms)$/i ); $to = 'EUC-JP' if ( $to =~ /\beuc-?jp-?(win|ms)$/i ); } my $RE_IS_UTF8 = qr/^utf-?8$/i; if ( $from =~ $RE_IS_UTF8 ) { $$txtref =~ s/^\xEF\xBB\xBF//s; # UTF-8 BOM (Byte Order Mark) } my $setflag = $self->{utf8_flag} if exists $self->{utf8_flag}; if ( ! $ALLOW_UTF8_FLAG && $setflag ) { return $self->die( "Perl 5.8.1 is required for utf8_flag: $]" ); } if ( $USE_ENCODE_PM ) { &load_encode(); my $encver = ( $Encode::VERSION =~ /^([\d\.]+)/ )[0]; my $check = ( $encver < 2.13 ) ? 0x400 : Encode::FB_XMLCREF(); my $encfrom = Encode::find_encoding($from) if $from; return $self->die( "Unknown encoding: $from" ) unless ref $encfrom; my $encto = Encode::find_encoding($to) if $to; return $self->die( "Unknown encoding: $to" ) unless ref $encto; if ( $ALLOW_UTF8_FLAG && utf8::is_utf8( $$txtref ) ) { if ( $to =~ $RE_IS_UTF8 ) { # skip } else { $$txtref = $encto->encode( $$txtref, $check ); } } else { $$txtref = $encfrom->decode( $$txtref ); if ( $to =~ $RE_IS_UTF8 && $setflag ) { # skip } else { $$txtref = $encto->encode( $$txtref, $check ); } } } elsif ( ( uc($from) eq 'ISO-8859-1' || uc($from) eq 'US-ASCII' || uc($from) eq 'LATIN-1' ) && uc($to) eq 'UTF-8' ) { &latin1_to_utf8($txtref); } else { my $jfrom = &get_jcode_name($from); my $jto = &get_jcode_name($to); return $to if ( uc($jfrom) eq uc($jto) ); if ( $jfrom && $jto ) { &load_jcode(); if ( defined $Jcode::VERSION ) { Jcode::convert( $txtref, $jto, $jfrom ); } else { return $self->die( "Jcode.pm is required: $from to $to" ); } } else { return $self->die( "Encode.pm is required: $from to $to" ); } } $to; } sub load_jcode { return if defined $Jcode::VERSION; local $@; eval { require Jcode; }; } sub load_encode { return if defined $Encode::VERSION; local $@; eval { require Encode; }; } sub latin1_to_utf8 { my $strref = shift; $$strref =~ s{ ([\x80-\xFF]) }{ pack( 'C2' => 0xC0|(ord($1)>>6),0x80|(ord($1)&0x3F) ) }exg; } sub get_jcode_name { my $src = shift; my $dst; if ( $src =~ /^utf-?8$/i ) { $dst = 'utf8'; } elsif ( $src =~ /^euc.*jp(-?(win|ms))?$/i ) { $dst = 'euc'; } elsif ( $src =~ /^(shift.*jis|cp932|windows-31j)$/i ) { $dst = 'sjis'; } elsif ( $src =~ /^iso-2022-jp/ ) { $dst = 'jis'; } $dst; } sub xml_escape { my $str = shift; return '' unless defined $str; # except for TAB(\x09),CR(\x0D),LF(\x0A) $str =~ s{ ([\x00-\x08\x0B\x0C\x0E-\x1F\x7F]) }{ sprintf( '&#%d;', ord($1) ); }gex; $str =~ s/&(?!#(\d+;|x[\dA-Fa-f]+;))/&/g; $str =~ s//>/g; $str =~ s/'/'/g; $str =~ s/"/"/g; $str; } sub xml_unescape { my $str = shift; my $map = {qw( quot " lt < gt > apos ' amp & )}; $str =~ s{ (&(?:\#(\d{1,3})|\#x([0-9a-fA-F]{1,2})|(quot|lt|gt|apos|amp));) }{ $4 ? $map->{$4} : &code_to_ascii( $3 ? hex($3) : $2, $1 ); }gex; $str; } sub xml_deref_octet { my $str = shift; my $map = {qw( quot " lt < gt > apos ' amp & )}; $str =~ s{ (&(?:\#(\d{1,7})|\#x([0-9a-fA-F]{1,6})|(quot|lt|gt|apos|amp));) }{ $4 ? $map->{$4} : &code_to_utf8( $3 ? hex($3) : $2, $1 ); }gex; $str; } sub xml_deref_string { my $str = shift; my $map = {qw( quot " lt < gt > apos ' amp & )}; $str =~ s{ (&(?:\#(\d{1,7})|\#x([0-9a-fA-F]{1,6})|(quot|lt|gt|apos|amp));) }{ $4 ? $map->{$4} : pack( U => $3 ? hex($3) : $2 ); }gex; $str; } sub code_to_ascii { my $code = shift; if ( $code <= 0x007F ) { return pack( C => $code ); } return shift if scalar @_; # default value sprintf( '&#%d;', $code ); } sub code_to_utf8 { my $code = shift; if ( $code <= 0x007F ) { return pack( C => $code ); } elsif ( $code <= 0x07FF ) { return pack( C2 => 0xC0|($code>>6), 0x80|($code&0x3F)); } elsif ( $code <= 0xFFFF ) { return pack( C3 => 0xE0|($code>>12), 0x80|(($code>>6)&0x3F), 0x80|($code&0x3F)); } elsif ( $code <= 0x10FFFF ) { return pack( C4 => 0xF0|($code>>18), 0x80|(($code>>12)&0x3F), 0x80|(($code>>6)&0x3F), 0x80|($code&0x3F)); } return shift if scalar @_; # default value sprintf( '&#x%04X;', $code ); } 1; XML-TreePP-0.39/MANIFEST0000644000175100017510000000276111222330273013602 0ustar u-sukeu-sukeChanges example/envxml.cgi lib/XML/TreePP.pm make-dist.sh Makefile.PL MANIFEST META.yml README t/00_pod.t t/01_parse.t t/02_write.t t/03_parsefile.t t/04_escape.t t/05_empty.t t/06_cdata.t t/07_attr_prefix.t t/08_force_array.t t/09_http-lite.t t/10_http-lwp.t t/11_escape_cdata.t t/12_escape_charref.t t/13_encoding_en.t t/14_encoding_zh.t t/15_encoding_ja.t t/16_encoding_ko.t t/17_output_encoding.t t/18_escape_amp.t t/19_multi_text.t t/20_http-lite-cached.t t/21_http-lwp-cached.t t/22_http-lite-headers.t t/23_http-lwp-headers.t t/24_ignore_error.t t/25_text_node_key.t t/26_attr_prefix_null.t t/27_http-lite-force.t t/28_http-lwp-force.t t/29_http-lwp-withcache.t t/30_first_out.t t/31_tie_ixhash.t t/32_base_class.t t/33_indent.t t/34_utf8_flag.t t/35_force_hash.t t/36_elem_class.t t/37_undef.t t/38_cdata_cdsect.t t/39_writefile.t t/40_writefile_jcode.t t/41_writefile_encode.t t/42_cdata_comment.t t/43_encoding_quote.t t/44_utf8_bom.t t/45_attr_space.t t/46_xml_deref.t t/47_xml_deref_utf8.t t/48_blobref.t t/49_invalid_encoding.t t/50_invalid_tree.t t/example/hello-en-latin1.xml t/example/hello-en-nodecl-bom.xml t/example/hello-en-nodecl.xml t/example/hello-en-noenc-bom.xml t/example/hello-en-noenc.xml t/example/hello-en-utf8-bom.xml t/example/hello-en-utf8.xml t/example/hello-ja-euc.xml t/example/hello-ja-sjis.xml t/example/hello-ja-utf8.xml t/example/hello-ko-euc.xml t/example/hello-ko-utf8.xml t/example/hello-zh-big5.xml t/example/hello-zh-gb2312.xml t/example/hello-zh-utf8.xml t/example/index.rdf XML-TreePP-0.39/README0000644000175100017510000003030111136634137013332 0ustar u-sukeu-sukeNAME XML::TreePP -- Pure Perl implementation for parsing/writing XML documents SYNOPSIS parse an XML document from file into hash tree: use XML::TreePP; my $tpp = XML::TreePP->new(); my $tree = $tpp->parsefile( "index.rdf" ); print "Title: ", $tree->{"rdf:RDF"}->{item}->[0]->{title}, "\n"; print "URL: ", $tree->{"rdf:RDF"}->{item}->[0]->{link}, "\n"; write an XML document as string from hash tree: use XML::TreePP; my $tpp = XML::TreePP->new(); my $tree = { rss => { channel => { item => [ { title => "The Perl Directory", link => "http://www.perl.org/", }, { title => "The Comprehensive Perl Archive Network", link => "http://cpan.perl.org/", } ] } } }; my $xml = $tpp->write( $tree ); print $xml; get a remote XML document by HTTP-GET and parse it into hash tree: use XML::TreePP; my $tpp = XML::TreePP->new(); my $tree = $tpp->parsehttp( GET => "http://use.perl.org/index.rss" ); print "Title: ", $tree->{"rdf:RDF"}->{channel}->{title}, "\n"; print "URL: ", $tree->{"rdf:RDF"}->{channel}->{link}, "\n"; get a remote XML document by HTTP-POST and parse it into hash tree: use XML::TreePP; my $tpp = XML::TreePP->new( force_array => [qw( item )] ); my $cgiurl = "http://search.hatena.ne.jp/keyword"; my $keyword = "ajax"; my $cgiquery = "mode=rss2&word=".$keyword; my $tree = $tpp->parsehttp( POST => $cgiurl, $cgiquery ); print "Link: ", $tree->{rss}->{channel}->{item}->[0]->{link}, "\n"; print "Desc: ", $tree->{rss}->{channel}->{item}->[0]->{description}, "\n"; DESCRIPTION XML::TreePP module parses an XML document and expands it for a hash tree. This generates an XML document from a hash tree as the opposite way around. This is a pure Perl implementation and requires no modules depended. This can also fetch and parse an XML document from remote web server like the XMLHttpRequest object does at JavaScript language. EXAMPLES Parse XML file Sample XML document: Yasuhisa Chizuko Shiori Yusuke Kairi Sample program to read a xml file and dump it: use XML::TreePP; use Data::Dumper; my $tpp = XML::TreePP->new(); my $tree = $tpp->parsefile( "family.xml" ); my $text = Dumper( $tree ); print $text; Result dumped: $VAR1 = { 'family' => { '-name' => 'Kawasaki', 'father' => 'Yasuhisa', 'mother' => 'Chizuko', 'children' => { 'girl' => 'Shiori' 'boy' => [ 'Yusuke', 'Kairi' ], } } }; Details: print $tree->{family}->{father}; # the father's given name. The prefix '-' is added on every attribute's name. print $tree->{family}->{"-name"}; # the family name of the family The array is used because the family has two boys. print $tree->{family}->{children}->{boy}->[1]; # The second boy's name print $tree->{family}->{children}->{girl}; # The girl's name Text node and attributes: If a element has both of a text node and attributes or both of a text node and other child nodes, value of a text node is moved to "#text" like child nodes. use XML::TreePP; use Data::Dumper; my $tpp = XML::TreePP->new(); my $source = 'Kawasaki Yusuke'; my $tree = $tpp->parse( $source ); my $text = Dumper( $tree ); print $text; The result dumped is following: $VAR1 = { 'span' => { '-class' => 'author', '#text' => 'Kawasaki Yusuke' } }; The special node name of "#text" is used because this elements has attribute(s) in addition to the text node. See also "text_node_key" option. METHODS new This constructor method returns a new XML::TreePP object with %options. $tpp = XML::TreePP->new( %options ); set This method sets a option value for "option_name". If $option_value is not defined, its option is deleted. $tpp->set( option_name => $option_value ); See OPTIONS section below for details. get This method returns a current option value for "option_name". $tpp->get( 'option_name' ); parse This method reads an XML document by string and returns a hash tree converted. The first argument is a scalar or a reference to a scalar. $tree = $tpp->parse( $source ); parsefile This method reads an XML document by file and returns a hash tree converted. The first argument is a filename. $tree = $tpp->parsefile( $file ); parsehttp This method receives an XML document from a remote server via HTTP and returns a hash tree converted. $tree = $tpp->parsehttp( $method, $url, $body, $head ); $method is a method of HTTP connection: GET/POST/PUT/DELETE $url is an URI of an XML file. $body is a request body when you use POST method. $head is a request headers as a hash ref. LWP::UserAgent module or HTTP::Lite module is required to fetch a file. ( $tree, $xml, $code ) = $tpp->parsehttp( $method, $url, $body, $head ); In array context, This method returns also raw XML document received and HTTP response's status code. write This method parses a hash tree and returns an XML document as a string. $source = $tpp->write( $tree, $encode ); $tree is a reference to a hash tree. writefile This method parses a hash tree and writes an XML document into a file. $tpp->writefile( $file, $tree, $encode ); $file is a filename to create. $tree is a reference to a hash tree. OPTIONS FOR PARSING XML This module accepts option parameters following: force_array This option allows you to specify a list of element names which should always be forced into an array representation. $tpp->set( force_array => [ 'rdf:li', 'item', '-xmlns' ] ); The default value is null, it means that context of the elements will determine to make array or to keep it scalar or hash. Note that the special wildcard name '*' means all elements. force_hash This option allows you to specify a list of element names which should always be forced into an hash representation. $tpp->set( force_hash => [ 'item', 'image' ] ); The default value is null, it means that context of the elements will determine to make hash or to keep it scalar as a text node. See also "text_node_key" option below. Note that the special wildcard name '*' means all elements. cdata_scalar_ref This option allows you to convert a cdata section into a reference for scalar on parsing an XML document. $tpp->set( cdata_scalar_ref => 1 ); The default value is false, it means that each cdata section is converted into a scalar. user_agent This option allows you to specify a HTTP_USER_AGENT string which is used by parsehttp() method. $tpp->set( user_agent => 'Mozilla/4.0 (compatible; ...)' ); The default string is 'XML-TreePP/#.##', where '#.##' is substituted with the version number of this library. http_lite This option forces pasrsehttp() method to use a HTTP::Lite instance. my $http = HTTP::Lite->new(); $tpp->set( http_lite => $http ); lwp_useragent This option forces pasrsehttp() method to use a LWP::UserAgent instance. my $ua = LWP::UserAgent->new(); $ua->timeout( 60 ); $ua->env_proxy; $tpp->set( lwp_useragent => $ua ); You may use this with LWP::UserAgent::WithCache. base_class This blesses class name for each element's hashref. Each class is named straight as a child class of it parent class. $tpp->set( base_class => 'MyElement' ); my $xml = 'text'; my $tree = $tpp->parse( $xml ); print ref $tree->{root}->{parent}->{child}, "\n"; A hash for element above is blessed to "MyElement::root::parent::child" class. You may use this with Class::Accessor. elem_class This blesses class name for each element's hashref. Each class is named horizontally under the direct child of "MyElement". $tpp->set( base_class => 'MyElement' ); my $xml = 'text'; my $tree = $tpp->parse( $xml ); print ref $tree->{root}->{parent}->{child}, "\n"; A hash for element above is blessed to "MyElement::child" class. xml_deref This option dereferences the numeric character references, like ë, 漢, etc., in an XML document when this value is true. $tpp->set( xml_deref => 1 ); Note that, for security reasons and your convenient, this module dereferences the predefined character entity references, &, <, >, ' and ", and the numeric character references up to U+007F without xml_deref per default. OPTIONS FOR WRITING XML first_out This option allows you to specify a list of element/attribute names which should always appears at first on output XML document. $tpp->set( first_out => [ 'link', 'title', '-type' ] ); The default value is null, it means alphabetical order is used. last_out This option allows you to specify a list of element/attribute names which should always appears at last on output XML document. $tpp->set( last_out => [ 'items', 'item', 'entry' ] ); indent This makes the output more human readable by indenting appropriately. $tpp->set( indent => 2 ); This doesn't strictly follow the XML specification but does looks nice. xml_decl This module inserts an XML declaration on top of the XML document generated per default. This option forces to change it to another or just remove it. $tpp->set( xml_decl => '' ); output_encoding This option allows you to specify a encoding of the XML document generated by write/writefile methods. $tpp->set( output_encoding => 'UTF-8' ); On Perl 5.8.0 and later, you can select it from every encodings supported by Encode.pm. On Perl 5.6.x and before with Jcode.pm, you can use "Shift_JIS", "EUC-JP", "ISO-2022-JP" and "UTF-8". The default value is "UTF-8" which is recommended encoding. OPTIONS FOR BOTH utf8_flag This makes utf8 flag on for every element's value parsed and makes it on for the XML document generated as well. $tpp->set( utf8_flag => 1 ); Perl 5.8.1 or later is required to use this. attr_prefix This option allows you to specify a prefix character(s) which is inserted before each attribute names. $tpp->set( attr_prefix => '@' ); The default character is '-'. Or set '@' to access attribute values like E4X, ECMAScript for XML. Zero-length prefix '' is available as well, it means no prefix is added. text_node_key This option allows you to specify a hash key for text nodes. $tpp->set( text_node_key => '#text' ); The default key is "#text". ignore_error This module calls Carp::croak function on an error per default. This option makes all errors ignored and just returns. $tpp->set( ignore_error => 1 ); use_ixhash This option keeps the order for each element appeared in XML. Tie::IxHash module is required. $tpp->set( use_ixhash => 1 ); This makes parsing performance slow. (about 100% slower than default) AUTHOR Yusuke Kawasaki, http://www.kawa.net/ COPYRIGHT AND LICENSE Copyright (c) 2006-2009 Yusuke Kawasaki. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. XML-TreePP-0.39/META.yml0000644000175100017510000000076711222330343013724 0ustar u-sukeu-suke--- #YAML:1.0 name: XML-TreePP version: 0.39 abstract: ~ author: [] license: perl distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: ExtUtils::MakeMaker: 0 requires: LWP: 5.802 Test::More: 0 no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.52 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 XML-TreePP-0.39/example/0000755000175100017510000000000011222330343014074 5ustar u-sukeu-sukeXML-TreePP-0.39/example/envxml.cgi0000755000175100017510000000026110424737556016117 0ustar u-sukeu-suke#!/usr/bin/perl use strict; use XML::TreePP; my $tree = { env => \%ENV }; my $tpp = XML::TreePP->new(); print "Content-Type: text/xml\n\n"; print $tpp->write( $tree ), "\n"; XML-TreePP-0.39/Makefile.PL0000755000175100017510000000143211222010136014411 0ustar u-sukeu-sukeuse ExtUtils::MakeMaker; my $opt = { NAME => 'XML::TreePP', VERSION_FROM => 'lib/XML/TreePP.pm', PREREQ_PM => { 'Test::More' => '0', # 'LWP::UserAgent' => '0', # 'HTTP::Lite' => '0', # 'Jcode' => '0', # on Perl 5.005/5.6.x }, }; my $mm = $ExtUtils::MakeMaker::VERSION; $mm =~ s/[^\d\.]+//g; $opt->{LICENSE} = 'perl' if ( $mm >= 6.3001 ); my $PERL581 = 1 if ( $] >= 5.008001 ); $opt->{PREREQ_PM}->{Jcode} = '0' unless $PERL581; eval { require 'LWP/UserAgent.pm'; }; # LWP.pm 5.802 required for decoded_content method $opt->{PREREQ_PM}->{'LWP'} = '5.802' if $LWP::UserAgent::VERSION; $opt->{PREREQ_PM}->{'HTTP::Lite'} = '0' unless $LWP::UserAgent::VERSION; WriteMakefile( %$opt ); XML-TreePP-0.39/Changes0000755000175100017510000001520711222327750013754 0ustar u-sukeu-suke# XML::TreePP Changes 2009/06/30 (0.39) * parsehttp now uses decoded_content method under LWP 5.802. This allows compressed content by Content-Encoding: gzip, etc. (thanks to cormanaz and ikegami) http://perlmonks.org/?node_id=774537 http://rt.cpan.org/Public/Bug/Display.html?id=47336 2009/03/01 (0.38) * dies by "Invalid tree" when write() is called without a hash argument. * warns by "Unsupported reference type" when write() is called with a tree which contains unsupported references, ex. BLOBREF. It avoids "Not a HASH reference" and "Can't use string as a HASH ref." * dies by "Unknown encoding" when unknown encoding is used. * No new features are added at this version except for the messages above. 2009/01/17 (0.37) * new option: xml_deref dereferences the numeric character references, like ë, 漢 etc. Now UTF-8 flag is correctly treated. (thanks to haarg) http://rt.cpan.org/Public/Bug/Display.html?id=42347 * without xml_deref option, the numeric character references between U+0080 and U+00FF are not dereferenced any more. the numeric character references up to U+007F and the predefined character entity references are still dereferenced per default. * supports Perl 5.8.4 which includes Encode 1.99_01. (thanks to SAPER) http://rt.cpan.org/Public/Bug/Display.html?id=41986 2008/10/26 (0.36) * supports spaces around the "=" sign in attribute (thanks to John) ex. http://tech.groups.yahoo.com/group/xml-treepp/message/27 * Perl 5.10.0 has a memory leak problem on qr// (thanks to Marcin Guzowski) http://rt.perl.org/rt3/Public/Bug/Display.html?id=59516 * Makefile.PL now calls Jcode and HTTP::Lite when needed 2008/01/05 (0.33) * Subversion on Google Code http://xml-treepp.googlecode.com/svn/trunk/XML-TreePP/ * supports UTF-8 with BOM when parsing XML http://www.kawa.net/works/perl/feedpp/feedpp.html#com-2008-01-03T15:02:56Z 2007/11/11 (0.32) * supports invalid xml decl quoted with single quote (thanks to xatrix) ex. http://rt.cpan.org/Public/Bug/Display.html?id=30187 2007/09/22 (0.31) * "]]>" in CDATA must be separated into "]]>" http://www.w3.org/TR/REC-xml/#sec-cdata-sect * utf8_flag option requires Perl 5.8.1 * avoid "Wide character in print at" in writefile() 2007/08/27 (0.29) * 34_utf8_flag.t skips all tests on Perl 5.8.0 utf8::is_utf8() wasn't there in 5.8.0. http://www.nntp.perl.org/group/perl.perl5.changes/2003/08/msg8628.html * 34_utf8_flag.t passes all tests on Perl 5.8.1-2 http://rt.perl.org/rt3/Public/Bug/Display.html?id=24846 * avoid "Use of uninitialized value in substitution" in xml_escape 2007/08/13 (0.27) * bug fix: autoload Encode.pm on particular environment, $] == 5.008 http://www.nntp.perl.org/group/perl.cpan.testers/2007/08/msg557739.html http://www.nntp.perl.org/group/perl.cpan.testers/2007/08/msg557741.html * pod revised. OPTIONS FOR PARSING/WRITING sections are separated. 2007/08/07 (0.26) * new option: force_array => '*' means every elements (thanks to Niek) * new option: force_hash => [], and also '*' means every elements * new option: elem_class => 'class' * new tests: t/35_force_hash.t t/36_elem_class.t 2007/07/28 (0.22) * new option: ident => 2 (thanks to Aaron) * new option: utf8_flag => 1 * new option: base_class => 'class' * new tests: t/32_base_class.t t/33_indent.t t/34_utf8_flag.t * LICENSE field added in META.yml 2007/07/25 (0.21) * bug fix: use_ixhash missing order on elements with attribute(s) 2007/07/22 (0.20) * new option: http_lite => HTTP::Lite->new() * new option: lwp_useragent => LWP::UserAgent->new() (thanks to NEELY) http://rt.cpan.org/Ticket/Display.html?id=28167 * new option: use_ixhash => 1 (thanks to RENEEB) http://rt.cpan.org/Ticket/Display.html?id=23522 * first_out and last_out options keep its order (thanks to BASHI and sajohn52) http://tech.groups.yahoo.com/group/xml-treepp/message/13 * new tests: 27_http-lite-force.t 28_http-lwp-force.t 29_http-lwp-withcache.t 30_first_out.t 31_tie_ixhash.t 2006/11/03 (0.19) * new option: text_node_key (thanks to Niek) * attr_prefix now supports zero-length prefix. 2006/08/13 (0.18) * parsehttp()'s 4th argument: an HTTP request header as a hash ref. * new option: ignore_error (thanks to Riyousha) * new option: xml_decl (thanks to Stephen and Jon) * new tests: 20_http-lite-cached.t 21_http-lwp-cached.t 22_http-lite-headers.t 23_http-lwp-headers.t 24_ignore_error.t 2006/05/25 (0.17) * bug fix: multiple CDATA or text nodes in a element (thanks to junichi) * new test: 19_multi_text.t 2006/05/21 (0.16) * bug fix: character references support (since 0.14) * Encode::FB_XMLCREF support (again) * new test: 18_escape_amp.t 2006/05/15 (0.14) * new encodings: eucJP-win and eucJP-ms (for Perl 5.005/5.6.1) * new entity references: ' * character references supported: & & * spaces in text node are not deleted on parse() method. * returns are not added in text node on write() method. * HTTP tests are skipped per default: 09_http-lite.t 10_http-lwp.t * new tests: 00_pod.t 13_encoding_en.t 14_encoding_zh.t 15_encoding_ja.t 16_encoding_ko.t 17_output_encoding.t 2006/04/30 (0.10) * attr_prefix parameter added to emulate E4X, ECMAScript for XML. * user_agent parameter and its default value added. * source code passed perltidy. (thanks to Nadim) 2006/04/08 (0.08) * set() and get() method added. * cdata_scalar_ref option added. CDATASection's round trip supported. * some error checkes added. (thanks to Nadim) 2006/03/09 (0.07) * Correct POD about parsehttp() method 2006/03/02 (0.06) * parsehttp() method now supports the HTTP::Lite pure Perl module as well. * Bug fix: xml_escape() call in hash_to_xml() method. (thanks to suVene) 2006/02/26 (0.04) * Correct POD about force_array option of new() method. * parsehttp() method returns a hash tree and xml source on array context. 2006/02/22 (0.03) * Changes 2006/02/21 (0.02) * Change encoding from ISO-8859-1 to UTF-8 is natively supported. * t/force_array.t t/parse.t t/parsefile.t t/parsehttp.t t/write.t t/index.rdf t/family.xml * Test scripts added. 2006/02/20 (0.01) * first release. # http://www.kawa.net/works/perl/treepp/treepp-e.html (English) # http://www.kawa.net/works/perl/treepp/treepp.html#changes (Japanese)