Metainformationen zur Seite
Modul Stats4Lox::JSON
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
Parameter | Optional | Default | Beschreibung |
filename | JSON-Datei, die geöffnet werden soll. Existiert die Datei nicht, wird sie erzeugt. | ||
writeonclose | x | 0 | Wenn 0, muss explizit write aufgerufen werden. Es kann auch mehrmals write aufgerufen werden. Wenn 1, wird im Destruktor automatisch gespeichert. |
readonly | x | 0 | Wenn 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);
Parameter | Description |
@/%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");