So I have some perl code that goes something like:
use strict;
use XML::XPath;
# $xml is an xml string read from file
my $returnVal = mySubA($xml);
#... some more code ...
# sub definition
sub mySubA {
my ($xml) = @_;
my $xp = XML::XPath->new(xml => $xml);
my @fields = $xp->find('/elA/elB/elC')->get_nodelist;
# foreach elC, get desired info...
foreach my $field (@fields) {
$xp = XML:XPath->new(context => $field);
my $info1 = $xp->find('/info1')->string_value;
print "\nINFO1: $info1";
my $info2 = $xp->find('/info2')->string_value;
}
# do some stuff....
return $returnVal;
}
This works fine and prints out INFO1: value… . I’m now changing the code, and am trying to get information from another section of the xml, and so I’ve written a different sub for it. To avoid parsing the same xml twice, I’m trying to write my code only using 1 xpath object (see XPath new in perl docs).
So now my code is something like….
use strict;
use XML::XPath;
# $xml is an xml string read from file
my $xp = XML::XPath->new(xml => $xml);
my $returnValA = mySubA($xp);
my $returnValB = mySubB($xp);
#... some more code ...
# sub definition
sub mySubA {
my ($xp) = @_;
my @fields = $xp->find('/elA/elB/elC')->get_nodelist;
# foreach elC, get desired info...
foreach my $field (@fields) {
$xp = XML:XPath->new(context => $field);
my $info1 = $xp->find('/info1')->string_value;
print "\nINFO1: $info1";
my $info2 = $xp->find('/info2')->string_value;
}
# do some stuff...
return $returnVal;
}
sub mySubB {
my ($xp) = @_;
# do some stuff....
return $returnVal;
}
So, basically, I’m passing the ref to the xpath object into mySubA instead of creating it within mySubA. The problem is that no values are being found, even though I’m pretty sure the xpath expression is resolving something because the loop iterates about 10 times. I’m new to perl, so I might be missing something here, but the thing that is confusing for me is that the second method – mySubB – is working fine; kind of blowing away my first suspicion that there is a problem with passing the xpath object into the sub (as in, I’m not dereferencing/referencing the xpath object as I should be).
I don’t know if its relevant or not, but the xml I’m working with doesn’t contain any namespaces or attributes.
Unless you are going to extract more than just one child element, I would use a direct XPath expression:
If this is not your case, then you should use the XPath expression to select the parents
elCand after that use simple DOM method to get the children.If you are going to use some complex selecting from the
elCelement, then there should be for you in your XPath engine some method taking an expression and a context node. But do note that ifelCis the context node, then you should use a relative XPath likeinfo1instead of an absolute XPath like/info1