Я работаю над кодом для извлечения данных, хранящихся в формате JSON, с веб-страницы. Данные JSON извлекаются и правильно декодируются в хэш.
Структура данных JSON очень сложна, я написал некоторый вспомогательный код / функцию, которая «пересекает» хеш и помогает найти «индекс» (местоположение) значения, интересующего хеш.
Функция 'find' возвращает 'index' (местоположение) данных в хэше, которые хранятся в переменной.
Я пытаюсь использовать эту переменную (сохраненный 'index') в другомопераций, но пока безуспешно.
Пожалуйста, посмотрите включенный простой демонстрационный код для объяснения проблемы.
Спасибо, Белый Медведь
use strict;
use warnings;
use JSON qw(decode_json);
my $index;
my $slice;
my $data = decode_json( join '', <DATA> );
printf "TITLE: %-15s TIME: %5s TIMES: %5s FAVORITE: %s\n",
$data->{playList}[1]{title},
$data->{playList}[1]{time},
$data->{playList}[1]{played},
$data->{playList}[1]{favorite} ? "yes" : "no";
$index = '{playList}[1]';
$slice = $data{$index}; # does not pass 'use strict' compilation error
$slice = $data->{$index}; # empty slice
$slice = $data->$index; # Can't call method "{playList}[1]" on unblessed reference at
printf "TITLE: %-15s TIME: %5s TIMES: %5s FAVORITE: %s\n",
$slice->{title},
$slice->{time},
$slice->{played},
$slice->{favorite} ? "yes" : "no";
__DATA__
{
"playList": [
{
"title": "Song name 1",
"time": "3:25",
"played": "240",
"favorite": "1"
},
{
"title": "Song name 2",
"time": "4:12",
"played": "30",
"favorite": "0"
},
{
"title": "Song name 3",
"time": "2:56",
"played": "85",
"favorite": "0"
}
]
}
Я ожидаю, чтополучить доступ к данным, используя «индекс», хранящийся в переменной, но я не смог найти способ достичь этого результата. Подробности см. В комментариях к коду.
ПРИМЕЧАНИЕ. В реальной жизни индекс выглядит следующим образом:
my $index = "{contents}{twoColumnBrowseResultsRenderer}{tabs}[0]{tabRenderer}{content}{sectionListRenderer}{contents}[0]{itemSectionRenderer}{contents}[0]{playlistVideoListRenderer}{contents}[0]{playlistVideoRenderer}{title}{accessibility}{accessibilityData}{label}";
РЕШЕНИЕ:
Я хотел бы расширить my' спасибо ' Хокону Огланду и Лордамире за предложенное решение
use Data::Diver qw/Dive/; # or Data::DPath, etc
# Capture web page, extract data JSON, convert to hash, assign hash ref to $data
my $data = ...;
# Find index/location in the hash
#my $index = find($data, $value);
my $index = "{contents}{twoColumnBrowseResultsRenderer}{tabs}[0]{tabRenderer}{content}{sectionListRenderer}{contents}[0]{itemSectionRenderer}{contents}[0]{playlistVideoListRenderer}{contents}[0]{playlistVideoRenderer}{title}{accessibility}{accessibilityData}{label}";
$index =~ s/[{\[]//g; # throw away opening brackets
my @index = split /[}\]]/, $index; # split into array on closing brackets
pop @index for 1..8 # 8 levels to back up to
my $slice = Dive( $data, @index ); # extract hash slice of interest
# extract playlist
my $playlist = $slice->{playlistVideoListRenderer}{contents};
# go through playlist and extract information of our interest
foreach ( @$playlist ) {
my $video = $_->{playlistVideoRenderer};
printf "%s %8s %s\n",
$video->{videoId},
$video->{lengthText}{simpleText},
$video->{title}{simpleText};
}
Они оба направили меня на use Data::Dive
с помощью этого модуля, который я могу сделать создайте резервную копию нескольких уровней из глубины хэша и извлеките срез , представляющий интерес.
Выяснилось, что при использовании этого модуля индекс в виде массива с ним легче работать. Из-за этого фактора я изменю мою функцию поиска, чтобы вернуть индекс массив .