Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^3: XML::Twig traversing tree and storing in an array

by Anonymous Monk
on Aug 05, 2012 at 08:23 UTC ( #985503=note: print w/ replies, xml ) Need Help??


in reply to Re^2: XML::Twig traversing tree and storing in an array
in thread XML::Twig traversing tree and storing in an array

Sure, sprint, aka outer_xml

use strict; use warnings; use XML::Twig; my $twig = XML::Twig->new( pretty_print => 'indented', TwigHandlers => { ro => \&ssprint, sham => \&ssprint, bo => \&ssprint, } ); $twig->xparse('<hi> <ro><yo/></ro> <sham><yo/></sham> <bo><yo/></bo> </hi>' ); sub ssprint { print 'moo', $_->sprint, "\n"; } __END__ moo <ro> <yo/> </ro> moo <sham> <yo/> </sham> moo <bo> <yo/> </bo>

So whatever it is you're trying to get done, might be written as

#!/usr/bin/perl -- use strict; use warnings; use XML::Twig; use Data::Dump qw' dd '; Main( @ARGV ); exit( 0 ); sub Main { my %files; my $filename; my $ssprint = sub { # my( $twig, $elt ) = @_; # my( $twig, $_ ) = @_; # $_ is $elt push @{ $files{ $filename }{ $_->path } }, $_->sprint; return; }; my $twig = XML::Twig->new( pretty_print => 'indented', TwigHandlers => { 'panoply/classes' => $ssprint, 'panoply/files' => $ssprint, 'panoply/namespaces' => $ssprint, }, ); for my $file( @_ ){ dd $filename = $file; ## eval { $twig->parsefile( $file ); 1; } or warn "ERROR parsefile($file): $@ "; $twig->purge; } dd \%files; } __END__ "panolpy.985318.xml" "panolpy.985465.xml" { "panolpy.985318.xml" => { "/panoply/classes" => [ "\n <classes name +=\"Panoply::AccessLogic\">\n <all_members name=\"accessLogic\" pro +tection=\"public\" scope=\"Panoply::AccessLogic\" virtualness=\"non_v +irtual\"/>\n <all_members name=\"DBUS\" protection=\"public\" scop +e=\"Panoply::AccessLogic\" virtualness=\"non_virtual\"/>\n <all_me +mbers name=\"DDR_VIA_JTAG\" protection=\"public\" scope=\"Panoply::Ac +cessLogic\" virtualness=\"non_virtual\"/>\n <all_members name=\"DE +FAULT\" protection=\"public\" scope=\"Panoply::AccessLogic\" virtualn +ess=\"non_virtual\"/>\n <brief></brief>\n <detailed>\n <do +c type=\"text\">Models the access logic</doc>\n </detailed>\n < +includes local=\"no\" name=\"AccessLogic.hpp\"/>\n <private_member +s>\n <members kind=\"variable\" name=\"m_accessLogic\" protectio +n=\"private\" static=\"no\" type=\"AccessLogicTypes\" virtualness=\"n +on_virtual\"></members>\n <members kind=\"variable\" name=\"m_ha +ndledErrors\" protection=\"private\" static=\"no\" type=\"HandledErro +rs\" virtualness=\"non_virtual\"></members>\n </private_members>\n + <public_methods>\n <members const=\"yes\" kind=\"function\" +name=\"accessLogic\" protection=\"public\" static=\"no\" type=\"Acces +sLogicTypes\" virtualness=\"non_virtual\" volatile=\"no\">\n < +brief></brief>\n <detailed>\n <doc type=\"text\">Gets + the current access logic for...</doc>\n </detailed>\n </ +members>\n <members const=\"no\" kind=\"function\" name=\"Access +Logic\" protection=\"public\" static=\"no\" virtualness=\"non_virtual +\" volatile=\"no\">\n <parameters declaration_name=\"accessLog +ic\" default_value=\"DEFAULT\" type=\"AccessLogicTypes\"/>\n < +parameters declaration_name=\"handledErrors\" default_value=\"Handled +Errors::ALL\" type=\"const HandledErrors &amp;\"/>\n </members>\ +n </public_methods>\n <public_typedefs>\n <members kind=\" +enum\" name=\"AccessLogicTypes\" protection=\"public\" static=\"no\" +virtualness=\"non_virtual\">\n <values name=\"DEFAULT\"></valu +es>\n <values name=\"IO_CF8_CFC\"></values>\n </members>\ +n </public_typedefs>\n </classes>", "\n <classes name +=\"Panoply::Details::ActionBatch\">\n <brief></brief>\n <detail +ed></detailed>\n <includes local=\"no\" name=\"PlatformActionBatch +.hpp\"/>\n </classes>", ], "/panoply/files" => [ "\n <files name=\ +"panoplydoc.hpp\">\n <detailed></detailed>\n </files>", "\n <files name=\ +"PanoplyVersion.hpp\">\n <brief></brief>\n <includes name=\"str +ing\"/>\n <variables>\n <members initializer=\"&quot;0.1.9&qu +ot;\" kind=\"variable\" name=\"LIBRARY_VERSION\" static=\"no\" type=\ +"const std::string\"></members>\n <members initializer=\"&quot;0 +0/00/0000&quot;\" kind=\"variable\" name=\"BUILD_DATE\" static=\"no\" + type=\"const std::string\"></members>\n </variables>\n </files>" +, ], }, "panolpy.985465.xml" => { "/panoply/classes" => [ "\n <classes n +ame=\"Panoply::AccessLogic\">\n <all_members name=\"accessLogic\" +protection=\"public\"/>\n <all_members name=\"DDR_VIA_JTAG\" prote +ction=\"public\"/>\n <brief></brief>\n <detailed>\n <doc t +ype=\"text\">Models the access logic</doc>\n </detailed>\n <inc +ludes local=\"no\" name=\"AccessLogic.hpp\"/>\n <public_methods>\n + <members const=\"yes\" kind=\"function\" name=\"handledErrors\" + protection=\"public\" static=\"no\"></members>\n <members const +=\"no\" kind=\"function\" name=\"AccessLogic\" protection=\"public\" +static=\"no\">\n <parameters declaration_name=\"accessLogic\" +type=\"AccessLogicTypes\"/>\n <parameters declaration_name=\"h +andledErrors\" type=\"const HandledErrors &amp;\"/>\n </members> +\n </public_methods>\n <public_typedefs>\n <members kind=\ +"enum\" name=\"AccessLogicTypes\" protection=\"public\">\n <va +lues name=\"IO_CF8_CFC\"></values>\n </members>\n <members +kind=\"enumvalue\" name=\"MJTAG\"></members>\n </public_typedefs>\ +n </classes>", "\n <classes n +ame=\"Panoply::Details::ActionBatch\">\n <detailed></detailed>\n + <includes local=\"no\" name=\"PlatformActionBatch.hpp\"/>\n </clas +ses>", "\n <classes n +ame=\"Panoply::Details::ActionResult\">\n <derived name=\"Panoply: +:Details::CPUIDActionResult\"/>\n <includes local=\"no\" name=\"Pl +atformAction.hpp\"/>\n </classes>", "\n <classes n +ame=\"Panoply::Details::AddressIndex\">\n <includes local=\"no\" n +ame=\"Panoply.hpp\"/>\n </classes>", ], "/panoply/files" => [ "\n <files nam +e=\"panoplydoc.hpp\"></files>", "\n <files nam +e=\"PanoplyExports.hpp\">\n <defines>\n <members kind=\"defin +e\" name=\"NOMINMAX\" protection=\"public\"></members>\n <member +s kind=\"define\" name=\"_SCL_SECURE_NO_WARNINGS\"></members>\n </ +defines>\n </files>", ], "/panoply/namespaces" => [ "\n <namespace +s name=\"AMD\">\n <namespaces name=\"AMD::RegisterDef\"/>\n </nam +espaces>", "\n <namespace +s name=\"AMD::RegisterDef\">\n <classes name=\"AMD::RegisterDef::B +aseDevice\"/>\n <enums>\n <members kind=\"enum\" name=\"Permi +ssionLevel\" protection=\"public\">\n <values initializer=\" 1 +0\" name=\"PERMISSION_PUBLIC\"></values>\n <values initializer +=\" 20\" name=\"PERMISSION_NDA\"></values>\n </members>\n < +members kind=\"enum\" name=\"RegisterType\" protection=\"public\">\n + <values initializer=\" 0\" name=\"REGISTER_PCI\"></values>\n + <values initializer=\" 1\" name=\"REGISTER_MSR\"></values>\n + </members>\n </enums>\n <functions>\n <members const=\" +no\" kind=\"function\" name=\"Compare\" protection=\"public\">\n + <parameters declaration_name=\"first\" type=\"T\"/>\n <para +meters declaration_name=\"second\" type=\"T\"/>\n </members>\n + </functions>\n <namespaces name=\"AMD::RegisterDef::Buffalo\"/>\ +n <variables>\n <members name=\"LIBRARY_VERSION\"></members>\ +n </variables>\n </namespaces>", "\n <namespace +s name=\"AMD::RegisterDef::Buffalo\">\n <classes name=\"AMD::Regis +terDef::Buffalo::BaseEntity\"/>\n </namespaces>", ], }, }


Comment on Re^3: XML::Twig traversing tree and storing in an array
Select or Download Code
Replies are listed 'Best First'.
Re^4: XML::Twig traversing tree and storing in an array
by jccunning (Acolyte) on Aug 06, 2012 at 18:16 UTC
    Thanks, works great but I am not familiar how to extract info from this type of hash. For example, output appears to be an anonymous hash, a string, anonymous hash, string, then array. How do I extract arrays of info. Tried variations of $key->{}->{}->[0] but no luck.
    { "xmlout.xml" => { "/panoply/classes" => [ "\n <classes name=\"Panoply::AccessLog +ic\">\n <all_members name=\"accessLogic\" protection=\"public\" sc +ope=\"Panoply::AccessLogic\" virtualness=\"non_virtual\"/>\n </clas +ses>", "\n <classes name=\"Panoply::Details:: +ActionBatch\"></classes>", ], "/panoply/files" => [ "\n <files name=\"AccessLogic.hpp\"></ +files>", "\n <files name=\"BaseDevice.h\"></fil +es>", ], "/panoply/namespaces" => [ "\n <namespaces name=\"std\"></namespa +ces>", ], }, }

      Tried variations of ....

      Why not post what you tried?

      #!/usr/bin/perl -- use strict; use warnings; my $foops = { "xmlout.xml" => { "/panoply/classes" => [ "\n <classes name=\"Panoply::AccessLog +ic\">\n <all_members name=\"accessLogic\" protection=\"public\" sc +ope=\"Panoply::AccessLogic\" virtualness=\"non_virtual\"/>\n </clas +ses>", "\n <classes name=\"Panoply::Details:: +ActionBatch\"></classes>", ], "/panoply/files" => [ "\n <files name=\"AccessLogic.hpp\"></ +files>", "\n <files name=\"BaseDevice.h\"></fil +es>", ], "/panoply/namespaces" => [ "\n <namespaces name=\"std\"></namespa +ces>", ], }, }; print $foops, "\n"; print $foops->{"xmlout.xml"}, "\n"; print $foops->{"xmlout.xml"}{"/panoply/classes"}, "\n"; print $foops->{"xmlout.xml"}{"/panoply/classes"}[0], "\n"; print $foops->{"xmlout.xml"}{"/panoply/classes"}[1], "\n\n"; use Data::Diver qw( Dive ); my $classes = Dive( $foops, "xmlout.xml", "/panoply/classes" ); print $classes, "\n"; print scalar @{$classes}, "\n"; print @{$classes}, "\n\n"; while( my( $filename, $datahash ) = each %$foops ){ print "$filename => $datahash\n"; while( my( $branchname, $brancharray ) = each %$datahash ){ printf "%-20s => n(%3d) => %s\n", $branchname, scalar(@$brancharray), $brancharray; } } __END__ HASH(0x9ad1bc) HASH(0x99a36c) ARRAY(0x3f8a8c) <classes name="Panoply::AccessLogic"> <all_members name="accessLogic" protection="public" scope="Panoply +::AccessLogic" virtualness="non_virtual"/> </classes> <classes name="Panoply::Details::ActionBatch"></classes> ARRAY(0x3f8a8c) 2 <classes name="Panoply::AccessLogic"> <all_members name="accessLogic" protection="public" scope="Panoply +::AccessLogic" virtualness="non_virtual"/> </classes> <classes name="Panoply::Details::ActionBatch"></classes> xmlout.xml => HASH(0x99a36c) /panoply/namespaces => n( 1) => ARRAY(0x99a2fc) /panoply/files => n( 2) => ARRAY(0x99a26c) /panoply/classes => n( 2) => ARRAY(0x3f8a8c)

      TutorialsData Types and VariablesData Type: ArrayData Type: HashReferences quick reference

        Thanks again, learned more. Regarding your first code post where Main( @ARGV ); is used for providing multiple xml files on command line, is the most practical way of placing output from each file into a separate hash by duplicating "for my $file" and specify $_[0], $_1, etc.
        for my $file( $_[0] ){ # dd $filename = $file; ## eval { $twig->parsefile( $file ); 1; } or warn "ERROR parsefile($file): $@ "; }

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (10)
As of 2015-07-07 22:34 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 (93 votes), past polls