http://qs321.pair.com?node_id=375951

I wrote this with two aims, to learn XML/XSLT/XPath, and to learn SOAP. I gave up on SOAP and cheated by using the excellent Net::Amazon module :-) The script takes an xml file as input, and produces another xml file containing additional information from amazon, including cover images where available. This is then processed for display using an XML stylesheet. In order to use this, you will need the following sample files:- In addition, you will need an Amazon Developer token, available at www.amazon.com/soap/. Right now, the script can look up information on books and dvds using amazon. The root node is <wishlist/>, which can contain <book/>, <cd/> and <dvd/> child elements. In order to gather data from Amazon, add a child element <amazonAsin/>, and possibly <amazonLocale/> if the item is contained in a different Amazon locale (not all items appear in the us locale!) See the script in action Code critique, and any other feedback good or bad is most definately welcome, as my perl is a little rusty. I probably ought to use XML::DOM instead of XML::Simple.

Update 22/07/2004: Return correct detailUrl (locale-dependant)
#!/usr/bin/perl ### ### Configuration ### # URL of wishlist source my $wishlist_url = 'http://chaz6.com/static/content/wishlist.xml'; # Amazon developer token my $amazon_token = '[Amazon Developer Token]'; # Default locale # Possible values: us,uk,de,jp my $amazon_locale = 'us'; ### ### Modules ### use strict; use CGI; use Cache::File; use LWP::Simple; use XML::Simple; use Net::Amazon; ### ### Main ### # Create a cache object my $cache = Cache::File->new( cache_root => '/tmp/mycache', default_expires => '1 day', ); # Fetch the wishlist my $wishlist_src = get($wishlist_url); # Read the wishlist into an XML object my $wishlist = XMLin($wishlist_src, KeepRoot => 1); # Create a Net::Amazon object my $amazon; my $ua = Net::Amazon->new(token => $amazon_token, cache => $cache); $amazon->{'us'} = Net::Amazon->new(token => $amazon_token, cache => $c +ache); $amazon->{'uk'} = Net::Amazon->new(token => $amazon_token, cache => $c +ache, locale => 'uk'); $amazon->{'jp'} = Net::Amazon->new(token => $amazon_token, cache => $c +ache, locale => 'jp'); $amazon->{'de'} = Net::Amazon->new(token => $amazon_token, cache => $c +ache, locale => 'de'); ###################################################################### +##### ################################## Books ############################# +##### ###################################################################### +##### # Process all the book nodes my $books = $wishlist->{'wishlist'}->{'book'}; # Remove the old book nodes $wishlist->{'wishlist'}->{'book'} = undef; # Create the new node my @newbooks; foreach my $book (@{$books}){ my $bookinfo; # Search for book information my $locale = $book->{'amazonLocale'} || $amazon_locale; # Prefer to use the Amazon ASIN if($book->{'amazonAsin'}) { $bookinfo = getBookInfo(asin => $book->{'amazonAsin'}, locale +=> $locale); # Fall back to ISBN } elsif ($book->{'isbn'}) { $bookinfo = getBookInfo(isbn => $book->{'isbn'}, locale => $lo +cale); } $book->{'imageUrl'} ||= $bookinfo->{'imageUrl'}; $book->{'title'} ||= $bookinfo->{'title'}; $book->{'publisher'} ||= $bookinfo->{'publisher'}; $book->{'year'} ||= $bookinfo->{'year'}; $book->{'media'} ||= $bookinfo->{'media'}; $book->{'released'} ||= $bookinfo->{'released'}; $book->{'imageUrlLarge'} ||= $bookinfo->{'imageUrlLarge'}; $book->{'detailUrl'} ||= $bookinfo->{'detailUrl'}; # Insert the new node into the tree push (@newbooks,$book); } # Insert the new book nodes into the wishlist $wishlist->{'wishlist'}->{'book'} = [@newbooks]; ###################################################################### +##### ################################## dvds ############################## +#### ###################################################################### +##### # Process all the dvd nodes my $dvds = $wishlist->{'wishlist'}->{'dvd'}; # Remove the old dvd nodes $wishlist->{'wishlist'}->{'dvd'} = undef; # Create the new node my @newdvds; foreach my $dvd (@{$dvds}){ my $dvdinfo; my $locale = $dvd->{'amazonLocale'} || $amazon_locale; # Search for dvd information if($dvd->{'amazonAsin'}) { $dvdinfo = getDvdInfo(asin => $dvd->{'amazonAsin'}, locale => +$locale); } if($dvdinfo){ $dvd->{'imageUrl'} ||= $dvdinfo->{'imageUrl'}; $dvd->{'title'} ||= $dvdinfo->{'title'}; $dvd->{'publisher'} ||= $dvdinfo->{'publisher'}; $dvd->{'year'} ||= $dvdinfo->{'year'}; $dvd->{'media'} ||= $dvdinfo->{'media'}; $dvd->{'released'} ||= $dvdinfo->{'released'}; $dvd->{'imageUrlLarge'} ||= $dvdinfo->{'imageUrlLarge'}; $dvd->{'detailUrl'} ||= $dvdinfo->{'detailUrl'}; } # Insert the new node into the tree push (@newdvds,$dvd); } # Insert the new book nodes into the wishlist $wishlist->{'wishlist'}->{'dvd'} = [@newdvds]; # Send the wishlist to the client print CGI->header(-type=>'application/xml'); print '<?xml version="1.0" standalone="yes"?>'; print "\n"; print '<?xml-stylesheet type="text/xsl" href="/static/xml/wishlist.xsl +" media="screen"?>'; print "\n"; print XMLout($wishlist, KeepRoot => 1, NoAttr => 1); ### ### Subroutines ### sub getBookInfo { my %params = @_; my $req; if(0) { } elsif(exists $params{asin}) { $req = getAmazonBookByAsin(%params); } elsif(exists $params{isbn}) { $req = getAmazonBookByIsbn(%params); } else { warn "Request could not be completed"; return; } return $req; } sub getDvdInfo { my %params = @_; my $req; if(0) { } elsif(exists $params{asin}) { $req = getAmazonDvdByAsin(@_); } else { warn "Request could not be completed"; return; } return $req; } sub getAmazonBookByAsin { my %params = @_; my $resp = $amazon->{$params{locale}}->search(asin => $params{asin +}); if($resp->is_success()){ my $bookinfo = getAmazonBookInfo($resp); return $bookinfo; } } # Separated for future use sub getAmazonBookByIsbn { my %params = @_; my $resp = $amazon->{$params{locale}}->search(asin => $params{isbn +}); if($resp->is_success()){ my $bookinfo = getAmazonBookInfo($resp,$params{locale}); return $bookinfo; } } # Takes a Net::Amazon::Search object and returns a hash sub getAmazonBookInfo { my ($resp,$locale) = @_; # Get the result my ($prop) = $resp->properties; # Create the new node my $info; $info->{'imageUrl'} = $prop->ImageUrlMedium; $info->{'title'} = $prop->title; $info->{'publisher'} = $prop->publisher; $info->{'year'} = $prop->year; $info->{'media'} = $prop->Media; $info->{'released'} = $prop->ReleaseDate; $info->{'imageUrlLarge'} = $prop->ImageUrlLarge; $info->{'detailUrl'} = getAmazonUrlPrefix($locale) . $prop->Asin; return $info; } sub getAmazonDvdByAsin { my %params = @_; my $resp = $amazon->{$params{locale}}->search(asin => $params{asin +}); if($resp->is_success()){ my $dvdinfo = getAmazonDvdInfo($resp, $params{locale}); return $dvdinfo; } } sub getAmazonDvdInfo { my ($resp, $locale) = @_; # Get the result my ($prop) = $resp->properties; # Create the new node my $info; $info->{'imageUrl'} = $prop->ImageUrlMedium; $info->{'title'} = $prop->title; #$info->{'publisher'} = $prop->publisher; $info->{'year'} = $prop->year; $info->{'media'} = $prop->Media; $info->{'released'} = $prop->ReleaseDate; $info->{'imageUrlLarge'} = $prop->ImageUrlLarge; $info->{'locale'} = $locale; $info->{'detailUrl'} = getAmazonUrlPrefix($locale) . $prop->Asin; return $info; } sub getAmazonUrlPrefix { my $locale = shift || 'us'; my $prefix; if($locale eq 'us'){ $prefix = 'http://www.amazon.com/exec/obidos/ASIN/'; } elsif ($locale eq 'uk'){ $prefix = 'http://www.amazon.co.uk/exec/obidos/ASIN/'; } elsif ($locale eq 'jp'){ $prefix = 'http://www.amazon.co.jp/exec/obidos/ASIN/'; } elsif ($locale eq 'de'){ $prefix = 'http://www.amazon.de/exec/obidos/ASIN/'; } else { $prefix = 'http://www.amazon.com/exec/obidos/ASIN/'; } return $prefix; }