XML::Simple drives me mad

D

Denis Valdenaire

Hello,

Here is my problem. I have a "data" in perl (I said a "data", because
i don't know WHAT it is. I know what it is not : not an ARRAY ref, not
an ARRAY, not a HASH ref, etc. etc. Every attempt i made to parse it
fails with an error message of that kind.), that was provider by
XML::Simple::XMLIn();

Let's consider the code :


#!/usr/bin/perl

use XML::Simple;
use Data::Dumper;

$xml = '<configuration>
<sync_method type="common">
<sync_modules>
<ena name="was6"/>
<ena name="wasconf"/>
<dis name="ihs"/>
</sync_modules>
</sync_method></configuration>';


my $config = XMLin($xml, KeyAttr => "");

print Dumper($config->{sync_method}->{sync_modules}->{ena});

That gives me the following output (THE VERY "data") :

$VAR1 = [
{
'name' => 'was6'
},
{
'name' => 'wasconf'
}
];

My question : what i am supposed to do if i want to parse each name ?
like, processing was6 and then wasconf and then stop.

I believe I tried everything (keys, foreach, each, #{@->{%}}, etc...).
Do I do it the wrong way ?

Any suggestion is very welcome !
 
R

RedGrittyBrick

$VAR1 = [
{
'name' => 'was6'
},
{
'name' => 'wasconf'
}
];


#!/usr/bin/perl
use strict;
use warnings;

my $VAR1 = [
{
'name' => 'was6'
},
{
'name' => 'wasconf'
}
];


for my $row (@$VAR1) {
print $row->{name}, "\n";
}
 
G

George Mpouras

# I think you want something like this



print $config->{sync_method}->{sync_modules}->{dis}->{name} ,"\n";
print $config->{sync_method}->{sync_modules}->{ena}->[0]->{name} ,"\n";
print $config->{sync_method}->{sync_modules}->{ena}->[1]->{name} ,"\n";


print "\n\n\n-----------\n\n\n";


foreach my $k1 (keys $config->{sync_method}->{sync_modules})
{
my $k2 = $config->{sync_method}->{sync_modules}->{$k1};


if ( 'ARRAY' eq ref $k2 )
{
foreach (@{$k2})
{
print "$k1 , $_->{'name'}\n";
}
}
elsif ( 'HASH' eq ref $k2 )
{
foreach my $k3 (keys %{$k2})
{
print "$k3 $k2->{$k3}\n";
}
}
}
 
K

Keith Keller

$VAR1 = [
{
'name' => 'was6'
},
{
'name' => 'wasconf'
}
];

You do realize that this is just Data::Dumper output, right? It uses
$VAR1 as a dummy variable if you don't specify a variable name.
my $VAR1 = [

Oh, I guess not.

To the OP, you need to operate on the $config object. See if George's
code works for you.

--keith
 
R

RedGrittyBrick

$VAR1 = [
{
'name' => 'was6'
},
{
'name' => 'wasconf'
}
];

You do realize that this is just Data::Dumper output, right?

Correct, I do.
It uses
$VAR1 as a dummy variable if you don't specify a variable name.

Not only that, but a feature of Data::Dumper is that can be used to
serialize objects. You can use that output to reconstruct (deserialize)
the object in such a way that future operations on the reconstituted
object will behave exactly the same as they would with the original object.

my $VAR1 = [

Oh, I guess not.

You guess wrong.
To the OP, you need to operate on the $config object. See if George's
code works for you.

George's code is over-complex IMHO.

my $result = $config->{sync_method}->{sync_modules}->{ena};
for my $row (@$result) {
print $row->{name}, "\n";
}

Clearer?
 
U

Uri Guttman

GM> foreach my $k1 (keys $config->{sync_method}->{sync_modules})
GM> {
GM> my $k2 = $config->{sync_method}->{sync_modules}->{$k1};

that is redundant. just loop over the values of that last hash and skip
the entire extra access line above. or do a each %hash in a while loop
and get the key and the value. just access the desired level which is an
array ref and loop over that. no need to do the deep access twice.


GM> if ( 'ARRAY' eq ref $k2 )
GM> {
GM> foreach (@{$k2})
GM> {
GM> print "$k1 , $_->{'name'}\n";
GM> }
GM> }
GM> elsif ( 'HASH' eq ref $k2 )
GM> {
GM> foreach my $k3 (keys %{$k2})
GM> {
GM> print "$k3 $k2->{$k3}\n";
GM> }
GM> }
GM> }

and XML::Simple can force single elements to be parsed into arrays so
you can always process an array of items which simplifies your code.

uri
 
C

C.DeRykus

Hello,

Here is my problem. I have a "data" in perl (I said a "data", because
i don't know WHAT it is. I know what it is not : not an ARRAY ref, not
an ARRAY, not a HASH ref, etc. etc. Every attempt i made to parse it
fails with an error message of that kind.), that was provider by
XML::Simple::XMLIn();

Let's consider the code :

#!/usr/bin/perl

use XML::Simple;
use Data::Dumper;

$xml = '<configuration>
        <sync_method type="common">
            <sync_modules>
                <ena name="was6"/>
                <ena name="wasconf"/>
                <dis name="ihs"/>
            </sync_modules>
        </sync_method></configuration>';

my $config = XMLin($xml, KeyAttr => "");

print Dumper($config->{sync_method}->{sync_modules}->{ena});

That gives me the following output (THE VERY "data") :

$VAR1 = [
          {
            'name' => 'was6'
          },
          {
            'name' => 'wasconf'
          }
        ];

My question : what i am supposed to do if i want to parse each name ?
like, processing was6 and then wasconf and then stop.

I believe I tried everything (keys, foreach, each, #{@->{%}}, etc...).
Do I do it the wrong way ?


That's the right idea... just need to drill down
to bedrock. Here's a possible solution:

my $array_ref = $config->{sync_method}
->{sync_modules}->{ena};

foreach my $array_elem ( @{$array_ref} )
{
while ( my($key,$value) = each %{$array_elem} )
{
print "$key=$value\n";
}
}

perldoc perldsc for more info and examples..
 
K

Keith Keller

Not only that, but a feature of Data::Dumper is that can be used to
serialize objects. You can use that output to reconstruct (deserialize)
the object in such a way that future operations on the reconstituted
object will behave exactly the same as they would with the original object.

Yes, it can, but your code doesn't actually help the OP, who isn't using
that feature.

--keith
George's code is over-complex IMHO.

my $result = $config->{sync_method}->{sync_modules}->{ena};
for my $row (@$result) {
print $row->{name}, "\n";
}

Clearer?

Not ''clearer'', but certainly more useful to the OP.

--keith
 
K

Klaus

Hello,

Here is my problem. I have a "data" in perl (I said a "data", because
i don't know WHAT it is. I know what it is not : not an ARRAY ref, not
an ARRAY, not a HASH ref, etc. etc. Every attempt i made to parse it
fails with an error message of that kind.), that was provider by
XML::Simple::XMLIn();

Let's consider the code :

#!/usr/bin/perl

use XML::Simple;
use Data::Dumper;

$xml = '<configuration>
        <sync_method type="common">
            <sync_modules>
                <ena name="was6"/>
                <ena name="wasconf"/>
                <dis name="ihs"/>
            </sync_modules>
        </sync_method></configuration>';

my $config = XMLin($xml, KeyAttr => "");

print Dumper($config->{sync_method}->{sync_modules}->{ena});

That gives me the following output (THE VERY "data") :

$VAR1 = [
          {
            'name' => 'was6'
          },
          {
            'name' => 'wasconf'
          }
        ];

My question : what i am supposed to do if i want to parse each name ?
like, processing was6 and then wasconf and then stop.

I believe I tried everything (keys, foreach, each, #{@->{%}}, etc...).
Do I do it the wrong way ?

It's actually an array-ref, therefore you use @{...}

for (@{$config->{sync_method}->{sync_modules}->{ena}}) {
print "Do something with >$_->{name}<\n";
}

*********************************************
alternatively, you can use XML::Reader:

use XML::Reader;

my $rdr = XML::Reader->new(\$xml, {mode => 'branches'},
{ root => '/configuration/sync_method/sync_modules/ena',
branch => ['/@name'] },
);

while ($rdr->iterate) {
print "Do something with >", $rdr->value, "<\n";
}
 
D

Denis Valdenaire

Hi there,

Thanks for you help !!!

That solution worked. I finally understand why a direct usage of
$config->{... etc. } like :

for my $row (@$config->{sync_method}->{sync_modules}->{ena}) {
print $row->{name}, "\n";
}

did not work (Not an ARRAY reference at ./test.pl line 35.) and

for my $row (@{$config->{sync_method}->{sync_modules}->{ena}}) {
print $row->{name}, "\n";
}

Also work.. i need to read documentation about the usage of {}...

The last solution with $_ was also elegant.

Thanks a lot again for all !!!

Denis
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top