using variables in perl xpath find statement
Ok, i've been searching around and can't seem to find an answer for my problem. I'm using Perl to parse an XML file using XPATH. Part of the file, I don't know what the child nodes will be named. For example:
<state xmlns="http://google.com" id=1>
<randomName1 type="boolean">0</randomName1>
</state>
<state xmlns="http://google.com" id=2>
<randomName2 type="boolean">1</random开发者_JAVA百科Name2>
</state>
So for each randomName, I need to grab the name which I was able to do by doing the following code (note: I grab the nodelist in a parent foreach statement).
my $elements = $nodes->getChildNodes;
foreach my $element(@$elements)
{
my $name = (lc($element->getName))
}
My issue comes comes in when I try to grab the value, I attempted to put my $value = $element->string_value;
inside of the foreach loop and all that did was return 0 no matter the name. I also tried putting a variable in the xpath string_value statement with no luck.
Is there a way to put a variable in an xpath expression? Something simliar to (note: this doesn't work) my $value = $element->find('$name')->string_value;
?
Sorry, if that's not clear and i'll try to answer any questions but any help would be greatly appreciated, I've already spent more time on trying to figure this out.
The problem is that if a document is in a default namespace just using an element name in a location step will select nothing, because XPath treats all unprefixed names to be in "no namespace". This is the most FAQ in XPath. Just search for "XPath default namespace" to get the answer.
There are two solutions:
Register the namespace in a "NamespaceManager" -like object and then use the prefix in the XPath expression.
Use a location step like:
*[name()='someName']
I recommend the use of XML::XPath module:
use XML::XPath;
use XML::XPath::XMLParser;
my $xp = XML::XPath->new(filename => 'test.xml');
my $nodeset = $xp->find('/states/state/*'); # find all subnodes
foreach my $node ($nodeset->get_nodelist) {
print "FOUND: ", XML::XPath::XMLParser::as_string($node), "\n";
}
with this example XML file:
<?xml version="1.0"?>
<states>
<state xmlns="http://google.com" id="1">
<randomName1 type="boolean">0</randomName1>
</state>
<state xmlns="http://google.com" id="2">
<randomName2 type="boolean">1</randomName2>
</state>
</states>
This piece of code prints:
FOUND: <randomName1 type="boolean">0</randomName1>
FOUND: <randomName2 type="boolean">1</randomName2>
perl+cpan rocks!
With g
prefix bound to http://google.com
namespace URI, you could use this expression for selecting any element child of state
:
//g:state/*
Note: If you know the schema don't start a path with //
operator, use a full path.
Update: To get the string value of each of the selected nodes is not an XPath problem but host language DOM method problem.
thanks to everyone that wrote a response, turns out i'm just a moron. in the way i was calling the sub-routine, it was only passing the variables properly on every other set so my $value = $element->string_value;
was doing it's job and returning just 0 because the sets where the value was 1 were being passed over.
my apologies for wasting anyone's time...not the first impression I wanted to make to the stackoverflow community but thanks again for the responses.
精彩评论