开发者

Getting highest value node using XPath

开发者 https://www.devze.com 2023-03-13 09:48 出处:网络
In XPath, how can I get the node with the highest value? e.g. <tr> <td>$12.00</td> <开发者_JAVA技巧;td>$24.00</td>

In XPath, how can I get the node with the highest value? e.g.

<tr>
   <td>$12.00</td>
   <开发者_JAVA技巧;td>$24.00</td>
   <td>$13.00</td>
</tr> 

would return $24.00.

I'm using PHP DOM, so this would be XPath version 1.0.


I spend the last little while trying to come up with the most elegant solution for you. As you know, max ins't available in XPath 1.0. I've tried several different approach, most of which don't seem very efficient.

<?php

$doc = new DOMDocument;
$doc->loadXml('<table><tr><td>$12.00</td><td>$24.00</td><td>$13.00</td></tr></table>');

function dom_xpath_max($this, $nodes)
{
  usort($nodes, create_function('$a, $b', 'return strcmp($b->textContent, $a->textContent);'));

  return $this[0]->textContent == $nodes[0]->textContent;
}

$xpath = new DOMXPath($doc);
$xpath->registerNamespace('php', 'http://php.net/xpath');
$xpath->registerPHPFunctions('dom_xpath_max');

$result = $xpath->evaluate('//table/tr/td[php:function("dom_xpath_max", ., ../td)]');

echo $result->item(0)->textContent;

?>

Alternatively, you could use a foreach loop to iterate through the result of a simpler XPath expression (once which only selects all of the TD elements) and find the highest number.

<?php

...

$xpath = new DOMXPath($doc);

$result = $xpath->evaluate('//table/tr/td');

$highest = '';

foreach ( $result as $node )
  if ( $node->textContent > $highest )
    $highest = $node->textContent;

echo $highest;

?>

You could also use the XSLTProcessor class and a XSL document that uses the math:max function from exslt.org but I've tried that and couldn't get it to work quite right because of the dollar signs ($).

I've tested both solutions and they worked well for me.


First of all it would be extremely difficult or not possible to write a single XPath query to return highest value which contains characters other than numbers like in your case $. But if you consider XML fragment excluding $ like

<tr>
   <td>12.00</td>
   <td>24.00</td>
   <td>13.00</td>
</tr> 

then you can write a single XPath query to retrieve the highest value node. //tr/td[not(preceding-sibling::td/text() > text() or following-sibling::td/text() > text())]

This query returns you <td> with value 24.00.

Hope this helps.


A pure XPath 1.0 solution is difficult: at the XSLT level you would use recursion, but that involves writing functions or templates, so it rules out pure XPath. In PHP, I would simply pull all the data back into the host language and compute the max() using PHP code.

0

精彩评论

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