Beginner wrote:
On 4 Dec 2006 at 8:47, Tom Phoenix wrote:

On 12/4/06, Beginner <[EMAIL PROTECTED]> wrote:

        print "found $ref->{'order_number'}\n";
I get "found HASH(0xacacfe8)".
That's a reference to a hash. It sounds as if you might want to ask
the question "Is that hash empty or not?", which the keys() function
can answer:

    if (keys %{ $ref->{'order_number'} }) {
      print "There's something in the order number hash.\n";
    } else {
      print "Hash is empty.\n";
    }

If you use keys() in a list context, you'll get a list of the keys of
the hash. Hope this helps!

Yes that worked fine. Thanx. Within the same xml file structure I
also have

'address' => {
  'line' =>   [
    {
      'line' =>     'STARLING ROOFING'
    },
    {
      'line' =>     '338 EUSTON ROAD'
    },
    {
      'line' =>     'DUBLIN'
    },
    {
      'line' =>     {}
    },
    {
      'line' =>     {}
    },
    {
      'line' =>     {}
    },
    {
      'line' =>     'DB1 3BH'
    }
  ]
},

Using that principle I thought I could do

if (keys(%{$ref->{'address'}{line}[$j]->{line}}) ) {
  print "Found ", $ref->{'address'}{line}[$j]->{line}, "\n";

But I am getting an error:
Can't use string ("STARLING ROOFING") as a HASH ref while "strict
refs" in use.

Am I accessing the values incorrectly?

Hi Dermot

You get some fun stuff to do don't you!

To be honest I wouldn't go near XML::Simple because of exactly the problems
you're experiencing. It turns XML into a nested hash structure where the hash
values can be a hash reference, an array reference or a simple string scalar. To
process the structure you have to check what sort of thing each value is so that
you know what to do with it. The 'simple' seems to apply to the module itself,
and the consequence is that the code which uses it has to be more complex. I
would recommend XML::Twig or XML::TreeBuilder over XML::Simple which, while they
may seem complex at first glance, will result more concise code.

As for the problem in hand, I can't get XML::Simple to generate a structure like
you've shown. My guess would have been

<dataset>
 <order_number>
   <address>
     <line>STARLING ROOFING</line>
     <line>338 EUSTON ROAD</line>
     <line>DUBLIN</line>
     <line></line>
     <line></line>
     <line></line>
     <line>DB1 3BH</line>
   </address>
 </order_number>
</dataset>

but that produces a hash element like this:

'line' => [
 'STARLING ROOFING',
 '338 EUSTON ROAD',
 'DUBLIN',
 {},
 {},
 {},
 'DB1 3BH'
]

and I couldn't find a set of module options to make it look like yours. Could
you enlighten me please?

To process your structure you need something like

foreach my $line (@{$ref->{address}{line}}) {
 my $text = $line->{line};
 print $text unless ref $text;
 print "\n";
}

but this relies on prior knowledge that $ref->{address}{line} is an array
reference and that the address line values are hash references if the line was
blank. (Jenda's suggestion of using the SuppressEmpty option would help here.)

Finally, here's the code to use XML::Twig print the text of the <line> elements
of my XML above:

my $tw = XML::Twig->new;
$tw->parse($xml);

foreach my $order ($tw->get_xpath('/dataset/order_number')) {
 foreach ($order->get_xpath('address/line')) {
   print $_->text, "\n";
 }
}

which I think is hugely preferable. There are other ways to extract the
information from the parsed data if you're not comfortable with XPath.

HTH,

Rob



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


Reply via email to