Gauthier, Dave wrote:
Hi:

I'm trying to construct something like a nested for loop structuire to
read the data out of an XML file using XML::Simple.
Here's the sample xml...

<?xml version='1.0' encoding='ISO-8859-1' ?>

<ARBORINFO NAME="Info about Trees">

<FOREST NAME="olympic">

  <TREE NAME="spruce">

    <DIAM_HEIGHT>4.0,70.0</DIAM_HEIGHT>

    <DIAM_HEIGHT>4.1,70.1</DIAM_HEIGHT>

    <DIAM_HEIGHT>4.2,70.2</DIAM_HEIGHT>

  </TREE>

  <TREE NAME="redwood">

    <DIAM_HEIGHT>5.0,80.0</DIAM_HEIGHT>

    <DIAM_HEIGHT>5.1,80.1</DIAM_HEIGHT>

    <DIAM_HEIGHT>5.2,80.2</DIAM_HEIGHT>

    <DIAM_HEIGHT>5.3,80.3</DIAM_HEIGHT>

  </TREE>

  <TREE NAME="pine">

    <DIAM_HEIGHT>3.0,60.0</DIAM_HEIGHT>

    <DIAM_HEIGHT>3.1,60.1</DIAM_HEIGHT>

  </TREE>

</FOREST>

<FOREST NAME="acadia">

  <TREE NAME="birch">

    <DIAM_HEIGHT>1.0,30.0</DIAM_HEIGHT>

    <DIAM_HEIGHT>1.1,30.1</DIAM_HEIGHT>

    <DIAM_HEIGHT>1.2,30.2</DIAM_HEIGHT>

    <DIAM_HEIGHT>1.3,30.3</DIAM_HEIGHT>

    <DIAM_HEIGHT>1.4,30.4</DIAM_HEIGHT>

    <DIAM_HEIGHT>1.5,30.5</DIAM_HEIGHT>

  </TREE>

  <TREE NAME="oak">

    <DIAM_HEIGHT>3.0,50.0</DIAM_HEIGHT>

    <DIAM_HEIGHT>3.1,50.1</DIAM_HEIGHT>

    <DIAM_HEIGHT>3.2,50.2</DIAM_HEIGHT>

    <DIAM_HEIGHT>3.3,50.3</DIAM_HEIGHT>

  </TREE>

  <TREE NAME="maple">

    <DIAM_HEIGHT>2.0,40.0</DIAM_HEIGHT>

  </TREE>

</FOREST>

<FOREST NAME="caddo">

  <TREE NAME="scrb">

    <DIAM_HEIGHT>0.5,30.0</DIAM_HEIGHT>

  </TREE>

</FOREST>

</ARBORINFO>

And here's the code that I got to partially work....

use XML::Simple;

$xml = new XML::Simple;

$phl = $xml->XMLin("./small.xml");

for(my $x=0;$x<$#{$phl->{FOREST}}+1;$x++)

  {

  $fname = $phl->{FOREST}[$x]{NAME};

  $z = 0;

  print "forest: $fname \n";

  for(my $y=0;$y<$#{$phl->{FOREST}[$x]{TREE}}+1;$y++)

    {

    $tname = $phl->{FOREST}[$x]{TREE}[$y]{NAME};

    print "  tree: $tname\n";

    for(my $z=0;$z<$#{$phl->{FOREST}[$x]{TREE}[$y]{DIAM_HEIGHT}}+1;$z++)

      {

      $tdata = $phl->{FOREST}[$x]{TREE}[$y]{DIAM_HEIGHT}[$z];

      print "      tdata: $tdata\n";

      }

    }

  }

And this is what I got...

forest: olympic

  tree: spruce

      tdata: 4.0,70.0

      tdata: 4.1,70.1

      tdata: 4.2,70.2

  tree: redwood

      tdata: 5.0,80.0

      tdata: 5.1,80.1

      tdata: 5.2,80.2

      tdata: 5.3,80.3

  tree: pine

      tdata: 3.0,60.0

      tdata: 3.1,60.1

forest: acadia

  tree: birch

      tdata: 1.0,30.0

      tdata: 1.1,30.1

      tdata: 1.2,30.2

      tdata: 1.3,30.3

      tdata: 1.4,30.4

      tdata: 1.5,30.5

  tree: oak

      tdata: 3.0,50.0

      tdata: 3.1,50.1

      tdata: 3.2,50.2

      tdata: 3.3,50.3

  tree: maple

forest: caddo

Not an ARRAY reference at tryxml.pl line 12.

2 things to note....

1) It didn't pick up on the sole "maple" tree in "acadia"

2) It outright croaked when it tried to reference the sole tree in
"caddo" as an array.

I'm wide open as to suggestions on how to accomplish this.  If foreach
can be used somehow, I'm wide open to that.

First of all, put

 use strict;
 use warnings;

at the beginning of your code and declare all your variables with 'my'.
This will help you avoid most of the common mistakes.

Your error occurs because forest 'caddo' contains only a single tree
and is represented by XML::Simple as a single anonymous hash instead
of an array of hashes like the others. To fix it change your parsing
line to

 my $phl = $xml->XMLin('./small.xml', ForceArray => 1);

which will put this hash into an array just like the others.

HTH,

Rob

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to