Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

trying to understand xml::twig and also trying to learn how to extract attribute

by convenientstore (Pilgrim)
on Nov 04, 2008 at 22:31 UTC ( #721522=perlquestion: print w/ replies, xml ) Need Help??
convenientstore has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am trying to learn and use XML with perl but because of difficulty that I am having with the perldoc XML::Twig and also the website of twig(despite all the tutorials, I decide to seek for help here. honestly, I just don't think I am getting it.

Anyway, I have fairly complicated XML file I want to parse out so that I can do some report on it but I am just not sure how to use XML::Twig nor if XML::Twig is even the right module to use.

I have been
1)trying to read the doc but honestly, it's little bit over my head...
2)trying to follow the tutorials on the website but it's not giving me what I want..(i am sure I am just not getting it .. same for 1) as well but
3)also did super seach on perlmonks w/ following key words ---> xml twig and read pretty much read all posts)

I have wrote a example xml file below and my question is, if I wanted to make a array of id so that my @array will contain qw/ msn movies espn/ how would I go about doing it?

I was thinking somehow using first_child method?
Would appreciate the pointer/advise.
thank you
-------- code that I was just looking at------------- #!/usr/bin/perl use warnings; use strict; use XML::Twig; my $twig = XML::Twig->new(twig_roots => { one => 1}); $twig->parsefile(shift); $twig->print; --- example file ------- <config> <one id="msn" type="shopping"> <traffic> <daily value="on" /> <weekly value="off" /> <monthly value="off" /> </traffic> </one> <one id="movies" type="entertainment"> <traffic> <daily value="on" /> <weekly value="off /> <monthly value="on" /> </traffic> </one> <one id="espn" type="sports"> <traffic> <daily value="on" /> <weekly value="on" /> <monthly value="on /> <hyper value="true /> </traffic> </one> </config>

Comment on trying to understand xml::twig and also trying to learn how to extract attribute
Download Code
Re: trying to understand xml::twig and also trying to learn how to extract attribute
by GrandFather (Sage) on Nov 04, 2008 at 23:27 UTC

    You're not a long way away from what you need to do. twig_roots supplies a reference to a sub to handle matching elements. Consider:

    use warnings; use strict; use XML::Twig; my $xmlStr = <<XML; <config> <one id="msn" type="shopping"> <traffic> <daily value="on" /> <weekly value="off" /> <monthly value="off" /> </traffic> </one> <one id="movies" type="entertainment"> <traffic> <daily value="on" /> <weekly value="off" /> <monthly value="on" /> </traffic> </one> <one id="espn" type="sports"> <traffic> <daily value="on" /> <weekly value="on" /> <monthly value="on" /> <hyper value="true" /> </traffic> </one> </config> XML my $result = ''; my $twig = XML::Twig->new (twig_roots => {one => sub {oneHandler (\$re +sult, @_);}}); $twig->parse ($xmlStr); print $result; sub oneHandler { my ($resRef, $twig, $elt) = @_; $$resRef = join ' ', $$resRef, $elt->att ('id'); return; }

    Prints:

    msn movies espn

    Note that there were a few missing close " in your sample XML that I've fixed.

    Also notice that I created an anonymous sub so I could pass extra parameters into the handler thus avoiding the need for global variables.


    Perl reduces RSI - it saves typing
Re: trying to understand xml::twig and also trying to learn how to extract attribute
by toolic (Bishop) on Nov 05, 2008 at 01:43 UTC
    Here is a different approach using XML::Twig. I consider this a more brute-force, less elegant solution than that provided by GrandFather. However, it illustrates the TIMTOWTDI-ness of Twig; perhaps you are more comfortable thinking of this as looping through elements, rather than the more powerful use of handlers (as I currently am). I have borrowed GrandFather's cleaned up XML text.
    use strict; use warnings; use Data::Dumper; use XML::Twig; my $xmlStr = <<XML; <config> <one id="msn" type="shopping"> <traffic> <daily value="on" /> <weekly value="off" /> <monthly value="off" /> </traffic> </one> <one id="movies" type="entertainment"> <traffic> <daily value="on" /> <weekly value="off" /> <monthly value="on" /> </traffic> </one> <one id="espn" type="sports"> <traffic> <daily value="on" /> <weekly value="on" /> <monthly value="on" /> <hyper value="true" /> </traffic> </one> </config> XML my @ids; my $t = XML::Twig->new(); $t->parse($xmlStr); for my $one ($t->root()->children('one')) { push @ids, $one->att('id'); } print Dumper(\@ids); __END__ $VAR1 = [ 'msn', 'movies', 'espn' ];

      I should have noted that the cleaned up XML is licensed under the Perl license so use it by all means. ;)


      Perl reduces RSI - it saves typing
        thank you guys
        Grandfather's solution is *bit* above my head at this point
        But eventually, I like my code to look like that(once I have better understanding)
        so I tried the second solution with bit of modification, but the way I am doing is I am sure wrong(as it's not working)
        I wanted to loop through and find monthly value eq 'on' and then push a certain elements and attribute in the array which I can loop through later for usage...
        #!/usr/bin/perl use strict; use warnings; use Data::Dumper; use XML::Twig; my $xmlStr = <<XML; <config> <one id="msn" type="shopping"> <traffic> <daily value="on" /> <weekly value="off" /> <monthly value="off" /> </traffic> </one> <one id="movies" type="entertainment"> <traffic> <daily value="on" /> <weekly value="off" /> <monthly value="on" /> </traffic> </one> <one id="espn" type="sports"> <traffic> <daily value="on" /> <weekly value="on" /> <monthly value="on" /> <hyper value="true" /> </traffic> </one> </config> XML my @ids; my $t = XML::Twig->new(); $t->parse($xmlStr); for my $one ( ($t->root()->children('one') ) { for my $month ( ($t->root()->children('monthly') ) { if ( $momth->att('value') eq 'on' ) { push @ids, $one->att('id'); } } } print Dumper(\@ids);

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://721522]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (10)
As of 2015-07-07 02:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (86 votes), past polls