From: Rob Dixon <[EMAIL PROTECTED]>
> 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. 

Ever heard of ForceArray, ForceContent and SuppressEmpty?

If a tag may be repeated ... add it to ForceArray, if you have tags 
that sometimes do and sometimes don't have attributes use 
ForceContent.

> To process the structure you have
> to check what sort of thing each value is so that you know what to do
> with it. 

No, if you set the above options right you don't.

> 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.

I'd love to see that.

> 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?

Good catch.

> 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.

Using XML::Rules you could do something like:


my $parser = XML::Rules->new(
        rules => [
                line => sub {print $_[1]->{_content}."\n" if $_[1]->{_content}; 
return},
                ...
        ]
);

If you instead wanted to have the whole address and use it somewhere 
later you could do something like:

my $parser = XML::Rules->new(
        rules => [
                line => sub {
                        return '.lines' => $_[1]->{_content}."\n" if 
$_[1]->{_content};
                        return;
                },
                address => sub {
                        chomp($_[1]->{lines});
                        $_[1]->{lines} =~ s/\n/\n\t/g;
                        return 'address' => $_[1]->{lines}
                },
                order_number => sub {
                        print "Received order number $_[1]->{id}\nFor client 
$_[1]-
>{clientname}\nAddress: $_[1]->{address}\n\n";
                },
                ...

        ]
);

Not sure this style looks very readable at first. You just specify 
what do you want to do with each tag and the stuff your handler 
returns is made available to the handler of the parent tag.

Jenda
===== [EMAIL PROTECTED] === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed 
to get drunk and croon as much as they like.
        -- Terry Pratchett in Sourcery


-- 
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