Как ссылаться на данные в массиве / хэше из ответа JSON в Perl - PullRequest
0 голосов
/ 27 мая 2019

Я пишу некоторый код на Perl и я совершенно нуб (специализируюсь на PHP и JS).Я извлекаю некоторые данные из запроса JSON API и хочу сослаться на эти данные и создать некоторые HTML-параметры для поля выбора.Но я просто не могу понять, как ссылаться на значения из JSON Response.

#!/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):

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"}),
    );
}

Я получаю 10 предметов по 200, но я просто не могу понять, как получить длину массива @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();

1 Ответ

1 голос
/ 27 мая 2019

Похоже, что переменная $ pagetype на самом деле является ссылкой на массив (если посмотреть на Dumper, по крайней мере, он выглядит так) Так что, вероятно, следует решить эту проблему:

    my $pagetype = $_;

    $html .= sprintf(

    '<option value="%s">%s</option>',
    $pagetype->[0]->{"identifier"},
    encode_utf8($pagetype->{"label"}),

    );

...