开发者

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:

  1. Register the namespace in a "NamespaceManager" -like object and then use the prefix in the XPath expression.

  2. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜