leszekdubiel has asked for the wisdom of the Perl Monks concerning the following question:
Hello Monks! If could anyone during perl-meditation put a light on the problem, then I would be grateful...
Background: there are some multi-level structured data in JSON for our internal web page. I told marketing people that the data is in JSON and they could edit that data in Notepad++. They are not happy with that. They want Excel. So I decided that I will convert JSON to Excel, they will edit Excel table, and I will read that table back to JSON data. Me and marketing people agreed to have complicated column names... -- these column names would be just JSON Paths.
So I need to read JSON data, and emit pairs -- JSON path and value under this path. Here is the program to write such data.
What is my question? Where do I need help? Is there a simpler way of doing such conversion JSON --> path/values? How to tell Perl to dive into JSON and find all simple data (scalars...) and return paths and values of them...
#!/usr/bin/perl -CSDA use utf8; use Modern::Perl qw{2019}; use JSON; use Data::Dumper; sub extract_paths_values { my ($cur_node, $top_path, $put_here) = @_; $top_path //= "\$"; $put_here //= {}; if (ref $cur_node eq "HASH") { extract_paths_values($$cur_node{$_}, "$top_path\['$_'\]", $put +_here) for keys %$cur_node; } elsif (ref $cur_node eq "ARRAY") { extract_paths_values($$cur_node[$_], "$top_path\[$_\]", $put_h +ere) for 0 .. @$cur_node - 1; } else { $$put_here{$top_path} = $cur_node; } return $put_here; } my $json = ' { "store" : { "files": [ ["alfa.txt", "about first letter in greek"], ["model.dxf", "for architects"], ["errors.txt", "no need for that normally"], ], "book" : [ { "category" : "reference", "title" : "Sayings of the Century", "author" : "Nigel Rees", "price" : 8.95 }, { "author" : "Evelyn Waugh", "title" : "Sword of Honour", "price" : 12.99, "category" : "fiction" }, ], "bicycle" : [ { "price" : 19.95, "color" : "red" } ] }, "status" : { "curr" : "Okey", "code" : 232, } } '; my $paths_values = extract_paths_values( JSON->new->relaxed->decode($json) ); print "$_ ~~~~> $$paths_values{$_}\n" for sort keys %$paths_values; print "Hurray! Done that \n";
result:
$['status']['code'] ~~~~> 232 $['status']['curr'] ~~~~> Okey $['store']['bicycle'][0]['color'] ~~~~> red $['store']['bicycle'][0]['price'] ~~~~> 19.95 $['store']['book'][0]['author'] ~~~~> Nigel Rees $['store']['book'][0]['category'] ~~~~> reference $['store']['book'][0]['price'] ~~~~> 8.95 $['store']['book'][0]['title'] ~~~~> Sayings of the Century $['store']['book'][1]['author'] ~~~~> Evelyn Waugh $['store']['book'][1]['category'] ~~~~> fiction $['store']['book'][1]['price'] ~~~~> 12.99 $['store']['book'][1]['title'] ~~~~> Sword of Honour $['store']['files'][0][0] ~~~~> alfa.txt $['store']['files'][0][1] ~~~~> about first letter in greek $['store']['files'][1][0] ~~~~> model.dxf $['store']['files'][1][1] ~~~~> for architects $['store']['files'][2][0] ~~~~> errors.txt $['store']['files'][2][1] ~~~~> no need for that normally Hurray! Done that :)
|
---|