Perl で、Google の PageRank を表示するには以下のモジュールを使う。
ここではクライアント/サーバ間の通信、画面表示に AJAX を使っている。
ここで、ブラウザ側 (JavaScript) で XML を受け取るには、以下の部分が重要である。
var xml = xmlHttp.responseXML;
var pagerank = xml.documentElement
                  .getElementsByTagName('PageRank')[0]
                  .childNodes[0]
                  .nodeValue;以下はサーバ側コード、XML のフォーマット、クライアント側 JavaScript である。
使用するモジュール
use WWW::Google::PageRank;サーバ側の CGI (Perl) コード
#!/usr/bin/perl
# created by yas 2006/01/08
use lib 'WWW::Google::PageRank モジュールまでのパス: …/lib/perl5/site_perl';
use strict;
use utf8;
use WWW::Google::PageRank;
use CGI;
our $XML_HEADER = "Content-type: text/xml\n\n"   # XML を送るときは絶対にこれが必要!!! MUST!!!
                . "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; #  XML Header
my $CGI   = new CGI;
my $proxy = new WWW::Google::PageRank;
my $pagerank = $proxy->get($CGI->param('url'));
my $xml = "$XML_HEADER"
        . qq|<xml><PageRank>$pagerank</PageRank></xml>\n|;
print $xml;
1;
サーバがクライアントに送る XML の例 (
Content-type: text/xml
<?xml version="1.0" encoding="UTF-8"?>
<xml><PageRank>1</PageRank></xml>クライアント (ブラウザ) 側のコード
//<![CDATA[
var BASE_URL = '/perltips';
var CGI_FILE = '/pagerank.cgi';
// 特に IE に対応するために、XMLHttpRequest オブジェクトをブラウザによって作成
function createXmlHttp() {
    try {
        return new ActiveXObject ('Msxml2.XMLHTTP');
    } catch(e) {
        try {
            return new ActiveXObject ('Microsoft.XMLHTTP');
        } catch(e1) {
            try {
                return new XMLHttpRequest();
            } catch(e2) {
                return null;
            }
        }
    }
}
// メイン部分。HTML <input type="button" onClick="getPageRank"> タグの
// onClick で関連付けられている。ボタンが押されると呼び出される。
function getPageRank() {
    if ((xmlhttp = createXmlHttp()) == null) {
        window.alert('XMLHTTP Initialization Failed.');
    } else {
        xmlhttp.abort();    // 連続して HTTP 通信する場合は必ず呼び出す。
    }
    post('url=' + document.getElementById('url').value);  // submit から url を取得
}
function repaint(xml) {
   var pagerank = '';
    if(xml) {
        // IE の場合はより厳密にチェックが必要、Firefox は xml だけでよい
        if(xml.documentElement) {
            pagerank = xml.documentElement
                          .getElementsByTagName('PageRank')[0]
                          .childNodes[0]
                          .nodeValue;
        }
    }
    // このスクリプトが呼ばれる HTML には、<div id="PageRank"></div> があるとする。
    document.getElementById('PageRank').innerHTML = 'PageRank: ' + pagerank;
}
// post メソッドは、例えば getPath メソッドから呼ばれる
function post(data) {
    var xmlHttp = createXmlHttp();
    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState == 4) {
            var xml = xmlHttp.responseXML;
            repaint(xml);
        }
    }
    xmlHttp.open('POST', BASE_URL + CGI_FILE, true);
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlHttp.send(data);
}
//]]>
Perl で、Google の PageRank を表示するには以下のモジュールを使う。
ここではクライアント/サーバ間の通信、画面表示に AJAX を使っている。
ここで、ブラウザ側 (JavaScript) で XML を受け取るには、以下の部分が重要である。
var xml = xmlHttp.responseXML;
var pagerank = xml.documentElement
                  .getElementsByTagName('PageRank')[0]
                  .childNodes[0]
                  .nodeValue;以下はサーバ側コード、XML のフォーマット、クライアント側 JavaScript である。
使用するモジュール
use WWW::Google::PageRank;サーバ側の CGI (Perl) コード
#!/usr/bin/perl
# created by yas 2006/01/08
use lib 'WWW::Google::PageRank モジュールまでのパス: …/lib/perl5/site_perl';
use strict;
use utf8;
use WWW::Google::PageRank;
use CGI;
our $XML_HEADER = "Content-type: text/xml\n\n"   # XML を送るときは絶対にこれが必要!!! MUST!!!
                . "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; #  XML Header
my $CGI   = new CGI;
my $proxy = new WWW::Google::PageRank;
my $pagerank = $proxy->get($CGI->param('url'));
my $xml = "$XML_HEADER"
        . qq|<xml><PageRank>$pagerank</PageRank></xml>\n|;
print $xml;
1;
サーバがクライアントに送る XML の例 (
Content-type: text/xml
<?xml version="1.0" encoding="UTF-8"?>
<xml><PageRank>1</PageRank></xml>クライアント (ブラウザ) 側のコード
//<![CDATA[
var BASE_URL = '/perltips';
var CGI_FILE = '/pagerank.cgi';
// 特に IE に対応するために、XMLHttpRequest オブジェクトをブラウザによって作成
function createXmlHttp() {
    try {
        return new ActiveXObject ('Msxml2.XMLHTTP');
    } catch(e) {
        try {
            return new ActiveXObject ('Microsoft.XMLHTTP');
        } catch(e1) {
            try {
                return new XMLHttpRequest();
            } catch(e2) {
                return null;
            }
        }
    }
}
// メイン部分。HTML <input type="button" onClick="getPageRank"> タグの
// onClick で関連付けられている。ボタンが押されると呼び出される。
function getPageRank() {
    if ((xmlhttp = createXmlHttp()) == null) {
        window.alert('XMLHTTP Initialization Failed.');
    } else {
        xmlhttp.abort();    // 連続して HTTP 通信する場合は必ず呼び出す。
    }
    post('url=' + document.getElementById('url').value);  // submit から url を取得
}
function repaint(xml) {
   var pagerank = '';
    if(xml) {
        // IE の場合はより厳密にチェックが必要、Firefox は xml だけでよい
        if(xml.documentElement) {
            pagerank = xml.documentElement
                          .getElementsByTagName('PageRank')[0]
                          .childNodes[0]
                          .nodeValue;
        }
    }
    // このスクリプトが呼ばれる HTML には、<div id="PageRank"></div> があるとする。
    document.getElementById('PageRank').innerHTML = 'PageRank: ' + pagerank;
}
// post メソッドは、例えば getPath メソッドから呼ばれる
function post(data) {
    var xmlHttp = createXmlHttp();
    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState == 4) {
            var xml = xmlHttp.responseXML;
            repaint(xml);
        }
    }
    xmlHttp.open('POST', BASE_URL + CGI_FILE, true);
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlHttp.send(data);
}
//]]><html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="stylesheet" href="styles-site.css" type="text/css" />
    </head>
    <body>
        <form enctype="multipart/form-data" action="gmap_excel.cgi" method="post">
            <input type="hidden" name="MAX_FILE_SIZE" value="2000000" />
            <table width="600">
                <tr><td>Names file:</td><td><input type="file" name="file" />
                        <input type="submit" value="Upload" /></td></tr>
            </table>
        </form>
    </body>
</html>#!/usr/bin/perl
use lib "path_to_your_perl_lib/lib/perl5/site_perl";
use strict;
use Geo::Google;
use CGI;
our $XML_HEADER   = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";  #  XML ヘッダ
our $HOME_DIR     = 'your_home_dir';
our $LOCK_DIR     = 'path_to_lock_dir/lock'; # do chmod 777 path_to_lock_dir/lock
our $LOCK_FILE    = 'lock';
our $XML_FILE     = 'path_to_your_output_xml/gmap_excel.xml';        #  出力用 XML ファイル名
our $col_index    = 0;  #  Excel シートの現在の列(カラム)インデックス
our $row_index    = 0;  #  Excel シートの現在の行インデックス
our @data         = (); #  出力用データ
our @current_data = (); #  現在のデータ
# オブジェクト初期化
our $CGI = new CGI;
our $GEO = new Geo::Google;
# HTML 出力
print qq|Content-type: text/html\n\n|;
print qq|<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />|;
print qq|<link rel="stylesheet" href="styles-site.css" type="text/css" />|;
print qq|<div class="content"><p>|;
init();
print qq|</p></div>|;
# 個々のデータのハンドラ
sub dataHandler {
    my ($expat, $text) = @_;
    #  $row_index = 0 と 1 は、Excel で データのヘッダのため必要なし
    if($text !~ /^\s+$/ && $row_index > 1) {    #  空白行でなければ
        $current_data[$col_index] = $text;
    }
}
# 要素の開始
sub startElement {
    my ($expat, $tag, %attr) = @_;
    if($tag eq 'Row') {            #  <Row>で始まるとき
        $col_index = 0;                #  カラムを初期化
        $row_index++;                #  行を進める
        @current_data = ();            #  現在の行データを初期化
    }
    if($tag eq 'Data') {            #  <Data>で始まるとき
        $col_index++;                #  列を進める
    }
}
# 要素の終了
sub endElement {
    my ($expat, $tag) = @_;
    my ($xml, $html);
    my ($lng, $lat, $name, $link, $category1, $category2);
    my ($street, $city, $state, $phone, $comment1, $comment2);
    #  </Row> のとき
    if($tag eq 'Row') {
        push(@data, {    # データに現在の行データを代入
            'category1' => $current_data[1],
            'category2' => $current_data[2],
            'name'      => $current_data[3],
            'address'   => $current_data[4],
            'phone'     => $current_data[5],
            'link'      => $current_data[6],
            'comment1'  => $current_data[7],
            'comment2'  => $current_data[8]
        });
    }
    #  </Workbook> のとき
    if($tag eq 'Workbook') {
        $row_index = -1; #  行数を初期化 ($row_index = 0 はヘッダのため -1 からスタート)
        foreach my $row (@data) {
            $row_index++;
            if($row->{address}) {
                $lng = '';  $lat = '';
                my ($degree) = getDegrees($row->{address});
                if($degree) {
                    $lng    = $degree->longitude;
                    $lat    = $degree->latitude;
                }
            }
            $name      = $row->{name};
            $link      = $row->{link}
                       =~ /http:\/\/[!#-9A-~]+\.+[a-z0-9]/ ? $row->{link} : '';
            $category1 = $row->{category1};
            $category2 = $row->{category2};
            ($street, $city, $state) = split(',', $row->{address});
            $street    = $street;
            $city      = $city;
            $state     = $state;
            $phone     = $row->{phone};
            $comment1  = $row->{comment1} eq '-' ? '' : $row->{comment1};
            $comment2  = $row->{comment2};
            #  lng と lat が検索できたら (データが入っているということだから)
            if($lng && $lat) {
                $xml    .= "\t<marker\n"
                        .  "\t\tlng       = \"$lng\" lat = \"$lat\"\n"
                        .  "\t\tname      = \"" . $name      . "\"\n"
                        .  "\t\tlink      = \"" . $link      . "\"\n"
                        .  "\t\tcategory1 = \"" . $category1 . "\"\n"
                        .  "\t\tcategory2 = \"" . $category2 . "\"\n"
                        .  "\t\taddress1  = \"$street\"\n"
                        .  "\t\taddress2  = \"$city, $state\"\n"
                        .  "\t\tphone     = \"$phone\"\n"
                        .  "\t\tcomment1  = \"$comment1\"\n"
                        .  "\t\tcomment2  = \"$comment2\"\n"
                        .  "\t/>\n\n";
            } elsif($row_index) {
                $html   .= '<tr><td>'
                        .  "$row_index / $name / $street, $city, $state"
                        .  '</td></tr>';
            }
        }
        $xml    =  $XML_HEADER
                .  "<markers>\n"
                .  $xml
                .  "</markers>\n";
        if($html) {    #  エラーがあれば
            $html    = '<table>'
                     . '<tr><td>***** 以下、緯度経度が検索不能でした。</td></tr>'
                     . $html
                     . '</table>';
        } else {    #  エラーがなければ
            print '<br />done.';
        }
        #  ファイルのオープン
        &file_lock;        #  ファイルロック
        open(XML, ">$HOME_DIR$XML_FILE")
        or die('Cannot open an XML file: ' . "$HOME_DIR$XML_FILE");
        print XML $xml;    #  書き込み
        close(XML);        #  ファイルを閉じる
        &file_unlock;      #  ロック解除
        print $html;
    }
}
sub getDegrees {    #  住所から緯度経度を検索
    return $GEO->location( address => shift); # shift = address / リファレンスを返す
}
sub init() {
    # XMLパーサー作成 ('UTF-8')
    my $xml_parser = new XML::Parser(   ProtocolEncoding => 'UTF-8',
                                        Handlers=>{ Start=>\&startElement,
                                                    End  =>\&endElement,
                                                    Char =>\&dataHandler });
    # ファイルのオープンはいらない。input タグで指定した name 属性がそのままファイルハンドルになる
    my $xml = $CGI->param('file');
    # XMLパース処理
    $xml_parser->parse($xml) or    die "XML error: $xml_parser";
    # ファイルクローズ
    close($xml);
}
sub file_lock {
    my $wait = 5;
    while (!symlink('.',"$HOME_DIR$LOCK_DIR/.$LOCK_FILE")) {
        if (--$wait <= 0) {
#            &error(    '現在他の方が使用中です。',
#                    'しばらくしてから再度ご利用ください。');
        }
        sleep (1);
    }
}
sub file_unlock {
    unlink ("$HOME_DIR$LOCK_DIR/.$LOCK_FILE");
}
1;<?xml version="1.0" encoding="UTF-8"?>
<markers>
    <marker
        lng       = "-122.125690" lat = "37.413570"
        name      = "Tofu House"
        link      = ""
        category1 = "Restaurant"
        category2 = "Korean"
        address1  = "4127 El Camino Real"
        address2  = " Palo Alto,  CA 94306"
        phone     = "650-424-8805"
        comment1  = ""
        comment2  = "Santa Clara の Tofu House と同じ店。"
    />
...
</markers><html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="stylesheet" href="styles-site.css" type="text/css" />
    </head>
    <body>
        <form enctype="multipart/form-data" action="gmap_excel.cgi" method="post">
            <input type="hidden" name="MAX_FILE_SIZE" value="2000000" />
            <table width="600">
                <tr><td>Names file:</td><td><input type="file" name="file" />
                        <input type="submit" value="Upload" /></td></tr>
            </table>
        </form>
    </body>
</html>#!/usr/bin/perl
use lib "path_to_your_perl_lib/lib/perl5/site_perl";
use strict;
use Geo::Google;
use CGI;
our $XML_HEADER   = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";  #  XML ヘッダ
our $HOME_DIR     = 'your_home_dir';
our $LOCK_DIR     = 'path_to_lock_dir/lock'; # do chmod 777 path_to_lock_dir/lock
our $LOCK_FILE    = 'lock';
our $XML_FILE     = 'path_to_your_output_xml/gmap_excel.xml';        #  出力用 XML ファイル名
our $col_index    = 0;  #  Excel シートの現在の列(カラム)インデックス
our $row_index    = 0;  #  Excel シートの現在の行インデックス
our @data         = (); #  出力用データ
our @current_data = (); #  現在のデータ
# オブジェクト初期化
our $CGI = new CGI;
our $GEO = new Geo::Google;
# HTML 出力
print qq|Content-type: text/html\n\n|;
print qq|<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />|;
print qq|<link rel="stylesheet" href="styles-site.css" type="text/css" />|;
print qq|<div class="content"><p>|;
init();
print qq|</p></div>|;
# 個々のデータのハンドラ
sub dataHandler {
    my ($expat, $text) = @_;
    #  $row_index = 0 と 1 は、Excel で データのヘッダのため必要なし
    if($text !~ /^\s+$/ && $row_index > 1) {    #  空白行でなければ
        $current_data[$col_index] = $text;
    }
}
# 要素の開始
sub startElement {
    my ($expat, $tag, %attr) = @_;
    if($tag eq 'Row') {            #  <Row>で始まるとき
        $col_index = 0;                #  カラムを初期化
        $row_index++;                #  行を進める
        @current_data = ();            #  現在の行データを初期化
    }
    if($tag eq 'Data') {            #  <Data>で始まるとき
        $col_index++;                #  列を進める
    }
}
# 要素の終了
sub endElement {
    my ($expat, $tag) = @_;
    my ($xml, $html);
    my ($lng, $lat, $name, $link, $category1, $category2);
    my ($street, $city, $state, $phone, $comment1, $comment2);
    #  </Row> のとき
    if($tag eq 'Row') {
        push(@data, {    # データに現在の行データを代入
            'category1' => $current_data[1],
            'category2' => $current_data[2],
            'name'      => $current_data[3],
            'address'   => $current_data[4],
            'phone'     => $current_data[5],
            'link'      => $current_data[6],
            'comment1'  => $current_data[7],
            'comment2'  => $current_data[8]
        });
    }
    #  </Workbook> のとき
    if($tag eq 'Workbook') {
        $row_index = -1; #  行数を初期化 ($row_index = 0 はヘッダのため -1 からスタート)
        foreach my $row (@data) {
            $row_index++;
            if($row->{address}) {
                $lng = '';  $lat = '';
                my ($degree) = getDegrees($row->{address});
                if($degree) {
                    $lng    = $degree->longitude;
                    $lat    = $degree->latitude;
                }
            }
            $name      = $row->{name};
            $link      = $row->{link}
                       =~ /http:\/\/[!#-9A-~]+\.+[a-z0-9]/ ? $row->{link} : '';
            $category1 = $row->{category1};
            $category2 = $row->{category2};
            ($street, $city, $state) = split(',', $row->{address});
            $street    = $street;
            $city      = $city;
            $state     = $state;
            $phone     = $row->{phone};
            $comment1  = $row->{comment1} eq '-' ? '' : $row->{comment1};
            $comment2  = $row->{comment2};
            #  lng と lat が検索できたら (データが入っているということだから)
            if($lng && $lat) {
                $xml    .= "\t<marker\n"
                        .  "\t\tlng       = \"$lng\" lat = \"$lat\"\n"
                        .  "\t\tname      = \"" . $name      . "\"\n"
                        .  "\t\tlink      = \"" . $link      . "\"\n"
                        .  "\t\tcategory1 = \"" . $category1 . "\"\n"
                        .  "\t\tcategory2 = \"" . $category2 . "\"\n"
                        .  "\t\taddress1  = \"$street\"\n"
                        .  "\t\taddress2  = \"$city, $state\"\n"
                        .  "\t\tphone     = \"$phone\"\n"
                        .  "\t\tcomment1  = \"$comment1\"\n"
                        .  "\t\tcomment2  = \"$comment2\"\n"
                        .  "\t/>\n\n";
            } elsif($row_index) {
                $html   .= '<tr><td>'
                        .  "$row_index / $name / $street, $city, $state"
                        .  '</td></tr>';
            }
        }
        $xml    =  $XML_HEADER
                .  "<markers>\n"
                .  $xml
                .  "</markers>\n";
        if($html) {    #  エラーがあれば
            $html    = '<table>'
                     . '<tr><td>***** 以下、緯度経度が検索不能でした。</td></tr>'
                     . $html
                     . '</table>';
        } else {    #  エラーがなければ
            print '<br />done.';
        }
        #  ファイルのオープン
        &file_lock;        #  ファイルロック
        open(XML, ">$HOME_DIR$XML_FILE")
        or die('Cannot open an XML file: ' . "$HOME_DIR$XML_FILE");
        print XML $xml;    #  書き込み
        close(XML);        #  ファイルを閉じる
        &file_unlock;      #  ロック解除
        print $html;
    }
}
sub getDegrees {    #  住所から緯度経度を検索
    return $GEO->location( address => shift); # shift = address / リファレンスを返す
}
sub init() {
    # XMLパーサー作成 ('UTF-8')
    my $xml_parser = new XML::Parser(   ProtocolEncoding => 'UTF-8',
                                        Handlers=>{ Start=>\&startElement,
                                                    End  =>\&endElement,
                                                    Char =>\&dataHandler });
    # ファイルのオープンはいらない。input タグで指定した name 属性がそのままファイルハンドルになる
    my $xml = $CGI->param('file');
    # XMLパース処理
    $xml_parser->parse($xml) or    die "XML error: $xml_parser";
    # ファイルクローズ
    close($xml);
}
sub file_lock {
    my $wait = 5;
    while (!symlink('.',"$HOME_DIR$LOCK_DIR/.$LOCK_FILE")) {
        if (--$wait <= 0) {
#            &error(    '現在他の方が使用中です。',
#                    'しばらくしてから再度ご利用ください。');
        }
        sleep (1);
    }
}
sub file_unlock {
    unlink ("$HOME_DIR$LOCK_DIR/.$LOCK_FILE");
}
1;<?xml version="1.0" encoding="UTF-8"?>
<markers>
    <marker
        lng       = "-122.125690" lat = "37.413570"
        name      = "Tofu House"
        link      = ""
        category1 = "Restaurant"
        category2 = "Korean"
        address1  = "4127 El Camino Real"
        address2  = " Palo Alto,  CA 94306"
        phone     = "650-424-8805"
        comment1  = ""
        comment2  = "Santa Clara の Tofu House と同じ店。"
    />
...
</markers>#!/usr/bin/perl
use LWP::UserAgent;
use HTTP::Request;
use HTTP::Response;
our $URL = 'https://perltips.twinkle.cc/'; # アクセスする URL
my $proxy = new LWP::UserAgent;
my $req = HTTP::Request->new('GET' => $URL); # HTTP リクエストを作成
my $res = $proxy->request($req); # $res に HTTP レスポンスが返ってくる
print $res->content; # HTML を表示
1;#!/usr/bin/perl
use LWP::UserAgent;
use HTTP::Request;
use HTTP::Response;
our $URL = 'https://perltips.twinkle.cc/'; # アクセスする URL
my $proxy = new LWP::UserAgent;
$proxy->agent('your own created browser name here'); # 任意
$proxy->timeout(60); # 任意
my $req = HTTP::Request->new('GET' => $URL);
my $res = $proxy->request($req);
my $content = $res->content;
print "Content-Type: text/html\n\n"; # HTML ヘッダ (CGI として動作できる)
if($res->is_success) {
    print $content;
} else {
    print 'HTTP エラーコード: ' . $res->code;
}
1;#!/usr/bin/perl
use LWP::UserAgent;
use HTTP::Request;
use HTTP::Response;
our $URL = 'https://perltips.twinkle.cc/'; # アクセスする URL
my $proxy = new LWP::UserAgent;
my $req = HTTP::Request->new('GET' => $URL); # HTTP リクエストを作成
my $res = $proxy->request($req); # $res に HTTP レスポンスが返ってくる
print $res->content; # HTML を表示
1;#!/usr/bin/perl
use LWP::UserAgent;
use HTTP::Request;
use HTTP::Response;
our $URL = 'https://perltips.twinkle.cc/'; # アクセスする URL
my $proxy = new LWP::UserAgent;
$proxy->agent('your own created browser name here'); # 任意
$proxy->timeout(60); # 任意
my $req = HTTP::Request->new('GET' => $URL);
my $res = $proxy->request($req);
my $content = $res->content;
print "Content-Type: text/html\n\n"; # HTML ヘッダ (CGI として動作できる)
if($res->is_success) {
    print $content;
} else {
    print 'HTTP エラーコード: ' . $res->code;
}
1;use Encode; use Geo::Google;
#!/usr/bin/perl
use Encode;
use Geo::Google;
# 変数の初期化
our $GEO = new Geo::Google;
our $XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
our $output     = '';    # xml 出力
our ($dist);
$dist->{from} = qq|333 Ofarrell St, San Francisco, CA|; # From の住所 (米国のみ)
$dist->{to  } = qq|39 PIER 39, San Francisco, CA|;      # To   の住所 (米国のみ)
$output = getPath($dist);
$output =    $XML_HEADER
        .    "<markers>\n"
        .    $output
        .    "</markers>\n";
print "Content-type: text/xml\n\n";    # XML を送るときは絶対にこれが必要!!! MUST!!!
print $output;
exit;
sub getPath {
    my ($dist) = shift;
    my $output;
    my $path = $GEO->path(getDegrees($dist->{from}), getDegrees($dist->{to}));
    my @segments = $path->segments();
    foreach my $s (@segments) {
        my $description = $s->text();
        $description =~ s/</&lt;/g;
        $description =~ s/>/&gt;/g;
        $output .= "\t<route\n"
                .  "\t\tdescription=\"" . $description . "\"\n"
                .  "\t/>\n";
        my @points = $s->points;
        foreach my $p (@points) {
            $output .= "\t<path lng=\"" . $p->longitude . "\" lat=\"" . $p->latitude . "\" />\n";
        }
    }
    return $output;
}
sub getDegrees {    #  住所から緯度経度を検索
    return $GEO->location( address => Encode::encode_utf8(shift));
                                                        # shift = address / リファレンスを返す
}
1;Content-type: text/xml
<?xml version="1.0" encoding="UTF-8"?>
<markers>
    <route
        description="Head <b>east</b> from <b>Ofarrell St</b>"
    />
    <route
        description="Turn <b>left</b> at <b>Grant Ave</b>"
        />
    <path lng="-122.40966" lat="37.78621" />
    <path lng="-122.40932" lat="37.78628" />
    <path lng="-122.40894" lat="37.78632" />
    <path lng="-122.40803" lat="37.78644" />
    <path lng="-122.40639" lat="37.78663" />
    <path lng="-122.40529" lat="37.78676" />
    <path lng="-122.40485" lat="37.78683" />
    <path lng="-122.40485" lat="37.78683" />
    <route
        description="Turn <b>left</b> at <b>Sutter St</b>"
    />
    <path lng="-122.40504" lat="37.78774" />
    <path lng="-122.40513" lat="37.78819" />
    <path lng="-122.40524" lat="37.78870" />
    <path lng="-122.40530" lat="37.78913" />
    <path lng="-122.40533" lat="37.78931" />
    <path lng="-122.40539" lat="37.78964" />
    <path lng="-122.40539" lat="37.78964" />
</markers>use Encode; use Geo::Google;
#!/usr/bin/perl
use Encode;
use Geo::Google;
# 変数の初期化
our $GEO = new Geo::Google;
our $XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
our $output     = '';    # xml 出力
our ($dist);
$dist->{from} = qq|333 Ofarrell St, San Francisco, CA|; # From の住所 (米国のみ)
$dist->{to  } = qq|39 PIER 39, San Francisco, CA|;      # To   の住所 (米国のみ)
$output = getPath($dist);
$output =    $XML_HEADER
        .    "<markers>\n"
        .    $output
        .    "</markers>\n";
print "Content-type: text/xml\n\n";    # XML を送るときは絶対にこれが必要!!! MUST!!!
print $output;
exit;
sub getPath {
    my ($dist) = shift;
    my $output;
    my $path = $GEO->path(getDegrees($dist->{from}), getDegrees($dist->{to}));
    my @segments = $path->segments();
    foreach my $s (@segments) {
        my $description = $s->text();
        $description =~ s/</&lt;/g;
        $description =~ s/>/&gt;/g;
        $output .= "\t<route\n"
                .  "\t\tdescription=\"" . $description . "\"\n"
                .  "\t/>\n";
        my @points = $s->points;
        foreach my $p (@points) {
            $output .= "\t<path lng=\"" . $p->longitude . "\" lat=\"" . $p->latitude . "\" />\n";
        }
    }
    return $output;
}
sub getDegrees {    #  住所から緯度経度を検索
    return $GEO->location( address => Encode::encode_utf8(shift));
                                                        # shift = address / リファレンスを返す
}
1;Content-type: text/xml
<?xml version="1.0" encoding="UTF-8"?>
<markers>
    <route
        description="Head <b>east</b> from <b>Ofarrell St</b>"
    />
    <route
        description="Turn <b>left</b> at <b>Grant Ave</b>"
        />
    <path lng="-122.40966" lat="37.78621" />
    <path lng="-122.40932" lat="37.78628" />
    <path lng="-122.40894" lat="37.78632" />
    <path lng="-122.40803" lat="37.78644" />
    <path lng="-122.40639" lat="37.78663" />
    <path lng="-122.40529" lat="37.78676" />
    <path lng="-122.40485" lat="37.78683" />
    <path lng="-122.40485" lat="37.78683" />
    <route
        description="Turn <b>left</b> at <b>Sutter St</b>"
    />
    <path lng="-122.40504" lat="37.78774" />
    <path lng="-122.40513" lat="37.78819" />
    <path lng="-122.40524" lat="37.78870" />
    <path lng="-122.40530" lat="37.78913" />
    <path lng="-122.40533" lat="37.78931" />
    <path lng="-122.40539" lat="37.78964" />
    <path lng="-122.40539" lat="37.78964" />
</markers>