如何在 Perl 中从 JSON 响应中引用 Array/Hash 中的数据
How to reference Data in an Array/Hash from JSON Response in Perl
我正在写一些 Perl 代码,我完全是个菜鸟(专攻 PHP 和 JS)。我正在从 JSON API 请求中检索一些数据,我想引用这些数据并为 select 字段构建一些 HTML-Options。但我只是不知道如何从 JSON 响应中引用值。
#!/bin/false
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use JSON;
use Encode;
use vars qw(@parameters $new $mode $metainfo);
use Data::Dumper qw(Dumper);
sub main
{
if ($mode ne 'EDIT') {
return;
}
my @pagetypes = _getPagetypes();
if (scalar @pagetypes == 0 || ! defined \@pagetypes) {
return "";
}
my $html = "";
foreach (@pagetypes) {
my $pagetype = $_;
return Dumper @pagetypes;
$html .= sprintf(
'<option value="%s">%s</option>',
$pagetype->{"identifier"},
encode_utf8($pagetype->{"label"}),
);
}
return $html;
}
##
# Get Pagetypes from API
##
sub _getPagetypes
{
my $url = sprintf(
"%s/page-types/",
$ENV{'URL'}
);
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
my $header = HTTP::Request->new(GET => $url);
my $request = HTTP::Request->new('GET', $url, $header);
my $response = $ua->request($request);
my @data = decode_json($response->content);
my @pagetypes = @data[0]->{'pageTypes'};
return @pagetypes;
}
它说 return Dumper $pagetypes;
的地方写了以下输出:
$VAR1 = [
{
'label' => 'Projektsteckbrief',
'identifier' => 'pagetype-profile'
}
];
我尝试了 $pagetype->{"label"}
和 $pagetypes[0]->{"label"}
等等...但我只是不知道如何获得标签和标识符。
更新:
我尝试手动实现页面类型,使用 main()
方法(没有 Dumper Call)效果很好:
sub _getPagetypes
{
my @pagetypes = (
{
identifier => "pagetype-profile",
label => "Projektsteckbrief",
},
);
return @pagetypes;
}
更新 2:
所以我遇到了一个新问题...它还没有完全解决问题,但是 Bl00D4NGEL 的回复还是帮了大忙!
所以我的代码现在看起来像这样:
#!/bin/false
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use JSON;
use Encode;
use Project::Util::Api;
use vars qw(@parameters $new $mode $metainfo);
sub main
{
if ($mode ne 'EDIT') {
return;
}
my @pagetypes = _getPagetypes();
if (scalar @pagetypes == 0 || ! defined \@pagetypes) {
return "";
}
my $html = "";
foreach my $pagetype (@pagetypes) {
# selection will be automatically set by Imperia
$html .= sprintf(
'<option value="%s">%s</option>',
$pagetype->[0]->{"identifier"},
encode_utf8($pagetype->[0]->{"label"}),
);
}
return $html;
}
##
# Get Pagetypes from API
##
sub _getPagetypes
{
my $response = Project::Util::Api->sendRequest("/ajax/imperia/page-types/de/");
my @pagetypes = $response->{"pageTypes"};
return @pagetypes;
}
$new = main();
现在的问题是只显示了一项。
所以 $pagetype
在我的 foreach 循环中看起来它仍然是包含所有项目的数组,然后 $pagetype->[0]
只给我数组中的第一个项目。
当我像这样使用 for
而不是 foreach
时:
for ( $a = 0 ; $a <= 10 ; $a++ ) {
$html .= sprintf(
'<option value="%s">%s</option>',
@pagetypes[0]->[$a]->{"id"},
encode_utf8(@pagetypes[0]->[$a]->{"label"}),
);
}
我得到了 200 个中的 10 个项目,但我就是不知道如何获得数组的长度 @pagetypes
。
我尝试了以下方法:
# 500 Server error (because of long loading?)
for ( $a = 0 ; $a <= @pagetypes[0] ; $a++ ) {
my $pagetypesLength = @pagetypes;
# Only 2 items are displayed
for ( $a = 0 ; $a <= @pagetypes ; $a++ ) {
for ( $a = 0 ; $a <= $pagetypesLength ; $a++ ) {
for ( $a = 0 ; $a <= scalar @pagetypes ; $a++ ) {
for ( $a = 0 ; $a <= length @pagetypes ; $a++ ) {
更新 3(终于可以用了):
所以我终于设法让它工作了。最终代码如下:
#!/bin/false
use strict;
use warnings;
use Encode;
use Project::Util::Api;
use vars qw(@parameters $new $mode $metainfo);
sub main
{
if ($mode ne 'EDIT') {
return;
}
my $items = _getData();
if (0 == scalar @$items) {
return "";
}
my $html = "";
# $#{$items} is last index of array reference $items
for (my $i = 0 ; $i <= $#{$items} ; $i++) {
if (defined $items->[$i]->{"id"}) {
# option selection will be automatically set by Imperia
$html .= sprintf(
'<option value="%s">%s</option>',
$items->[$i]->{"identifier"},
encode_utf8($items->[$i]->{"label"}),
);
}
}
return $html;
}
##
# Get Pagetypes from API
##
sub _getData
{
my $response = Project::Util::Api->sendRequest("/ajax/imperia/page-types/de/");
return $response->{"pageTypes"};
}
$new = main();
看起来 $pagetype 变量实际上是一个数组引用(至少看起来像 Dumper)
那么应该解决这个问题的可能是:
my $pagetype = $_;
$html .= sprintf(
'<option value="%s">%s</option>',
$pagetype->[0]->{"identifier"},
encode_utf8($pagetype->{"label"}),
);
我正在写一些 Perl 代码,我完全是个菜鸟(专攻 PHP 和 JS)。我正在从 JSON API 请求中检索一些数据,我想引用这些数据并为 select 字段构建一些 HTML-Options。但我只是不知道如何从 JSON 响应中引用值。
#!/bin/false
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use JSON;
use Encode;
use vars qw(@parameters $new $mode $metainfo);
use Data::Dumper qw(Dumper);
sub main
{
if ($mode ne 'EDIT') {
return;
}
my @pagetypes = _getPagetypes();
if (scalar @pagetypes == 0 || ! defined \@pagetypes) {
return "";
}
my $html = "";
foreach (@pagetypes) {
my $pagetype = $_;
return Dumper @pagetypes;
$html .= sprintf(
'<option value="%s">%s</option>',
$pagetype->{"identifier"},
encode_utf8($pagetype->{"label"}),
);
}
return $html;
}
##
# Get Pagetypes from API
##
sub _getPagetypes
{
my $url = sprintf(
"%s/page-types/",
$ENV{'URL'}
);
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
my $header = HTTP::Request->new(GET => $url);
my $request = HTTP::Request->new('GET', $url, $header);
my $response = $ua->request($request);
my @data = decode_json($response->content);
my @pagetypes = @data[0]->{'pageTypes'};
return @pagetypes;
}
它说 return Dumper $pagetypes;
的地方写了以下输出:
$VAR1 = [
{
'label' => 'Projektsteckbrief',
'identifier' => 'pagetype-profile'
}
];
我尝试了 $pagetype->{"label"}
和 $pagetypes[0]->{"label"}
等等...但我只是不知道如何获得标签和标识符。
更新:
我尝试手动实现页面类型,使用 main()
方法(没有 Dumper Call)效果很好:
sub _getPagetypes
{
my @pagetypes = (
{
identifier => "pagetype-profile",
label => "Projektsteckbrief",
},
);
return @pagetypes;
}
更新 2:
所以我遇到了一个新问题...它还没有完全解决问题,但是 Bl00D4NGEL 的回复还是帮了大忙!
所以我的代码现在看起来像这样:
#!/bin/false
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;
use JSON;
use Encode;
use Project::Util::Api;
use vars qw(@parameters $new $mode $metainfo);
sub main
{
if ($mode ne 'EDIT') {
return;
}
my @pagetypes = _getPagetypes();
if (scalar @pagetypes == 0 || ! defined \@pagetypes) {
return "";
}
my $html = "";
foreach my $pagetype (@pagetypes) {
# selection will be automatically set by Imperia
$html .= sprintf(
'<option value="%s">%s</option>',
$pagetype->[0]->{"identifier"},
encode_utf8($pagetype->[0]->{"label"}),
);
}
return $html;
}
##
# Get Pagetypes from API
##
sub _getPagetypes
{
my $response = Project::Util::Api->sendRequest("/ajax/imperia/page-types/de/");
my @pagetypes = $response->{"pageTypes"};
return @pagetypes;
}
$new = main();
现在的问题是只显示了一项。
所以 $pagetype
在我的 foreach 循环中看起来它仍然是包含所有项目的数组,然后 $pagetype->[0]
只给我数组中的第一个项目。
当我像这样使用 for
而不是 foreach
时:
for ( $a = 0 ; $a <= 10 ; $a++ ) {
$html .= sprintf(
'<option value="%s">%s</option>',
@pagetypes[0]->[$a]->{"id"},
encode_utf8(@pagetypes[0]->[$a]->{"label"}),
);
}
我得到了 200 个中的 10 个项目,但我就是不知道如何获得数组的长度 @pagetypes
。
我尝试了以下方法:
# 500 Server error (because of long loading?)
for ( $a = 0 ; $a <= @pagetypes[0] ; $a++ ) {
my $pagetypesLength = @pagetypes;
# Only 2 items are displayed
for ( $a = 0 ; $a <= @pagetypes ; $a++ ) {
for ( $a = 0 ; $a <= $pagetypesLength ; $a++ ) {
for ( $a = 0 ; $a <= scalar @pagetypes ; $a++ ) {
for ( $a = 0 ; $a <= length @pagetypes ; $a++ ) {
更新 3(终于可以用了):
所以我终于设法让它工作了。最终代码如下:
#!/bin/false
use strict;
use warnings;
use Encode;
use Project::Util::Api;
use vars qw(@parameters $new $mode $metainfo);
sub main
{
if ($mode ne 'EDIT') {
return;
}
my $items = _getData();
if (0 == scalar @$items) {
return "";
}
my $html = "";
# $#{$items} is last index of array reference $items
for (my $i = 0 ; $i <= $#{$items} ; $i++) {
if (defined $items->[$i]->{"id"}) {
# option selection will be automatically set by Imperia
$html .= sprintf(
'<option value="%s">%s</option>',
$items->[$i]->{"identifier"},
encode_utf8($items->[$i]->{"label"}),
);
}
}
return $html;
}
##
# Get Pagetypes from API
##
sub _getData
{
my $response = Project::Util::Api->sendRequest("/ajax/imperia/page-types/de/");
return $response->{"pageTypes"};
}
$new = main();
看起来 $pagetype 变量实际上是一个数组引用(至少看起来像 Dumper) 那么应该解决这个问题的可能是:
my $pagetype = $_;
$html .= sprintf(
'<option value="%s">%s</option>',
$pagetype->[0]->{"identifier"},
encode_utf8($pagetype->{"label"}),
);