Skip to end of metadata
Go to start of metadata

Objektklasse zum Laden und Speichern von JSON-Files.

Erkennt, ob Daten geändert wurden oder nicht - speichert nur, wenn sich Daten geändert haben.

Syntax

require "$lbpbindir/libs/S4LJson.pm";

# Will send debugging to STDERR
$Stats4Lox::JSON::DEBUG = 1;
# Will send dumps (Data::Dumper) of objects to STDERR
$Stats4Lox::JSON::DUMP = 1;


my $jsonparser = Stats4Lox::JSON->new();
my $config = $jsonparser->open(filename => "/tmp/nofile.json", writeonclose => 0, readonly => 0);
$jsonparser->write();
my $current_filename = $jsonparser->filename();
$jsonparser->find($object, $condition);
$jsonparser->dump($object, $comment);


Parameter

ParameterOptionalDefaultBeschreibung
filename

JSON-Datei, die geöffnet werden soll. Existiert die Datei nicht, wird sie erzeugt.

writeonclose

x0

Wenn 0, muss explizit write aufgerufen werden. Es kann auch mehrmals write aufgerufen werden.

Wenn 1, wird im Destruktor automatisch gespeichert.

readonlyx0Wenn 1, wird niemals ein Schreibvorgang durchgeführt.

Grundsätzlich schreibt die Funktion nur, wenn tatsächlich Daten geändert wurden, auch bei explizitem Aufruf von write.

Bei writeonclose => 1 wird nicht sofort geschrieben, sondern, wenn der Destruktor aufgerufen wird, d.h. in der Regel 

  • beim Verlassen des Scopes des $jsonparser-Objekts (deswegen am besten $jsonparser im Hauptprogramm(weit oben definieren)
  • beim Beenden des Programms

Open and change JSON

#!/usr/bin/perl
use LoxBerry::System;
require "$lbpbindir/libs/S4LJson.pm";

$Stats4Lox::JSON::DEBUG = 1;
$Stats4Lox::JSON::DUMP = 1;

my $jsonparser = Stats4Lox::JSON->new();
my $config = $jsonparser->open(filename => "/tmp/nofile.json", writeonclose => 0);
if (!$config) {
	print "Error loading file\n";
} else {
	print "File loaded\n";
}

print "Version of the file: $config->{Version}\n";

# Simple values
$config->{Info} = "Write data to JSON";
$config->{Version} = $config->{Version} + 1;

# Creating 	
$config->{MINISERVER_HASH}->{1}->{Name} = "MSOG";
$config->{MINISERVER_HASH}->{2}->{Name} = "MSUG";

my @colors = ( "red", "blue", "green");
$config->{Colors} = \@colors;

my %settings = ( "ip" => "192.168.0.1",
				 "port" => "8000",
				 "protocol" => "tcp"
				);
$config->{Server} = \%settings;
				
$jsonparser->write();

JSON Result

{
   "Colors" : [
      "red",
      "blue",
      "green"
   ],
   "Info" : "Write data to JSON",
   "MINISERVERS" : {
      "1" : {
         "Name" : "MSOG"
      },
      "2" : {
         "Name" : "MSUG"
      }
   },
   "Server" : {
      "ip" : "192.168.0.1",
      "port" : "8000",
      "protocol" : "tcp"
   },
   "Version" : 1
}

Search in JSON

The module implements a find function to search for elements an hashes and arrays.

my @result = $jsonparser->find(@/%element_to_search, $condition);

ParameterDescription
@/%element_to_search

The element_to_search must be an ARRAY (@something) or a HASH (%something).

Most likely you would send an object of the readed JSON, e.g. $config->{colors}

$condition

This must be a string that contains a valid Perl if condition, that is evaluated. \$_ is the current object in the condition.

Keep an eye on string interpolation:

  • Non-escaped sequences are interpolated BEFORE of the function evaluation
  • Escaped sequences are interpolated IN the funcation evaluation

Conditions must be able to be evaluated inside an if statement. Precisely it is evaluated as if ($perl_condition).

In the $condition, the $_ is the current evaluated object of the array/hash. Therefore, in your $condition you have to escape the element with \$_ .

In an ARRAY, \$_ therefore is the value of the array.

In an HASH, \$_ is the current evaluated object.

Both datatypes return an array with a list of the keys. In an ARRAY evaluation, the returning array holds the key number (0, 1, 2 etc). In an HASH evaluation, the returning array holds the key name of the found elements.

Double-check escaping in your condition!

my $house = "green";

my $condition_doublequotes = "\$_ eq \"$house\"";  → The function evaluates $_ eq "green" → OK

my $condition_doublequotes = "\$_ eq \$house"; → The function evaluates $_ eq $house. As $house is not defined in the function, it will raise an exception.

my $condition_singlequoutes = '$_ eq "' . $house . '"';  → The function evaluates $_ eq "green" → OK

my $condition_singlequoutes = '$_ eq "$house"';  → The function evaluates $_ eq "$house". As $house is not defined in the function, it will raise an exception.



See the examples.

#!/usr/bin/perl
use LoxBerry::System;
require "$lbpbindir/libs/S4LJson.pm";

$Stats4Lox::JSON::DUMP = 1;



# Creating a hash (1, 2 are names, not array elements)
$config->{MINISERVER_HASH}->{1}->{Name} = "MSOG";
$config->{MINISERVER_HASH}->{2}->{Name} = "MSUG";

# HASH search
# Returns an array with the hash names
my @result = $jsonparser->find($config->{MINISERVER_HASH}, "\$_->{Name} eq 'MSUG'");
# Dump the result to STDERR
$jsonparser->dump(\@result, "Result of Hash search");

# ARRAY search
# Returns an array with the element indexes
my @result = $jsonparser->find($config->{Colors}, "\$_ eq 'red' or \$_ eq 'green'");
# Dump the result to STDERR
$jsonparser->dump(\@result, "Result of Array search");

  • No labels