【问题标题】:How do you output an attribute using Perl and XML::Simple如何使用 Perl 和 XML::Simple 输出属性
【发布时间】:2012-06-10 00:21:05
【问题描述】:
sub parse_xml{
    my $xml_link = $_[0];
    my $xml_content = get($xml_link) or warn "Cant get XML page of " . $xml_link . "\n";
    if(!$xml_content){
        return;
    }
    my $xml =  XML::Simple->new(KeepRoot => 1);
    my $xml_data = $xml->XMLin($xml_content);
    my @items = $xml_data->{rss}{channel}->{item};
   # print Dumper($xml_data);
    foreach my $item (@items) {
        if($item){
             print Dumper($item);             //This is the dump output
             print $item->{author};
             #print $item . "\n";
        }
    }
}

当我尝试输出项目的作者时,我只会得到 HASH(Memory Address)not a hash reference at ... line ...

我做错了吗?为什么会产生这个错误?

这是转储程序的输出。

$VAR1 = [
          {
            'link' => 'http://***.com/article/news/betty-white-credits-snickers-golden-opportunities/144290/#comments-67229',
            'author' => {},
            'title' => 'By: ',
            'pubDate' => 'Tue, 08 Jun 2010 12:47 EDT',
            'description' => 'Interesting. At least SHE remembered the product that propelled her to recent recognition. When many people I know have commented on how they loved that Betty White Super Bowl spot, they can't recall the product. Ah, advertising.'
          },
          {
            'link' => 'http://***.com/article/news/betty-white-credits-snickers-golden-opportunities/144290/#comments-67167',
            'author' => {},
            'title' => 'By: ',
            'pubDate' => 'Mon, 07 Jun 2010 13:26 EDT',
            'description' => 'Fun, fun, fun. A great attitude for all of us to take into our careers.'
          },
          {
            'link' => 'http://****.com/article/news/betty-white-credits-snickers-golden-opportunities/144290/#comments-67164',
            'author' => 'username',
            'title' => 'By: username',
            'pubDate' => 'Mon, 07 Jun 2010 12:23 EDT',
            'description' => 'Her appearance of the Comedy Central roast of William Shattner a couple of years ago was great... it seems like her willingness to be irreverent makes her more appealing to us all!  

www.adverspew.com'
          },
          {
            'link' => 'http://****.com/article/news/betty-white-credits-snickers-golden-opportunities/144290/#comments-67142',
            'author' => {},
            'title' => 'By: ',
            'pubDate' => 'Mon, 07 Jun 2010 09:50 EDT',
            'description' => 'Solid interview. I will definitely be tuning into "Hot in Cleveland" next week. We ought to enjoy Ms. White's talents for as long as we have her. She's great!'
          }
        ];

【问题讨论】:

  • 如果您从Dumper($item->{author}) 打印输出会更容易回答 - 事实上,这样做可能会首先告诉您问题所在。
  • 由于答案没有直接说明这一点 - 任何时候当你在 Perl 中打印表达式的值并得到 HASH(address) 时,这意味着你所拥有的都是一个 hashref。
  • XML::Feed 存在,无需编写此自定义解析器。
  • 可能想使用 SuppressEmpty 选项

标签: xml perl hash


【解决方案1】:

此 RSS 提要可能有也可能没有每个项目的 <author> 信息。

如果没有作者,则该元素仍会出现在 XML 中,但它没有内容。它显示为<author></author>

XML::Simple 会将其表示为一个空的匿名哈希。

因此,如果有项目的作者信息,$item->{author} 将是一个简单的文本字符串。否则它将是一个哈希引用。

您可以通过编写代码来编写代码

foreach my $item (@items) {
  my $author = $item->{author};
  $author = '' if ref $author;
  print "$item\n";
}

【讨论】:

  • 谢谢,但我通过检查 $item 是否为哈希表解决了这个问题。好像是不一致,有时返回哈希,有时不返回。
  • @user979663:我看不出$item 可以是哈希引用以外的任何东西。你的意思是检查$item->{author}?这将是一个字符串或哈希引用。我的代码使用if ref $author 来检查它是否是哈希引用。
【解决方案2】:

你走在正确的轨道上。我已经在从这个 StackOverflow 页面链接的新闻源上使用了你的代码,并对其进行了轻微的调整。

use LWP::Simple;
use XML::Simple;
use Data::Dumper;
sub parse_xml{
    my $xml_link = $_[0];
    my $xml_content = get($xml_link) or warn "Cant get XML page of " . $xml_link . "\n";
    if(!$xml_content){
        return;
    }
    my $xml =  XML::Simple->new(KeepRoot => 1);
    my $xml_data = $xml->XMLin($xml_content,ForceArray =>'entry');
    foreach my $item ($xml_data->{'feed'}[0]->{'entry'}) {
        foreach my $entry (@{$item}){
            if($entry){
                print $entry->{'author'}[0]->{'name'}[0]."\n";
                print $entry->{'author'}[0]->{'uri'}[0]."\n";
            }
        }

    }

}
parse_xml('http://stackoverflow.com/feeds/question/10906521');

在该示例上运行良好。我怀疑您可能试图打印出不是普通值的东西——在 stackoverflow 页面的示例中,您可以看到“作者”实际上包含一些子节点,因此如果您尝试打印 $item ->{'author'} 在 foreach 循环中,您将获得您描述的 'HASH' 结果。

看看你的转储和鲍罗丁的明智评论,这应该对你有用:

   my $xml_data = $xml->XMLin($xml_content,ForceArray =>'entry');
    my $item = $xml_data->{'rss'}[0]->{'channel'}[0]->{'item'};
    foreach my $entry (@{$item}){
        if($entry){
            if(!ref $entry->{'author'}[0]){
                    print $entry->{'author'}[0]."\n";
            }
            if(!ref $entry->{'description'}[0]){
                    print $entry->{'description'}[0]."\n";
            }
            if(!ref $entry->{'pubDate'}[0]){
                    print $entry->{'pubDate'}[0]."\n";
            } # etc.
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 2013-07-29
    • 2010-10-14
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多