3

I have to write a Perl script to convert an XML file into a CSV file. I've already written something simple in one context, and need to enhance it for a different dataset, and can't quite figure out what to do.

I'm using XML::Simple.

Here is one record of the data:

<custom-objects xmlns="http://www.demandware.com/xml/impex/customobject/2006-10-31">
    <custom-object type-id="emailBackInStockHistory" object-id="bczCAiaag0APcaaacLsvpJRmzW">
        <object-attribute attribute-id="email">some@email.com</object-attribute>
        <object-attribute attribute-id="emailSentAt">2010-04-10T09:00:01.000+0000</object-attribute>
        <object-attribute attribute-id="productID">someprodid</object-attribute>
        <object-attribute attribute-id="requestedAt">2010-04-09T10:07:54.000+0000</object-attribute>
        <object-attribute attribute-id="siteID">someSITEid</object-attribute>
    </custom-object>
</custom-objects>

Using the Data::Dumper module I see that the data is parsed as this:

'custom-object' => [
    {
        'type-id'          => 'emailBackInStockHistory',
        'object-id'        => 'bczCAiaag0APcaaacLsvpJRmzW',
        'object-attribute' => [
            {
                'attribute-id' => 'email',
                'content'      => 'some@email.com'
            },
            {
                'attribute-id' => 'emailSentAt',
                'content'      => '2010-04-10T09:00:01.000+0000'
            },
            {
                'attribute-id' => 'productID',
                'content'      => 'someprodid'
            },
            {
                'attribute-id' => 'requestedAt',
                'content'      => '2010-04-09T10:07:54.000+0000'
            },
            {
                'attribute-id' => 'siteID',
                'content'      => 'someSITEid'
            }
        ]
    },

Here is some code that I've tried to use to perform this export:

foreach $o (@{$data->{'custom-object'}}) {
    print $o->{'type-id'},   ",";
    print $o->{'object-id'}, ",";
    print $o->{'custom-object'}->{'object-attribute'}->{'email'}, ",";
    print "\n";

The type-id and object-id attributes get output properly, but I can't figure out how to print the data from the object-attribute reference.

daxim
  • 39,270
  • 4
  • 65
  • 132
Scott Wood
  • 1,077
  • 3
  • 18
  • 34

1 Answers1

2

You need to iterate over your object-attribute array-ref like your doing with the custom-object array-ref. Also have a look at Text::CSV for a more robust way of creating csv files.

foreach my $obj ( @{ $data->{'custom-object'} } ) {
    print $obj->{'type-id'}, ",";
    print $obj->{'object-id'}, ",";
    foreach my $attr ( @{ $obj->{'object-attribute'} } ) {
        if ( $attr->{'attribute-id'} eq 'email' ) {
            print $attr->{'content'}, ",";
        }
    }
    print "\n";
}
CoffeeMonster
  • 2,160
  • 4
  • 20
  • 34
  • Thanks very much. I actually cut out of the original code the section in which I tried to do this, doubtless incorrectly. But this code is not getting into the object-attribute. I tried throwing in a little print "x" in the middle loop to test whether the code was ever getting into the loop. The code didn't print out. – Scott Wood Jun 26 '12 at 18:36
  • This was a bug in my soln now fixed. Also make sure you force those items into arrays with XML::Simple like `my $data = XMLin( $xml, ForceArray => [ 'custom-object', 'object-attribute' ] );` – CoffeeMonster Jun 26 '12 at 21:57