#!/usr/bin/perl -- use strict; use warnings; use autodie; use utf8; use XML::Twig; use Data::Dump qw/ dd pp /; use Text::CSV; Main( @ARGV ); exit( 0 ); sub Main { #~ parseJmeter( \*DATA, \*STDOUT ); # DEMO my( $in1, $in2 ) = myData(); #~ my $csv = Text::CSV->new ( { auto_diag => 1, allow_loose_quotes => 1, allow_loose_escapes => 1,} ); #~ dd parseJmeter( $$in1, \*STDOUT ); #~ print "\n", '#' x 33, "\n"; #~ dd parseJmeter2( $$in1, \*STDOUT ); #~ print "\n", '#' x 33, "\n"; #~ dd parseJmeter2( $$in2, \*STDOUT ); #~ print "\n", '#' x 33, "\n"; #~ dd parseJmeter( $$in1, \*STDOUT ); #~ print "\n", '#' x 33, "\n"; #~ dd parseJmeter3( $$in1, \*STDOUT ); #~ print "\n", '#' x 33, "\n"; #~ dd parseJmeter3( $$in2, \*STDOUT ); #~ print "\n", '#' x 33, "\n"; dd parseJmeter4( $$in1, \*STDOUT, [] ); print "\n", '#' x 33, "\n"; dd parseJmeter4( $$in2, \*STDOUT, ['WTDate'] ); print "\n", '#' x 33, "\n"; } ## end sub Main sub parseJmeter4 { my( $inFilenameOrHandle, $outHandle, $names_init ) = @_; my %stuff; my @dimension_names = ( @$names_init ); my $name_index = 0; my $t = XML::Twig->new( twig_handlers => { q{/DimensionalReport/ReportDefinition/list[@name="Dimensions"]/Dimension/string[@name="name"]} => sub { warn $_->path, "\n"; push @dimension_names, $_->trimmed_text; $stuff{ $dimension_names[-1] } ||= 'null'; ## initialize }, q{/DimensionalReport/list[@name="data"]/DataRow} => sub { warn $_->path, "\n"; my $tp_name = $dimension_names[ $name_index++ ]; $stuff{$tp_name} = $_->att( 'name' ); }, q{//list/[@name="SubRows"]/DataRow} => sub { warn $_->path, "\n"; my $tp_name = $dimension_names[ $name_index++ ]; $stuff{$tp_name} = $_->att( 'name' ); }, q{//list[@name="measures"]/float} => sub { warn $_->path, "\n"; push @dimension_names, $_->att( 'name' ); $stuff{ $_->att( 'name' ) } = $_->trimmed_text; }, } ); $t->xparse( $inFilenameOrHandle ); $t->purge; length $_ or $_ = "null" for values %stuff; ## init not enough warn pp [ map { [ $_ => $stuff{$_} ] } @dimension_names ]; return \%stuff, \@dimension_names; } ## end sub parseJmeter4 sub parseJmeter3 { my( $inFilenameOrHandle, $outHandle ) = @_; my %stuff; my @dimension_names = ( 'WTDate' ); my $name_index = 0; my $t = XML::Twig->new( twig_handlers => { q{/DimensionalReport/ReportDefinition/list[@name="Dimensions"]/Dimension/string[@name="name"]} => sub { warn $_->path; print $_->trimmed_text, " = \n"; push @dimension_names, $_->trimmed_text; $stuff{ $dimension_names[-1] } ||= 'null'; ## initialize }, q{/DimensionalReport/list[@name="data"]/DataRow} => sub { warn $_->path; ## children my $tp_name = $dimension_names[ $name_index++ ]; print $tp_name , ' = ', $_->att( 'name' ), "\n"; $stuff{$tp_name} = $_->att( 'name' ); }, q{//list/[@name="SubRows"]/DataRow} => sub { warn $_->path; ## children my $tp_name = $dimension_names[ $name_index++ ]; print $tp_name , ' = ', $_->att( 'name' ), "\n"; $stuff{$tp_name} = $_->att( 'name' ); }, q{//list[@name="measures"]/float} => sub { warn $_->path; ## children print $_->att( 'name' ), ' = ', $_->trimmed_text, "\n"; push @dimension_names, $_->att( 'name' ); $stuff{ $_->att( 'name' ) } = $_->trimmed_text; }, } ); $t->xparse( $inFilenameOrHandle ); $t->purge; $stuff{giveup_input_data_too_cryptic} = 11_000; length $_ or $_ = "null" for values %stuff; ## init not enough dd [ map { [ $_ => $stuff{$_} ] } @dimension_names ]; return \%stuff; } ## end sub parseJmeter3 sub parseJmeter2 { my( $inFilenameOrHandle, $outHandle ) = @_; my %stuff; my $toilet_paper_name_index = 0; my @toilet_paper_name; my $t = XML::Twig->new( twig_handlers => { #~ '/DimensionalReport/ReportDefinition/list/Dimension' => sub { q{//Dimension/string[@name="name"]} => sub { warn $_->path; print $_->trimmed_text, " = \n"; push @toilet_paper_name, $_->trimmed_text; }, #~ '/DimensionalReport/ReportDefinition/list/Measure' => sub { q{//Measure/string[@name="name"]} => sub { warn $_->path; print $_->trimmed_text, " = \n"; }, q{//list/[@name="SubRows"]/DataRow/list[@name="measures"]/float} => sub { warn $_->path; ## children print $_->att( 'name' ), ' = ', $_->trimmed_text, "\n"; $stuff{ $_->att( 'name' ) } = $_->trimmed_text; return; }, #~ q{/DimensionalReport/list[@name="data"]/DataRow/list[@name="data"]/DataRow[@name]} => sub { #~ q{//list[@name="data"]/DataRow} => sub { #~ q{//list[@name]/DataRow} => sub { q{//list/[@name="SubRows"]/DataRow} => sub { warn $_->path; ## children my $tp_name = $toilet_paper_name[ $toilet_paper_name_index++ ]; print $tp_name , ' = ', $_->att( 'name' ), "\n"; $stuff{$tp_name} = $_->att( 'name' ); }, }, ); $t->xparse( $inFilenameOrHandle ); $t->purge; return \%stuff; } ## end sub parseJmeter2 sub parseJmeter { my( $inFilenameOrHandle, $outHandle ) = @_; my %stuff; my $toilet_paper_name = ''; my $t = XML::Twig->new( twig_handlers => { #~ '/DimensionalReport/ReportDefinition/list/Dimension' => sub { #~ '//Dimension/string' => sub { #~ warn $_->path; #~ print $_->att('name'), '=', $_->trimmed_text, "\n"; #~ }, q{//Dimension/string[@name="name"]} => sub { warn $_->path; print $_->trimmed_text, " = \n"; $toilet_paper_name = $_->trimmed_text; }, #~ '/DimensionalReport/ReportDefinition/list/Measure' => sub { #~ '//Measure/string' => sub { q{//Measure/string[@name="name"]} => sub { warn $_->path; print $_->trimmed_text, " = \n"; }, q{//list[@name="measures"]/float} => sub { warn $_->path; ## children print $_->att( 'name' ), ' = ', $_->trimmed_text, "\n"; $stuff{ $_->att( 'name' ) } = $_->trimmed_text; return; }, #~ q{/DimensionalReport/list[@name="data"]/DataRow/list[@name="data"]/DataRow[@name]} => sub { #~ q{//list[@name="data"]/DataRow} => sub { #~ q{//list[@name]/DataRow} => sub { q{//list/list[@name]/DataRow} => sub { warn $_->path; ## children print $toilet_paper_name , ' = ', $_->att( 'name' ), "\n"; $stuff{$toilet_paper_name} = $_->att( 'name' ); }, }, ); $t->xparse( $inFilenameOrHandle ); $t->purge; dd \%stuff; return \%stuff; } ## end sub parseJmeter sub myData { #~ https://ezcrypt.it/jk6n#4qRm2gc3F7f0RnOMqL5bPaYl my $in1 = <<'__IN1__'; 20510 zJt6RUMjXg6 VSlaqtDP0P6 Key Metrics A10_RPT_Key_Metrics_Summary_SD timeperiod Time Period Active Visits Visits 0 Page Views CAoNYspmFb5 1 9609.00 36456.00 604.00 9265.00 8948.00 9265.00 9265.00 9265.00 4444.00 9608.00 46.25 __IN1__ #~ https://ezcrypt.it/kk6n#eVINakVb1teCRmxKvdbtirFi my $in2 = <<'__IN2__'; some_id some_id some_id Campaigns by DMA This report shows campaign activity originating from different Designated Marketing Areas (DMAs) over the report time period. All activities are tracked and attributed to the last campaign to which visitors responded, even if this most recent campaign was seen prior to the current visit. dma DMA 5oTnPv0snj5 Most Recent Campaign Demand Channel KuU7oeAsnj5 Most Recent Campaign Partner BlpOxH5snj5 Most Recent Campaign Marketing Program Q2bjod3snj5 Most Recent Campaign Marketing Activity oda6Rji1Oj5 Most Recent Campaign Description 9STq0Y0Snj5 Most Recent Campaign ID Visits Visits 0 Page Views CAoNYspmFb5 1 Clickthroughs 6wSvdu0AOj5 2 Orders lEo2K44n7l5 3 Revenue qMKL354n7l5 4 Average Revenue per Order qMKL354n7l5_Average 5 Units pflHFpFmEL5 6 Average Units per Order pflHFpFmEL5_Average 7 Average Visit Duration (Minutes) 9VUp0ikQJb5 9 Average Visit Page Views RaAkw6wZzB5 10 Hits Hits 11 Daily Campaign Visitors JaLVXfZw4K5 12 Weekly Campaign Visitors N2tZxjIX4K5 13 Monthly Campaign Visitors Jdc329JX4K5 14 Quarterly Campaign Visitors GozsrIjX4K5 15 Yearly Campaign Visitors KrLEUoKX4K5 16 New Campaign Visitors TwdhsVkX4K5 17 4.00 4.00 4.00 0.00 0.00 0.00 4.00 2.00 0.00 2.00 2.00 2.00 0.00 0.00 1.00 __IN2__ s/^\s+//, s/\s+$// for $in1, $in2; return \$in1, \$in2; } ## end sub myData