in reply to Re: perl xml and array issue
in thread perl xml and array issue

Okay. So I've done a bit of research with ForceArray, but can't seem to make headway with this. When it comes to an item with a single entry like this:
<product> <title>widget3</title> <cost>0.50</cost> <rating>S</rating> <color>white</color> </product>
it returns empty. I have been poking around with my code, but can't seem to get ForceArray to return single item entries. I'm sooo close, yet sooo far...

Replies are listed 'Best First'.
Re^3: perl xml and array issue
by ikegami (Patriarch) on Nov 18, 2010 at 21:59 UTC

    I don't understand the question.

    If you use ForceArray => [qw( product color )],

    foreach $products (@{$file->{product}}) { print "Widget: " . $products->{title} ." \n"; print "Rating: " . $products->{rating} . "\n"; print " Cost: " . $products->{cost} . "\n"; print "Colors: " . join(', ', @{$products->{color}})."\n\n"; }

    will work for

    <shelf> <product> <title>widget3</title> <cost>0.50</cost> <rating>S</rating> <color>white</color> </product> </shelf>

    and

    <shelf> <product> <title>widget1</title> <cost>0.10</cost> <rating>B</rating> <color>red</color> <color>blue</color> <color>green</color> </product> <product> <title>widget2</title> <cost>0.25</cost> <rating>S</rating> <color>pink</color> <color>gray</color> <color>orange</color> </product> </shelf>

    and everything in between. Without ForceArray, you'd need

    sub list { if (defined(ref($_[0])) && ref($_[0]) eq 'ARRAY') { return @{ $_[0] }; } else { return $_[0]; } } foreach $products (list($file->{product})) { print "Widget: " . $products->{title} ." \n"; print "Rating: " . $products->{rating} . "\n"; print " Cost: " . $products->{cost} . "\n"; print "Colors: " . join(', ', list($products->{color}))."\n\n"; }

    So what's the problem?

      Okay. I updated the perl script as follows: prod.pl:
      use XML::Simple; $xml = new XML::Simple( ForceArray => [qw( product color )]); $file = $xml -> XMLin('./prod.xml', ); foreach $products (@{$file->{product}}) { print "Widget: " . $products->{title} ." \n"; print "Rating: " . $products->{rating} . "\n"; print " Cost: " . $products->{cost} . "\n"; print "Colors: " . (join ", ", @{$products->{color}})."\n\n"; }
      prod.xml
      <shelf> <product> <title>widget1</title> <cost>0.10</cost> <rating>B</rating> <color>red</color> <color>blue</color> <color>green</color> </product> <product> <title>widget2</title> <cost>0.25</cost> <rating>S</rating> <color>pink</color> <color>gray</color> <color>orange</color> </product> <product> <title>widget3</title> <cost>0.50</cost> <rating>S</rating> <color>white</color> </product> </shelf>
      However, output with a single item for "color" remains empty:
      Widget: widget1 Rating: B Cost: 0.10 Colors: red, blue, green Widget: widget2 Rating: S Cost: 0.25 Colors: pink, gray, orange Widget: widget3 Rating: S Cost: 0.50 Colors:
      I don't doubt that ForceArrray works, but apparently I just can't figure out the syntax (ie where to plug it in).

        Without changing anything at all, I get:

        Widget: widget1 Rating: B Cost: 0.10 Colors: red, blue, green Widget: widget2 Rating: S Cost: 0.25 Colors: pink, gray, orange Widget: widget3 Rating: S Cost: 0.50 Colors: white

        Maybe your version of XML::Simple is buggy? Maybe you're not running the script you think you are running? Maybe you're not using the XML file you think you are using?