XML::Simple drives me mad

Discussion in 'Perl Misc' started by Denis Valdenaire, Jul 29, 2011.

  1. 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 !
     
    Denis Valdenaire, Jul 29, 2011
    #1
    1. Advertising

  2. On 29/07/2011 14:48, Denis Valdenaire wrote:
    > $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";
    }


    --
    RGB
     
    RedGrittyBrick, Jul 29, 2011
    #2
    1. Advertising

  3. # 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";
    }
    }
    }
     
    George Mpouras, Jul 29, 2011
    #3
  4. Denis Valdenaire

    Keith Keller Guest

    On 2011-07-29, RedGrittyBrick <> wrote:
    > On 29/07/2011 14:48, Denis Valdenaire wrote:
    >> $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



    --
    -francisco.ca.us
    (try just my userid to email me)
    AOLSFAQ=http://www.therockgarden.ca/aolsfaq.txt
    see X- headers for PGP signature information
     
    Keith Keller, Jul 29, 2011
    #4
  5. On 29/07/2011 16:08, Keith Keller wrote:
    > On 2011-07-29, RedGrittyBrick<> wrote:
    >> On 29/07/2011 14:48, Denis Valdenaire wrote:
    >>> $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?

    --
    RGB
     
    RedGrittyBrick, Jul 29, 2011
    #5
  6. Denis Valdenaire

    Uri Guttman Guest

    >>>>> "GM" == George Mpouras <> writes:

    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

    --
    Uri Guttman -- uri AT perlhunter DOT com --- http://www.perlhunter.com --
    ------------ Perl Developer Recruiting and Placement Services -------------
    ----- Perl Code Review, Architecture, Development, Training, Support -------
     
    Uri Guttman, Jul 29, 2011
    #6
  7. Denis Valdenaire

    C.DeRykus Guest

    On Jul 29, 6:48 am, Denis Valdenaire <> wrote:
    > 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..

    --
    Charles DeRykus
     
    C.DeRykus, Jul 29, 2011
    #7
  8. Denis Valdenaire

    Keith Keller Guest

    On 2011-07-29, RedGrittyBrick <> wrote:
    >
    > 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

    --
    -francisco.ca.us
    (try just my userid to email me)
    AOLSFAQ=http://www.therockgarden.ca/aolsfaq.txt
    see X- headers for PGP signature information
     
    Keith Keller, Jul 29, 2011
    #8
  9. Denis Valdenaire

    Klaus Guest

    On 29 juil, 15:48, Denis Valdenaire <> wrote:
    > 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";
    }
     
    Klaus, Jul 29, 2011
    #9
  10. Hi there,

    Thanks for you help !!!

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


    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
     
    Denis Valdenaire, Aug 8, 2011
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Haider Abbas Y. Narsinh

    Re: I m gonna mad

    Haider Abbas Y. Narsinh, Aug 22, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    1,028
    Haider Abbas Y. Narsinh
    Aug 22, 2003
  2. SEWilson

    Re: I m gonna mad

    SEWilson, Aug 23, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    1,359
    SEWilson
    Aug 23, 2003
  3. =?Utf-8?B?UHJhZGVlcCBTdW5kYXJhbShNU0ZUKQ==?=

    Enumerate all the drives including Mapped network drives on a serv

    =?Utf-8?B?UHJhZGVlcCBTdW5kYXJhbShNU0ZUKQ==?=, Feb 25, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    1,058
    =?Utf-8?B?UHJhZGVlcCBTdW5kYXJhbShNU0ZUKQ==?=
    Feb 26, 2005
  4. Gerry
    Replies:
    6
    Views:
    535
    Gerry
    Feb 7, 2008
  5. Erik Wasser
    Replies:
    5
    Views:
    518
    Peter J. Holzer
    Mar 5, 2006
Loading...

Share This Page