http://qs321.pair.com?node_id=723626

Sporti69 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I have been working on a script that parses XML using the XML::Simple module. I am now in a phase where I want to make my code more dynamic. (it's already quite dynamic, but not in nesting eg more xml sub sub sub sub sub elements.)

I have quite some nested loops that all need values from upper loops. Now I wonder if it is possible to make this script more universal with XML::Simple

As you will see I speak to the top XML element and start 'for' looping everything. Then I use for $i loops every time again. Just look at the code and you will see that $sub1 $sub2 $sub3 and $sub4 are the same

Is there a way to program more effecient when you need those loops for building references?

#!/usr/bin/perl -- use strict; use warnings; use Cwd; use Win32::OLE; use XML::Simple; my $dir = cwd(); opendir(DIR, "."); my @file = grep(/\.xml$/,readdir(DIR)); closedir(DIR); use Data::Dumper; local $Data::Dumper::Indent=1; #print Dumper($doc); my $xs1 = XML::Simple->new(); my $doc = $xs1->XMLin($file[0], keyattr=>[], ForceContent=>1, ForceArr +ay=>1); for my $sub1 ( sort keys %{ $doc } ){ unless (ref($doc->{$sub1})) { print "$doc->{$sub1} is not a reference at + all.\n"; next; } my $count = @{ $doc->{$sub1} }; print "\n$sub1\t"; for (my $i=0; $i <= $count; $i++) { for my $sub2 ( sort keys %{ $doc->{$sub1}[$i] } ){ unless (ref($doc->{$sub1}[$i]{$sub2})) { print "$doc->{$sub1}[$i]{$sub2} is not a r +eference at all.\n"; next; } my $count2 = @{$doc->{$sub1}[$i]{$sub2}}; for (my $j=0; $j <= $count2; $j++) { for my $sub3 ( sort keys %{ $doc->{$sub1}[$i]{$sub2}[$ +j] } ){ unless (ref($doc->{$sub1}[$i]{$sub2}[$j]{$ +sub3})) { print "$doc->{$sub1}[$i]{$sub2}[$j]{$sub3} + is not a reference at all.\n"; next; } my $count3 = @{$doc->{$sub1}[$i]{$sub2}[$j]{$sub3} +}; print "\n\t$sub2\t$sub3($count3)"; for (my $k=0; $k <= $count3; $k++) { print "\n"; for my $sub4 ( sort keys %{ $doc->{$sub1}[$i]{ +$sub2}[$j]{$sub3}[$k] } ){ print "\n\t\t\t$sub4 : "; print $doc->{$sub1}[$i]{$ +sub2}[$j]{$sub3}[$k]{$sub4}; } } } } } } }
And the XML for the ones who like to run it:
<A type="not_a_reference"> <B type="not_a_reference"> <C types="not_a_reference"> <element type="k" name="p" online="yes"/> <element type="i" name="e" online="yes"/> </C> <D jammer="not_a_reference"> <element type="kd" name="pd" online="no"/> <element type="id" name="ed" online="yes"/> <element type="yd" name="zd" online="no"/> </D> </B> <Z type="klote" zever="not_a_reference"> <C> <element type="k" name="z" online="yes"/> <element type="t" name="p" online="yes"/> </C> <E type="not_a_reference"> <element type="kd" name="pd" online="no" zever="inpakstkes +"/> <element type="id" name="ed" online="yes"/> </E> </Z> </A>