15

Possible Duplicate:
How to use XPath function in a XPathExpression instance programatically?

I'm trying to find all of the rows of a nested table that contain an image with an id that ends with '_imgProductImage'.

I'm using the following query:

"//tr[/td/a/img[ends-with(@id,'_imgProductImage')]"

I'm getting the error: xmlXPathCompOpEval: function ends-with not found

My google searches i believe say this should be a valid query/function. What's the actual function i'm looking for if it's not "ends-with"?

Community
  • 1
  • 1
Matt
  • 153
  • 1
  • 1
  • 4

4 Answers4

13

from How to use XPath function in a XPathExpression instance programatically?

One can easily construct an XPath 1.0 expression, the evaluation of which produces the same result as the function ends-with():

$str2 = substring($str1, string-length($str1)- string-length($str2) +1)

produces the same boolean result (true() or false()) as:

ends-with($str1, $str2)

so for your example, the following xpath should work:

//tr[/td/a/img['_imgProductImage' = substring(@id, string-length(@id) - 15)]

you will probably want to add a comment that this is a xpath 1.0 reformulation of ends-with().

Community
  • 1
  • 1
ax.
  • 58,560
  • 8
  • 81
  • 72
9

It seems that ends-with() is an XPath 2.0 function.

DOMXPath only supports XPath 1.0


Edit after the comment : In your case, I suppose you'll have to :

  • Find all images, using a simpler XPath query, that will return more images than what you want -- but include those you want to keep.
  • Loops over those, testing in PHP, for each one of them, if the id attribute (see the getAttribute method) matches what you want.

To test if the attribute is OK, you could use something like this, in the loop that iterates over the images :

$id = $currentNode->getAttribute('id');
if (preg_match('/_imgProductImage$/', $id)) {
    // the current node is OK ;-)
}

Note that, in my regex pattern, I used a $ to indicate end of string.

Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
5

There is no ends-with function in XPath 1.0, but you can fake it:

"//tr[/td/a/img[substring(@id, string-length(@id) - 15) = '_imgProductImage']]"
Wayne
  • 59,728
  • 15
  • 131
  • 126
4

If you're on PHP 5.3.0 or later, you can use registerPHPFunctions to call any PHP function you want, although the syntax is a little odd. For example,

$xpath = new DOMXPath($document);
$xpath->registerNamespace("php", "http://php.net/xpath");
$xpath->registerPHPFunctions("ends_with");
$nodes = $x->query("//tr[/td/a/img[php:function('ends-with',@id,'_imgProductImage')]"

function ends_with($node, $value){
    return substr($node[0]->nodeValue,-strlen($value))==$value;
}
Anomie
  • 92,546
  • 13
  • 126
  • 145
  • Some say that the code here would not be working (but they don't provide any further details so far either), in case you're interested, it's via here: http://stackoverflow.com/q/19563167/367456 – hakre Oct 24 '13 at 12:47