-1

我想从下面的 XML 文件中获取图像。

部分如何从下面的 XML 文件中获取图像 url,但我无法接收它:

my @imageurl;     
foreach my $img(@{$_->{images}}){     
my $imgurl = &makeScalar($img->{image}->[0]); 

我认为这里有问题:my $imgurl = &makeScalar($img->{image}->[0]); 因为如果这样做:

my @imageurl;     
foreach my $img(@{$_->{images}}){     
my $imgurl = &makeScalar($img->{image_0}->[0]); 

我只得到一张图像而不是 3 张图像?

图像所在的 XML 文件:

<images>
    <image_0>url of image 1</image_0>
    <image_1>ulr of image 2</image_1>
    <image_2>url of image 3</image_2>
 </images>

完整代码:

package test::test1_123;
use strict;
use warnings;
use onb;
use base qw/;
use URI::URL;
use XML::Simple;
use Data::Dumper;
#use Unicode::String qw(utf8 latin1 utf16be);
use constant TASK_ID => 2084;
use constant CR_TYPE => '2084';
use constant IMAGE_PATH => "/home/public_html/files/";#"images/";

sub new
{
    #Initialization
    my $class = shift;
    my $self = $class->SUPER::new(CR_TYPE, TASK_ID);
    bless $self, $class;
    #Initialization ends

    my $url = 'http://www.url.com.asp?id=18&show=1000&page=1';


    my $xml = $self->geturl('url'=>$url);
    $self->extract($xml);


        #$self->teardown;
}

sub extract{
my $self = shift;
my $xmlfile = shift;
my $xml = new XML::Simple(ForceArray=>1,'KeyAttr' =>'image');
my $data = $xml->XMLin($xmlfile);


PASS:foreach(@{$data->{property}}){    

      my $property = &makeScalar($_->{id}->[0]);    

# get images from XML
      my @imageurl;   
      foreach my $img(@{$_->{images}}){
    my $imgurl = &makeScalar($img->{image_0}->[0]);

      push @imageurl,$imgurl;
      }
}
        my $detail = {};

          $detail->{cr_type}  = CR_TYPE;
          $detail->{catid}    = '434';
          $detail->{userid}   = '2084'; 
          $detail->{hw_added}   = &get_date;
          $detail->{hw_updated} = &get_date;

            unless ($self->exists_item($detail->{site_id}))
        {
            my $insertid = $self->add(%{$detail});

     #get last insert id and update images

     #get images and save them into a folder
            my $count = 0;
            my $imgstr;
            foreach my $u(@imageurl){
               my $res = $self->geturl('url'=>$u);
               my $filename = IMAGE_PATH . "item_" . $insertid;
                  $filename = $filename . '_' . $count if $count > 0;
                  $filename = $filename . ".jpg";
                              $imgstr = $imgstr . "" . "item_" . $insertid .".jpg" if $count == 0;
                  $imgstr = $imgstr . "\n" . "item_" . $insertid . "_" . $count .".jpg" if $count > 0;
                  $count++;
                  open FILE,">$filename";binmode(FILE);print FILE $res;close FILE;
                  &ResizeImg($filename,100,100) if -e $filename;

            }

            my $imgs ={};
               $imgs->{link_id} = $insertid;
               $imgs->{images}  = $imgstr;
            $self->update_img(%{$imgs});

        }
}
}



sub get_date {
    my ($sec, $min, $hour, $day, $mon, $year, $dweek, $dyear, $daylight) = localtime(time());
    my (@months) = qw!Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec!;
    ($day < 10) and ($day = "0$day");
    $year = $year + 1900;
    $mon = $mon +1;
     return "$year-$mon-$day $hour-$min-$sec";

}
sub makeScalar() {
    if ($_[0]=~/HASH\(0x(\d|\w)+\)/) { return ''; }
    return $_[0];
}
sub ResizeImg
{
   my ($file,$width_max,$height_max) = @_;
   eval { require GD; };
   return if $@;
   my $image = GD::Image->new($file);
   return unless $image;
   my ($width,$height) = $image->getBounds();
   my ($dx,$dy)=(0,0);
   if($width/$height >= $width_max/$height_max) ### Horizontal
   {
      $dx = sprintf("%.0f", ($width-$width_max*$height/$height_max)/2 );
   }
   else
   {
      $dy = sprintf("%.0f", ($height-$height_max*$width/$width_max)/2 );
   }
   my $thumb = GD::Image->newTrueColor($width_max,$height_max);
   $thumb->copyResampled($image,0,0,$dx,$dy,$width_max,$height_max,$width-2*$dx,$height-2*$dy);

   my $jpegdata = $thumb->jpeg(70);
   $file=~s/\.(jpg|jpeg|gif|png|bmp)$//i;
   $file=~s/\/files\//\/files\/small\//i;
   open(FILE,">$file.jpg")||warn "can't write th:$!";
   binmode FILE;
   print FILE $jpegdata;
   close(FILE);
}

1;
4

1 回答 1

3

首先,XML::Simple 是一个已弃用的模块,您应该尽可能避免使用它,这正是您在此处看到的原因:通常很难预测和处理它产生的 Perl 数据结构。模块文档本身说明了这一点

不鼓励在新代码中使用此模块。其他模块也可以提供更直接和一致的接口。特别是,强烈推荐使用 XML::LibXML。

这个模块的主要问题是大量的选项以及这些选项交互的任意方式——通常会产生意想不到的结果。

因此,如果可能的话,我建议您迁移到XML::LibXMLor XML::Twig

就目前而言,我看不出您的代码无法正常工作的原因,如果您不显示您的 XML,那么没有人可以提供帮助。在我看来,有了XML::Simple你所拥有的选项,每个元素都@{$data->{property}}应该是这样的。

{
  id => [99],
  images => [
    {
      image_0 => ["url of image 1"],
      image_1 => ["url of image 2"],
      image_2 => ["url of image 3"],
    },
  ],
}

for my $img (@{$_->{images}}) { ... }循环一个看起来像的单元素数组也是如此

[
  {
    image_0 => ["url of image 1"],
    image_1 => ["url of image 2"],
    image_2 => ["url of image 3"],
  },
]

并且$img->{image_0}[0]应该是字符串url of image 1

显示您的数据和您的真实程序,我们将能够为您提供进一步的帮助。

于 2013-06-23T16:54:32.580 回答