Reputation: 1
Hello I'm retrieving data from a XMLRPC API via PERL and end up with an HASH (actually I believe the correct term here would be array within an array) which I partially want to convert into a CSV file.
As a basic overview here is what I am doing:
my $server = XMLRPC::Lite
->proxy('https://myhost/api');
my $session = $server->login(foo)
->result;
my @tempArr = $server->call(foobar)->result;
Afterwards a:
print @tempArr;
results in:
HASH(0x23c0330)
If I dump the HASH content via Data::Dumper:
print Dumper(\@tempArr);
then I receive the following structure of the array:
$VAR1 = [
{
'table' => [
[
'abc',
'def',
'ghi',
'jkl'
],
[
'abc',
'def',
'fed',
'cba'
],
],
'columns' => [
'field1',
'field2',
'field3',
'field4',
]
}
];
Now I would like to write all items from 'table' into a CSV formated file. So basically in this case:
abc,def,ghi,jkl
abc,def,fed,cba
I was playing around with Text::CSV::Slurp for a while, but didn't really understand how to handle it for arrays within arrays:
my $csv = Text::CSV::Slurp->create( input => \@tempArr);
my $file = "/path/output.csv";
open( FH, ">$file" ) || die "Couldn't open $file $!";
print FH $csv;
close FH;
I only came up with a csv file of the following content:
columns,table
ARRAY(0x23c01b0),ARRAY(0x25a944c)
Any suggestions on how to approach this issue would be appreciated. Currently I've decided to go back and read about arrays and hashes in PERL in general, as I seem to lack a lot of fundamental understanding on the matter.
Upvotes: 0
Views: 925
Reputation: 561
It seems that result() is returning a hash reference not an array, so change that line to:
my $result = $server->call(foobar)->result;
Then transform the result into the format required by Text::CSV::Slurp
my $cols = $result->{'columns'};
my $rows = $result->{'table'};
my @idx = 0 .. @$cols - 1;
my @array_of_hashes;
for my $row (@$rows) {
my %hash = map { $cols->[$_] => $row->[$_] } @idx;
push(@array_of_hashes,\%hash);
}
my $csv = Text::CSV::Slurp->create(
input => \@array_of_hashes,
field_order => $cols
);
Upvotes: 1
Reputation: 15501
This will produce your csv file directly from your data structure:
for my $arr (@{$$VAR1[0]{'table'}}) {
my $last_elem = pop(@$arr);
for my $elem (@$arr) { print("$elem,"); }
print("$last_elem\n");
}
Upvotes: 0
Reputation: 6652
Text::CSV::Slurp operates on arrayrefs of the following format (both for how it parses and for what it takes to write back to CSV:)
$VAR1 = [ { field1 => 'abc',
field2 => 'def',
field3 => 'ghi',
field4 => 'jkl',
},
{ field1 => 'abc',
field2 => 'def',
field3 => 'fed',
field4 => 'cba',
},
];
Transform your response into that type of format.
As it operates now, Text::CSV::Slurp is treating the table and columns first level keys as the data field names, then stringifying the contained arrayrefs and using them as a value.
Upvotes: 1