I am trying to create a json string in perl that outputs something like this:
{"d":{"success":false, "error":"key is required"}}
I have figured out how to do it without the "d" using this example:
my %rec_hash = ('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
my $json = encode_json \%rec_hash;
print "$json\n";
but not sure what I'm suppose to do with the extra level
What you need is a hash reference:
use strict;
use warnings;
use JSON;
my $json = JSON->new;
my $data_to_json = {d=>{success=>JSON::false,error=>"key is required"}};
print $json->encode($data_to_json) . "\n";
The output is:
{"d":{"success":false,"error":"key is required"}}
Note the use of JSON::false to denote a value that the JSON module will correctly translate to false as a JSON value.
Related
I work with data from web forms in cp1251;
I need to convert hash with data to JSON
When i used
my $href = {a => "дот"};
my $str = to_json($href, {utf8 => 0});
use Data::Dumper;
print Dumper($str); # will print something like this {"a": "\x{c4}\x{ee}\x{e8}"}
i need to make JSON string without converting.
In this case helps something like this:
my $str = encode('cp1251', decode('cp1251', to_json($href, {utf8 => 0}) ));
print Dumper($str); # will print {"a": "дот"}
or
my $str = to_json($href, {utf8 => 0});
utf8::downgrade($str);
print Dumper($str); # will print {"a": "дот"}
What other right options are there to solve the problem?
You can use the encode_json function from the JSON module to generate a JSON string from a data structure in a specified encoding. For example:
use JSON qw(encode_json);
my $href = {a => "дот"};
my $str = encode_json($href, {utf8 => 0, encode_check_method => 'sv'});
print Dumper($str); # will print {"a": "дот"}
The encode_check_method option specifies the method used to check for characters that cannot be encoded in the specified encoding. The value sv checks the SVf_UTF8 flag on the scalar, which means that it will only encode characters that are not flagged as UTF-8.
Alternatively, you can use the encode function from the Encode module to encode the JSON string after it has been generated:
use Encode qw(encode);
my $href = {a => "дот"};
my $json = to_json($href, {utf8 => 0});
my $str = encode('cp1251', $json);
print Dumper($str); # will print {"a": "дот"}
This will encode the JSON string in the cp1251 encoding after it has been generated.
I'm assigning an hash %attributes to another hash %attributes_r. I need to print it as key/value pair of that hash %attributes, as mentioned below. But, while printing, why do I get this error, "Can't use string ("") as a HASH ref while "strict refs" in use at" in this line "foreach my $key1 (keys %{$attributes_r{$key}}) {" ?
My Code:
use strict;
use warnings;
our %attributes_r;
my %attributes = ('clear' => 0,
'reset' => 0,
'bold' => 1,
'dark' => 2,
'underscore' => 4,
'blink' => 5,
'reverse' => 7,
'concealed' => 8
);
for (keys %attributes) {
$attributes_r{$attributes{$_}} = $attributes{$_};
# print "$_ => $attributes_r{$attributes{$_}}\n";
}
foreach my $key (keys %attributes_r) {
foreach my $key1 (keys %{$attributes_r{$key}}) {
print "$key1 = > $attributes_r{$key}{$key1}\n";
}
}
Any help is appreciated.
With your data, this is incorrect:
foreach my $key1 (keys %{$attributes_r{$key}}) {
You are trying to dereference a value that is a string, not a reference, like the error says. If you did have a hash of hash, it might work, but you do not.
You might be trying to create a hash of hash, I'm not sure. This piece of code is very odd:
$attributes_r{$attributes{$_}} = $attributes{$_};
Here you are taking the value from the original hash and use it as a key in the other hash. For example:
$attributes_r{0} = 0;
This is not really going to accomplish anything useful. If you clarify what it is you are trying to do I might be able to suggest a fix.
Also, if you are trying to view the data structure you are creating, I suggest you print it with Data::Dumper like this:
use Data::Dumper;
...
print Dumper \%attributes_r;
I am using Perl LWP::UserAgent to get response from an API. Everything works good except one issue.
The API that i am using it returns response in JSON format. But I am getting it as string when i get the response through LWP module, Something like below.
$VAR1 = '
{"status":"success","data":[{"empid":"345232","customername":"Lee gates","dynamicid":"2342342332sd32423"},{"empid":"36.VLXP.013727..CBCL..","customername":"Lee subdirectories","dynamicid":"223f3423dsf23423423"}],"message":""}'
I did "print Dumper $response" to get the output.
One more thing, The challenge is that my client do not want to go with Perl module for JSON (use JSON::Parse 'parse_json';).
Any help would be appreciated!
You need to decode the JSON string into a Perl data structure. If your version of perl is 5.14+, JSON::PP is included in core, so nothing to install.
use warnings;
use strict;
use Data::Dumper;
use JSON::PP qw(decode_json);
my $json = '{"status":"success","data":[{"empid":"345232","customername":"Lee gates","dynamicid":"2342342332sd32423"},{"empid":"36.VLXP.013727..CBCL..","customername":"Lee subdirectories","dynamicid":"223f3423dsf23423423"}],"message":""}';
my $perl = decode_json $json;
print Dumper $perl;
Output:
$VAR1 = {
'status' => 'success',
'message' => '',
'data' => [
{
'dynamicid' => '2342342332sd32423',
'customername' => 'Lee gates',
'empid' => '345232'
},
{
'empid' => '36.VLXP.013727..CBCL..',
'customername' => 'Lee subdirectories',
'dynamicid' => '223f3423dsf23423423'
}
]
};
Using this code, I am only getting an array of values name and extension listed one after the other, how do I get a separate {name:"tom", extension:"012345"} for each hash I am creating? i.e I would like [{name:"tom", extension:"012345"}, {name:"tim", extension:"66666"}]
#!/usr/bin/perl
use strict;
use warnings;
use lib $ENV{HOME} . '/perl/lib/perl5';
use lib '/home/accounts/lib';
use Data::Dump qw(dump);
use Lib::Phonebook;
use JSON;
my $ldap = Lib::Phonebook->new();
my (#names, #numbers, $count, $name_number_count, #result);
#names = $ldap->list_telephone_account_names();
#numbers = $ldap->list_telephone_account_numbers();
$name_number_count = #names;
$count = 0;
for $count (0 .. $name_number_count - 1) {
my %hash = ( "name" => $names[$count], "extension" => $numbers[$count] );
push( #result, %hash );
}
my $json = encode_json \#result;
print dump $json;
Instead of
push( #result, %hash );
do:
push( #result, \%hash );
The original statement copies the entire hash to a list (as you discovered that becomes key, value, key, value, ...), whereas adding the backslash pushes a reference to the hash (without copying anything else) and serializing all that to JSON creates a nested structure.
I have a JSON that prints
{"d":{"success":true,"drivers":[{"FIRST_NAME":"JOHN","LAST_NAME":"SMITH"},{"FIRST_NAME":"JANE","LAST_NAME":"DOE"}]}}
The names change depending on what was found in the database. I need to push this in this format for each result resturned in the JSON:
push(#$dummy_data, {'name' => 'testname', 'key' => 'somekey-1234'});
push(#$dummy_data, {'name' => 'testname2', 'key' => 'somekey-5678'});
So for this example it would be John Smith in place of testname and Jane for testname2
How would I do this so for each first and last name in the json gets pushed in the format above?
Let's try this new game
use strict; use warnings;
use JSON::XS;
use Data::Dumper;
# creating reference to a void ARRAY
my $dummy_data = [];
# creating $json string
my $json = '{"d":{"success":true,"drivers":[{"FIRST_NAME":"JOHN","LAST_NAME":"SMITH"},{"FIRST_NAME":"JANE","LAST_NAME":"DOE"}]}}';
# converting JSON -> Perl data structure
my $perl_hash = decode_json $json;
# feeding $dummy_data ARRAY ref with a HASH
push #$dummy_data, {
name => $perl_hash->{d}->{drivers}->[0]->{FIRST_NAME},
key => $perl_hash->{d}->{drivers}->[1]->{FIRST_NAME}
};
# print what we have finally
print Dumper $dummy_data;
Output
$VAR1 = [
{
'name' => 'JOHN',
'key' => 'JANE'
}
];