2011-06-17 84 views
3

在XPath中,如何獲得具有最高價值的節點?例如使用XPath獲取最高價值節點

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

將返回24.00美元。

我使用PHP DOM,所以這將是XPath 1.0版。

回答

2

我花了最後一小時,試圖爲您提供最優雅的解決方案。如您所知,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中類和使用數學一個XSL文件:從exslt.org最大的功能,但我已經試過了,不能讓它的工作,因爲完全正確的美元符號($ )。

我已經測試了兩種解決方案,它們對我來說效果很好。

2

首先,編寫單個XPath查詢返回包含字符以外的字符(例如在您的案例$中)的單個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

希望這會有所幫助。

+1

當然,這可能會有O(n^2)的表現。 – 2011-06-17 10:09:08

+0

如果我有$的話會怎麼樣? – babonk 2011-06-17 18:24:12

+0

@babonk - 這個解決方案不會**符合美元符號。我已經發布了一個與美元符號一起工作的解決方案。 – 2011-06-18 00:19:13

1

純XPath 1.0解決方案很困難:在XSLT級別,您將使用遞歸,但涉及編寫函數或模板,因此它排除純XPath。在PHP中,我只需將所有數據重新導入主機語言並使用PHP代碼計算max()。

+0

好的,所以你建議循環DomNodeList來構建一個值數組,然後運行max()? – babonk 2011-06-17 18:33:14

+0

@babonk - 沒有必要創建另一個數組。看看我的第二個解決方案。 – 2011-06-18 00:20:03