4

I get an error when attempting to access the contents of my JSON array.

Here is the contents of my JSON array assets.json:

[{"id":1002,"interfaces":[{"ip_addresses":[{"value":"172.16.77.239"}]}]},{"id":1003,"interfaces":[{"ip_addresses":[{"value":"192.168.0.2"}]}]}]

Here is my code

#!/usr/bin/perl

use strict;
use warnings;
use JSON::XS;
use File::Slurp;

my $json_source = "assets.json";   

my $json = read_file( $json_source ) ;
my $json_array = decode_json $json;

foreach my $item( @$json_array ) { 
    print $item->{id};
        print "\n";
    print $item->{interfaces}->{ip_addresses}->{value};
        print "\n\n";
}

I get the expected output for $item->{id} but when accessing the nested element I get the error "Not a HASH reference"

2
  • 1
    try printing it with Data::Dumper to see what your perl datastruture looks like. Commented Sep 23, 2015 at 10:37
  • 4
    $item->{interfaces}[0]{ip_addresses}[0]{value} Commented Sep 23, 2015 at 10:40

1 Answer 1

7

Data::Dumper is your friend here:

Trying this:

#!/usr/bin/env perl
use strict;
use warnings;

use JSON::XS;
use Data::Dumper;
$Data::Dumper::Indent = 1;
$Data::Dumper::Terse  = 1;


my $json_array = decode_json ( do { local $/; <DATA> } );
print Dumper $json_array;

__DATA__
[{"id":1002,"interfaces":[{"ip_addresses":[{"value":"172.16.77.239"}]}]},{"id":1003,"interfaces":[{"ip_addresses":[{"value":"192.168.0.2"}]}]}]

Gives:

[
  {
    'interfaces' => [
      {
        'ip_addresses' => [
          {
            'value' => '172.16.77.239'
          }
        ]
      }
    ],
    'id' => 1002
  },
  {
    'interfaces' => [
      {
        'ip_addresses' => [
          {
            'value' => '192.168.0.2'
          }
        ]
      }
    ],
    'id' => 1003
  }
]

Important point of note - you have nested arrays (the [] denotes array, the {} a hash).

So you can extract your thing with:

print $item->{interfaces}->[0]->{ip_addresses}->[0]->{value};

Or as friedo notes:

Note that you may omit the -> operator after the first one, so $item->{interfaces}[0]{ip_addresses}[0]{value} will also work.

Sign up to request clarification or add additional context in comments.

3 Comments

Sobrique, thank you for your fast help as always, helping my learning.
I've set the Data::Dumper options so that the output is a bit less sprawling. Please revert my edit if you wish
Note that you may omit the -> operator after the first one, so $item->{interfaces}[0]{ip_addresses}[0]{value} will also work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.