From: Rob Dixon <[EMAIL PROTECTED]>
> Jenda Krynicky wrote:
> > 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.
> 
> Sure, if you set all those options you get all hash values being
> anonymous arrays (or text strings) and all array elements being
> anonymous hashes. But accessing all this gets ugly IMO. Using the XML
> sample in my previous post I have to write:
> 
> my $ref = XMLin($xml,
>    ForceArray => 1,
>    ForceContent => 1,
>    SuppressEmpty => '',
> );
> 
> my @address = @{$ref->{order_number}[0]{address}[0]{line}};
> foreach (@address) {
>    if (ref) {
>      print $_->{content};
>    }
>    print "\n";
> }

ForceArray accepts a list of tags so you can arraify(tm) just the 
tags that may be repeated. So in this case you'd most likely

        ForceArray => [qw(order_number line)],

and then

foreach my $order (@{$res->{order_number}}) {
        # do something
        foreach my $line (@{$order->{address}{line}}) {
                ...
        }
        ...
}
 
> And you still need to check whether the content is a hash reference as
> there's also a problem with ForceContent and SuppressEmpty. If you
> enable both as above then empty content is stored as just a null
> string '' instead of { 'content' => '' }.

As soon as I finaly find some spare time I'll create and submit a 
patch that allow the ForceContent to accept list of tags just like 
the ForceArray does so that you only get the { 'content' => '' } for 
the tags that actually do have some optional attributes.
 
> Finally, because XML::Simple stores its data in hashes it can't
> preserve the document order of elements, and all those with the same
> tag must be grouped together. Consider:
> 
> <locations>
>    <name>Jenda</name>
>    <country>Czechoslovakia</country>
>    <name>Rob</name>
>    <town>Shrewsbury</town>
>    <country>England</country>
>    <postcode>SY1 1XB</postcode>
>    <name>Dermot</name>
>    <postcode>W9 3RB</postcode>
> </locations>
> 
> which isn't a nice use of XML I agree but I have had to work with
> worse. 

Well, incorrectly designed XML forces us to jump through hoops no 
matter what we use. Often you do not care about the order of tags and 
in that case keeping it is just a waste of memory or time (or both). 

> Parsing this with XML::Simple leaves us with
> 
> {
>    'country' => [
>      { 'content' => 'Czechoslovakia' },
>      { 'content' => 'England' }
>    ],
>    'name' => [
>      { 'content' => 'Jenda' },
>      { 'content' => 'Rob' },
>      { 'content' => 'Dermot' }
>    ],
>    'town' => [
>      { 'content' => 'Shrewsbury' }
>    ],
>    'postcode' => [
>      { 'content' => 'SY1 1XB' },
>      { 'content' => 'W9 3RB' }
>    ]
> }
> 
> which is of little use.

Agreed

> All in all I prefer to avoid XML::Simple, but if it works for you then
> of course that's fine.
> 
> Rob

Sure :-)
In new stuff I'll most likely use XML::Rules since it fits my twisted 
brain best (I designed it to fit), but for lots of things XML::Simple 
is IMHO the right tool.

BTW, this http://xmltwig.com/article/index_wtr.html may be of 
interest to people here. There are some comparisons and examples of 
many different Perl modules for parsing XML.

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