The "sort and group" principle shown in other nodes is sound, but it makes most sense when you're only looking at arrays.

Here's an implementation that uses both arrays and hashes, to make an internal perl representation of the data that corresponds more closely (compared to a just arrays) to what you need to output. The output loop therefore becomes a bit simpler.

#!/usr/bin/perl use strict; use warnings; #use Text::CSV_XS; my $csv = CSV_Stub->new(); my $file = ''; if (defined $ARGV[0]) { $file = $ARGV[0]; } open(my $data, '<', $file) or die "Could not open '$file'\n"; # Get raw textual input: an array of strings my @input = <$data>; close $data; # Convert CSV text into an array of arrays @input = map { $csv->parse($_); [$csv->fields()] } @input; # Use input data to build a data structure which maps (fairly closely) + onto what we want to output # A hash of arrays # Key = order id # Value = the array of items in that order my %internalRepresentation; foreach my $input (@input) { push @{$internalRepresentation{$input->[0]}}, { name => $input->[1], itemId => $input->[2], itemDesc => $input->[3], price => $input->[4], } } # For each order we want to output: foreach my $orderNumber (keys %internalRepresentation) { open (OUTFILE, "> output/$orderNumber.xml") or die $! . " can't op +en the file\n"; print OUTFILE "<order>\n"; print OUTFILE " <order_id>$orderNumber</order_id>\n"; print OUTFILE " <name>$internalRepresentation{$orderNumber}->[0] +->{name}</name>\n"; # For each item in the order: foreach my $item (@{$internalRepresentation{$orderNumber}}) { print OUTFILE " <item>\n"; print OUTFILE " <item_id>$item->{itemId}</item_id>\n"; print OUTFILE " <item_desc>$item->{itemDesc}</item_desc>\n +"; print OUTFILE " <price>$item->{price}</price>\n"; print OUTFILE " </item>\n"; } print OUTFILE "</order>\n"; close OUTFILE; } package CSV_Stub; sub new { return bless {}, shift; } sub parse { my $self = shift; my $line = shift; chomp $line; $self->{currentFields} = [split ",", $line]; return 1; } sub fields { my $self = shift; return @{$self->{currentFields}}; }
Note that I stubbed out the CSV processing module you're using. My CSV parsing is a bit rougher around the edges :-)

Also note that in the input, the order name is repeated for each item in the order. In the internal representation, it's still repeated. Hence, in the output loop, it gets the name for the order from the first item in the order. Ie:

->[0]
is used when it outputs the name. If you were seeking perfection, you'd need to avoids this redundancy in the internal representation, by only storing the name once per order. That means that the structure of the data would need to change to accommodate it. I'll leave that option to you :-)

--
use JAPH;
print JAPH::asString();


In reply to Re^3: merging .csv text input based on matching column field values in multiple rows by wol
in thread merging .csv text input based on matching column field values in multiple rows by abrg

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.