Search code examples
jsonperl

Perl what is the best way to check if an object defined, missing or null within JSON


I have a JSON file below and I want to check 3 states

Within the array "categories" I have another array "children" which is currently null

How can I do to know

  1. if children array is null ?
  2. if children array is defined and contain at least one data ?
  3. if children array is completely missing from the JSON whereas I was expecting to be here

Here below the JSON file

{
  "id": "Store::REZZ",
  "name": "Rezz",
  "categories": [
    {
      "id": "Category::0556",
      "name": "Cinéma",
      "children": []
    },
    {
      "id": "Category::0557",
      "name": "Séries",
      "children": []
    }
  ],
  "images": [
    {
      "format": "logo",
      "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/1920px-Google_2015_logo.svg.png",
      "withTitle": false
    }
  ],
  "type": "PLAY"
}

I tried something but I can manage only the case 1. for others cases I have an "Not a Hash reference" error message

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use JSON qw( decode_json );
use JSON qw( from_json );

# JSON file 
my $json_f = '/home/test';

# JSON text
my $json_text = do {
        open (TOP, "<", $json_f);
        local $/;
        <TOP>
};

my $data = from_json($json_text);

my @tags = @{ $data->{"categories"}{"children"} };
if (@tags) { 
    foreach (@tags) {
        say $_->{"name"};
        say "1. array is ok and contains data";
    }   
} elsif (@tags == 0) {
    say "3. array is empty";
} else {
    say "2. array is missing";
}

__END__

Solution

  • Data::Dumper will let you visualize the perl data structure the JSON is converted to. In your example,

    $VAR1 = {
              'images' => [
                            {
                              'withTitle' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
                              'url' => 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/1920px-Google_2015_logo.svg.png',
                              'format' => 'logo'
                            }
                          ],
              'id' => 'Store::REZZ',
              'name' => 'Rezz',
              'categories' => [
                                {
                                  'children' => [],
                                  'id' => 'Category::0556',
                                  'name' => "Cin\x{e9}ma"
                                },
                                {
                                  'id' => 'Category::0557',
                                  'name' => "S\x{e9}ries",
                                  'children' => []
                                }
                              ],
              'type' => 'PLAY'
            };
    

    As you can see from this, $data->{"categories"} is an arrayref of hashrefs, not a hashref itself.

    You can iterate over its elements:

    foreach my $cat (@{$data->{categories}}) {
        if (!exists $cat->{children}) {
          # No children element
        } elsif (@{$cat->{children}} == 0) {
          # Empty array
        } else {
          # Has at least element in the array
        }
    }