Loading ...
Sorry, an error occurred while loading the content.

Re: [PBML] XML parsing

Expand Messages
  • Mark Reed
    If I understand, your only having problems when $type is an array correct? In the case that $type is an array, The array will contain hash references. Each
    Message 1 of 3 , Jun 30, 2003
    • 0 Attachment
      If I understand, your only having problems when $type
      is an array correct?

      In the case that $type is an array, The array will
      contain hash references. Each hash will have a key of
      'name', and a 'value' of the directory.

      I think this is the loop your looking for:

      if ($type eq "ARRAY") {
      foreach my $hash (@$dirs) {
      print "$$hash{name}\n";
      }
      }

      Or:
      if ($type eq "ARRAY") {
      foreach my $hash (@$dirs) {
      foreach my $value ( values %$hash ) {
      print "$value \n";
      }
      }
      }




      --- greg.hering@... wrote:
      > Hey! Request for XML (really probably basic perl
      > datatypes) understanding.
      >
      > This has the short data, short code and short
      > output, but altogether it gets long. I'll ask the
      > question first.
      >
      > I'm parsing a file formatted as XML, using
      > XML::Simple, that tells the names of directories on
      > a host.
      >
      > If the host has one directory, then the type
      > returned in my code is a HASH. If it has two then
      > the type is ARRAY.
      >
      > In trying to figure out the data structure, I used
      > Dumper. My code says the loop is an array of arrays
      > (iterating with a foreach) but it looks like an
      > array of hashes and I can't figure out how to access
      > it in a loop.
      >
      > In the code below, you can see I thought the control
      > variable in the 'foreach' would iterate over the
      > elements of the array and return me a hash. I can
      > hard-code '$config->{host}->{dir}[0]->{name}' to get
      > what I want, but I want to understand what is
      > happening well enough to do it in a loop.
      >
      > In the loop, $dir says it is an ARRAY (using ref())
      > but
      > print '$dir[0]' . " is $dir[0]"; #error
      > is an error, as is
      > print "$dir->{name}\n"; #error
      >
      > Only
      > {dir}[0]->{name} # works
      >
      > is valid, but that's not suitable for a loop.
      >
      > Here's my sample data file:
      >
      > <?xml version='1.0' encoding='ISO-8859-1' ?>
      > <!DOCTYPE MyHostFormat>
      > <configuration>
      > <host name="forth">
      > <dir name="/export/DATA" /> ## add more dirs
      > here
      > <dir name="/export/DATATWO" />
      > </host>
      > </configuration>
      >
      >
      > Here's my test program:
      >
      > use XML::Simple qw(:strict);
      > use Data::Dumper;
      > use strict;
      >
      > my $xs = new XML::Simple('keyattr' => 'host',
      > ForceArray => 0);
      > my $config = $xs->XMLin("/tmp/hostconfig.xml");
      >
      > print Dumper($config);
      >
      > #assign a reference part way down - to make life
      > easier.
      > my $dirs = $config->{host}->{dir};
      >
      > my $type = ref($dirs) || $dirs;
      >
      > if ($type eq "HASH") {
      > print '$config->{host}->{dir}' . " is a HASH
      > type\n";
      > print '$config->{host}->{dir}->{name}' . " and
      > is: $config->{host}->{dir}->{name}\n";
      > }
      >
      > if ($type eq "ARRAY") {
      > print '$config->{host}->{dir}' . " is an ARRAY
      > type\n";
      >
      > # would like the size of the array but this
      > doesn't work...
      > # print 'size of $config->{host}->{dir}' . " is
      > $#config->{host}->{dir}\n";
      > # nor does
      > print 'size of $config->{host}->{dir}' . " is
      > $#dirs\n";
      >
      > foreach my $dir ($dirs)
      > { # dir should be an
      > array of hashes
      > my $type = ref($dir);
      > printf '$config->{host}->{dir}[?]' . " type is
      > %s\n", $type;
      > print "$dir\n";
      > # print "$dir->{name}\n"; gives error because
      > $dir isn't a hash.
      > }
      > }
      >
      >
      >
      > --------------- The output with one host directory:
      > ----------------
      >
      > > test.pl
      > $VAR1 = {
      > 'host' => {
      > 'name' => 'forth',
      > 'dir' => {
      > 'name' =>
      > '/export/DATA'
      > }
      > }
      > };
      > $config->{host}->{dir} is a HASH type
      > >
      >
      > --------------- The output with two host
      > directories: ----------------
      >
      > > test.pl
      > $VAR1 = {
      > 'host' => {
      > 'name' => 'forth',
      > 'dir' => [
      > {
      > 'name' =>
      > '/export/DATA'
      > },
      > {
      > 'name' =>
      > '/export/DATATWO'
      > }
      > ]
      > }
      > };
      > $config->{host}->{dir} is an ARRAY type
      > $config->{host}->{dir}[?] type is ARRAY
      > ARRAY(0x6bcc78)
      >
      > If I print the iterator in the foreach loop it says
      > an array is next:
      > printf '$config->{host}->{dir}[?]' . " type is
      > %s\n", $type;
      >
      > i.e.
      > print "$dir\n"; #the control variable from
      > foreach
      > says
      > ARRAY(0x6bcc78)
      >
      > I thought the control variable in the 'foreach'
      > would iterate over the elements of the array and
      > return me a hash.
      >
      > If I print this I get the value:
      > printf '$config->{host}->{dir}[?]' . " value is
      > %s\n", $config->{host}->{dir}[0]->{name};
      >
      > but I can't figure out how to do it in a loop.
      >
      >
      > Thanks,
      >
      > Greg
      >
      >
      >
      > Gregory L. Hering
      > (256) 722-6420
      > 4807 Bradford Dr
      > Benchmark Electronics, Inc.
      > Huntsville, Al 35805
      >
      >
      >


      __________________________________
      Do you Yahoo!?
      SBC Yahoo! DSL - Now only $29.95 per month!
      http://sbc.yahoo.com
    • greg.hering@bench.com
      You is super-cool and you ain t no fool! Or, to be more precise, your response to my inquiry was insightful and accurate. It seems that the second form
      Message 2 of 3 , Jul 1 9:28 AM
      • 0 Attachment
        You is super-cool and you ain't no fool!

        Or, to be more precise, your response to my inquiry was insightful and accurate.
        It seems that the second form produces the same results, but is more 'anonymous' because you don't have to know the name of the hash key.

        Thanks!

        My Homework Assignment: Delving into the @$ and $$ signs of the world.

        Gregory L. Hering
        (256) 722-6420
        4807 Bradford Dr
        Benchmark Electronics, Inc.
        Huntsville, Al 35805

        -----Original Message-----
        From: Mark Reed [mailto:intensity_guy@...]
        Sent: Monday, June 30, 2003 11:56 PM
        To: perl-beginner@yahoogroups.com
        Subject: Re: [PBML] XML parsing

        If I understand, your only having problems when $type
        is an array correct?

        In the case that $type is an array, The array will
        contain hash references. Each hash will have a key of
        'name', and a 'value' of the directory.

        I think this is the loop your looking for:

        if ($type eq "ARRAY") {
                foreach my $hash (@$dirs) {
                        print "$$hash{name}\n";
                }
        }

        Or:
        if ($type eq "ARRAY") {
                foreach my $hash (@$dirs) {
                        foreach my $value ( values %$hash ) {
                                print "$value \n";
                        }
                }
        }

        <SNIPPed>
      Your message has been successfully submitted and would be delivered to recipients shortly.