I have following XML.
<Path>
<To>
<My>
<Node key="11">
<ChildA>1A</ChildA>
<ChildB key="Key1">1B</ChildB>
<ChildC>
<ChildD>ValD</ChildD>
</ChildC>
</Node>
<Node key="22">
<ChildA>2A</ChildA>
<ChildB key="Key2">2B</ChildB>
<ChildC>
<ChildD>ValD</ChildD>
</ChildC>
</Node>
</My>
</To>
</Path>
And I am trying to parse this xml using XML::Twig::XPath. Following is my code to parse it and extract element from it using XPath syntax.
use 5.010;
use strict;
use warnings FATAL => 'all';
use XML::Twig::XPath; #Issue with this shit as this thing was up to data but XML::XPath was not installed. So I did cpanm XML::XPath
use XML::Twig;
use Data::Dumper;
my @xml;
$xml[0] = q|<Path>
<To>
<My>
<Node key="11">
<ChildA>1A</ChildA>
<ChildB key="Key1">1B</ChildB>
<ChildC>
<ChildD>ValD</ChildD>
</ChildC>
</Node>
<Node key="22">
<ChildA>2A</ChildA>
<ChildB key="Key2">2B</ChildB>
<ChildC>
<ChildD>ValD</ChildD>
</ChildC>
</Node>
</My>
</To>
</Path>|;
my $twig = XML::Twig::XPath->new(pretty_print => 'indented')->parse($xml[0]);
#Finding the whole Node, using xpath. This shit also works if you have Twig, not XPath.
my @constraint = $twig->findnodes('/Path/To/My/Node[@key="22"]');
say $constraint[0]->sprint;
say ref($constraint[0]);
my $child_key = $constraint[0]->find('//ChildB/@key');
say $child_key;
$constraint[0] rightfully prints the XML Node.
And I expect $child_key to be Key2 but it turns out to be Key1Key2
What I could be possibly doing wrong? If I do full XPath search it is giving me corrct output.
The //ChildB/@key
xpath expression means that it starts at the root element and looks in any element for an element ChildB
and the attribute @key
.
It's confusing that your twig $constraint[0]
is not completely taken out of the tree. It's like a view on some part of the full document tree, so the //
actually looks in the full tree. It starts at root of the document, not at the <Node key="22">
element.
You need to tell your find
to start the current element by using the .
.
# V
my $child_key = $constraint[0]->find('.//ChildB/@key');
Now your output is only
Key2