For me, some information is missing before your puzzle can be solved:
- Are you running under use strict;?
- Where do you declare my $d;?
- Are you sure that your print statements are executed in order suggested? I would feel more comfortable if you had print "1:$d"; for your print1 etc. The parser might call your functions in a different order than expected or suggested by the names. (I have not checked on the documentation of XML::Parser.)
| [reply] [d/l] [select] |
G'day Priyo,
Welcome to the monastery.
Your code raised a number of issues which I'll address first.
My comments assume you've posted all relevant code; however, your problem description suggests otherwise.
Of course, I have no way of knowing what you've left out; just bear that in mind as you read the following.
(These guidelines will help you post a better question next time: "How do I post a question effectively?".)
-
You don't declare "$d".
("use strict;" would have picked this up — see strict)
-
You don't assign a value to "$d".
("use warnings;" would have picked this up — see warnings)
-
You haven't shown any input: I have no idea what data you're processing.
-
You haven't shown your output: "everything works fine" (and similar prose) is not particularly helpful.
-
Don't use prototypes unless you really need them and know exactly what you're doing (see perlsub - Prototypes).
-
Don't use Indirect Object Syntax (see perlobj - Invoking Class Methods).
-
You create a new $parser each time getValue() is called: this is unnecessary.
-
You don't capture the return value of $parser->parsefile() (see XML::Parser - METHODS).
-
You don't read the arguments passed to your handlers (see XML::Parser - HANDLERS).
-
You define your handlers inside the getValue subroutine. I don't know what you were trying to achieve by doing this.
Here's a basic script (along the lines that I think you want) which addresses these issues.
Consider this a template for reworking your code.
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Parser;
my $parser = XML::Parser::->new(Handlers => {
Start => \&hdl_start,
End => \&hdl_end,
Char => \&hdl_char,
Default => \&hdl_def,
Final => \&hdl_final,
});
my @xml_files
= qw{./pm_xml_parser_test_file1.xml ./pm_xml_parser_test_file2.xml
+};
for (@xml_files) {
_init_handler_vars('filename');
get_value($_);
}
sub get_value {
my $file = shift;
my $returned = $parser->parsefile($file);
if (defined $returned) {
print "Wanted content: '$returned'\n";
}
else {
print "Wanted content not found!\n";
}
return;
}
# Private scope for handler variables
{
my ($wanted_element, $in_wanted_element,
$wanted_content, $found_wanted_content);
sub _init_handler_vars {
$wanted_element = shift;
$in_wanted_element = 0;
$wanted_content = '';
$found_wanted_content = 0;
return;
}
sub hdl_start {
my ($expat, $element, $attr, @vals) = @_;
if ($element eq $wanted_element) {
$in_wanted_element = 1;
}
return;
}
sub hdl_end {
my ($expat, $element) = @_;
if ($element eq $wanted_element) {
$in_wanted_element = 0;
}
return;
}
sub hdl_char {
my ($expat, $string) = @_;
if ($in_wanted_element) {
if ($string) {
$found_wanted_content = 1;
$wanted_content = $string;
}
}
return;
}
sub hdl_def {
my ($expat, $string) = @_;
# Default handler actions here
return;
}
sub hdl_final {
my ($expat) = @_;
return unless $found_wanted_content;
return $wanted_content;
}
}
Most of what I have here should be obvious from the issues I identified (and supporting documentation) above.
Note that the variables $wanted_element, $in_wanted_element, $wanted_content and $found_wanted_content are only visible to _init_handler_vars() and the handlers themselves (hdl_*()).
Here's my (minimal) test data:
$ cat ./pm_xml_parser_test_file1.xml
<root_element>
<filename>pm_xml_parser_test_file1.xml</filename>
</root_element>
$ cat ./pm_xml_parser_test_file2.xml
<root_element>
<filename>pm_xml_parser_test_file2.xml</filename>
</root_element>
Here's the output:
$ pm_xml_parser_test.pl
Wanted content: 'pm_xml_parser_test_file1.xml'
Wanted content: 'pm_xml_parser_test_file2.xml'
| [reply] [d/l] [select] |
Why are those sub definition inside another subroutine? Did you want them to be lexically scoped? If so you should check that your version of perl makes it default behavior (ie perl6, which I suppose you're actually not using), or that the feature is enabled. But in perl 5.18 this feature is experimental, and should be used with caution.
If you did not want lexical scope for you subs, which they probably do not have (pushes the sub names into the current package's namespace). Actually, I'm pretty your subs are only compiled once, and not each time you enter getValue.
That may have nothing to do with your problem, but since you are speaking of scoping issues ... | [reply] |
| [reply] |
| [reply] |
Thanks for your prompt response
In my earlier post I gave simplified code, where actual function is explained in comment (#). Here is original code.
The output of two calls as follows:
PK_start : Sheet0 : 0, 0, 0, 0, 0
PK_end : Sheet0 : 5 : 17 : 82 : 0 : 0
PK_start : Sheet1 : 8, 21, 82, 0, 0
PK_start : Sheet2 : 0, 0, 82, 0, 0
PK_final : 0, 0, 82, 0, 0
PK_return : 0, 0, 82, 0, 0
APB2DCR_vPlan.ann.xml : 82
PK_start : Sheet0 : 0, 0, 82, 0, 0
PK_end : Sheet0 : 5 : 17 : 78 : 0 : 0
PK_start : Sheet1 : 8, 21, 78, 0, 0
PK_start : Sheet2 : 0, 0, 78, 0, 0
PK_final : 0, 0, 78, 0, 0
PK_return : 0, 0, 0, 0, 0
APB2DCR_vPlan.pass.ann.xml : 0
Please note return value of 3rd variable
sub getFuncCovSummary($) {
my ($reportFile) = @_;
my $func = 0;
my $compl = 0;
my $group = 0;
my $assert = 0;
my $ftest = 0;
my $targetSheet = "";
my $col = 0;
my $row = 0;
my $hvp_col = 0;
my $grp_col = 0;
my $ass_col = 0;
my $tst_col = 0;
my $plan_row = 0;
my $isData = 0;
my $isComment = 0;
my $mergeAcross = 0;
my $mergeDown = 0;
my @str = ();
my $parser = new XML::Parser ( Handlers => {
Start => \&hdl_start
+,
End => \&hdl_end,
Char => \&hdl_char,
Default => \&hdl_def,
Final => \&hdl_final
+,
});
$parser->parsefile( $reportFile );
# The Handlers
sub hdl_start{
my ($p, $elt, %atts) = @_;
return unless (($elt eq 'Worksheet') ||
($elt eq 'Row') ||
($elt eq 'Cell') ||
($elt eq 'Comment') ||
($elt eq 'Data') ||
($elt eq 'ss:Data'));
if ($elt eq 'Worksheet') {
if ($atts{'ss:Name'} =~ /^(\d)_/) {$targetSheet = "Sheet$1";}
print "PK_start : $targetSheet : $row, $col, $group, $assert,
+ $ftest<br>";
$row = 0;
$col = 0;
}
return unless $targetSheet eq "Sheet0";
if ($elt eq 'Row') { $row++; $col = 0;}
if ($elt eq 'Cell') {
$col = $col + 1 + $mergeAcross;
if ($atts{'ss:Index'} > 0) { $col = $atts{'ss:Index'};}
if ($atts{'ss:MergeAcross'} > 0) {$mergeAcross = $atts{'ss:Me
+rgeAcross'};}
else {$mergeAcross = 0;}
if ($atts{'ss:MergeDown'} > 0) {$mergeDown = $atts{'ss:MergeD
+own'};}
else {$mergeDown = 0;}
}
if ($elt eq 'Comment') { $isComment = 1;}
if (($elt eq 'Data') || ($elt eq 'ss:Data')) { @str = (); $isDat
+a = 1;}
}
sub hdl_end{
my ($p, $elt) = @_;
return unless $targetSheet eq "Sheet0";
return unless (($elt eq 'Comment') ||
($elt eq 'Data') ||
($elt eq 'ss:Data'));
if ($elt eq 'Comment') { $isComment = 0;}
if (($elt eq 'Data') || ($elt eq 'ss:Data')) {
if (!$isComment) {
my $p = 0;
my $str = join("", @str);
if ($str =~ /^hvp\s+plan/) { $hvp_col = $col; }
if ($str =~ /^value\w+\.Group/) { $grp_col = $col; }
if ($str =~ /^value\w+\.Assert/) { $ass_col = $col; }
if ($str =~ /^value\w+\.test/) { $tst_col = $col; }
if (($col == $hvp_col) && ($str =~ /^plan/)) { $plan_row
+= $row; }
if (($row == $plan_row) && ($col == $grp_col)) { $group =
+ sprintf("%0.f",$str*100); $p = 1;}
if (($row == $plan_row) && ($col == $ass_col)) { $assert =
+ sprintf("%0.f",$str*100); $p = 1;}
if (($row == $plan_row) && ($col == $tst_col)) { $ftest =
+ $str; $p = 1;}
if ($p) {print "PK_end : $targetSheet : $row : $col : $gro
+up : $assert : $ftest<br>";}
}
$isData = 0;
}
}
sub hdl_char {
my ($p, $str) = @_;
return unless $targetSheet eq "Sheet0";
return unless ($isData && !$isComment);
push @str, $str;
}
sub hdl_def { }
sub hdl_final {print "PK_final : $func, $compl, $group, $assert, $f
+test<br>"; }
print "PK_return : $func, $compl, $group, $assert, $ftest<br>";
return ($func, $compl, $group, $assert, $ftest);
}# getFuncCovSummary
| [reply] [d/l] |