【发布时间】:2011-09-16 21:14:21
【问题描述】:
在 XPath 中,如何获取具有最高值的节点?例如
<tr>
<td>$12.00</td>
<td>$24.00</td>
<td>$13.00</td>
</tr>
将返回 24.00 美元。
我使用的是 PHP DOM,所以这是 XPath 1.0 版。
【问题讨论】:
在 XPath 中,如何获取具有最高值的节点?例如
<tr>
<td>$12.00</td>
<td>$24.00</td>
<td>$13.00</td>
</tr>
将返回 24.00 美元。
我使用的是 PHP DOM,所以这是 XPath 1.0 版。
【问题讨论】:
纯 XPath 1.0 解决方案很困难:在 XSLT 级别,您将使用递归,但这涉及编写函数或模板,因此它排除了纯 XPath。在 PHP 中,我只需将所有数据拉回宿主语言并使用 PHP 代码计算 max()。
【讨论】:
我花了最后一点时间为你想出最优雅的解决方案。如您所知,max 在 XPath 1.0 中不可用。我尝试了几种不同的方法,其中大多数似乎都不是很有效。
<?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;
?>
或者,您可以使用foreach 循环遍历更简单的 XPath 表达式的结果(一次只选择所有 TD 元素)并找到最大的数字。
<?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;
?>
您还可以使用 XSLTProcessor 类和使用 exslt.org 中的 math:max 函数的 XSL 文档,但我已经尝试过了,但由于美元符号 ($) 的原因,它无法正常工作。
我已经测试了这两种解决方案,它们对我都很有效。
【讨论】:
首先,编写单个 XPath 查询以返回包含除数字以外的字符的最高值(如您的情况 $)将非常困难或不可能。但是,如果您考虑排除$ 之类的XML 片段
<tr>
<td>12.00</td>
<td>24.00</td>
<td>13.00</td>
</tr>
然后您可以编写单个 XPath 查询来检索最高值节点。
//tr/td[not(preceding-sibling::td/text() > text() or following-sibling::td/text() > text())]
此查询返回 <td> 和值 24.00。
希望这会有所帮助。
【讨论】:
$ 符号。我的回答旨在提供单个 XPath 查询。否则有完成此任务的传统方法(循环/递归)。