2024 年日本 PHP 研討會

DOMXPath::evaluate

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

DOMXPath::evaluate 評估給定的 XPath 運算式,並盡可能返回類型化的結果

說明

公開 DOMXPath::evaluate(字串 $expression, ?DOMNode $contextNode = null, 布林值 $registerNodeNS = true): 混合

執行給定的 XPath 表達式,並在可能的情況下返回類型化的結果。

參數

expression

要執行的 XPath 表達式。

contextNode

可以指定選用的 contextNode 來執行相對 XPath 查詢。預設情況下,查詢是相對於根元素的。

registerNodeNS

是否自動將上下文節點的範圍內命名空間前綴註冊到 DOMXPath 物件。這可以用來避免需要為每個範圍內命名空間手動調用 DOMXPath::registerNamespace()。當命名空間前綴存在衝突時,只會註冊最近的子系命名空間前綴。

回傳值

如果可能,則返回類型化的結果,或者返回包含所有符合給定 XPath 表達式 的節點的 DOMNodeList

如果 表達式 格式錯誤或 contextNode 無效,DOMXPath::evaluate() 會返回 false

範例

範例 #1 取得所有英文書籍的數量

<?php

$doc
= new DOMDocument;

$doc->load('book.xml');

$xpath = new DOMXPath($doc);

$tbody = $doc->getElementsByTagName('tbody')->item(0);

// 我們的查詢是相對於 tbody 節點的
$query = 'count(row/entry[. = "en"])';

$entries = $xpath->evaluate($query, $tbody);
echo
"共有 $entries 本英文書籍\n";

?>

以上範例將輸出

There are 2 english books

另請參閱

新增註記

使用者貢獻的註記 5 則註記

daniel at danielnorton dot com
13 年前
請注意,此方法無法區分傳回 FALSE 的成功結果和錯誤。

例如,以下程式碼會成功執行並傳回 FALSE

<?php $xpath->evaluate("1 = 0"); ?>

當您預期布林值時,一種解決方法是將結果用 string() 包裹起來。例如:

<?php $xpath->evaluate("string(1 = 0)"); ?>

這將在成功時傳回字串「false」,或在錯誤時傳回布林值 FALSE。
Damien Bezborodov
13 年前
如果您的表達式傳回節點集,您將獲得 DOMNodeList 而不是類型化結果。請嘗試將表達式從 "//node[1]" 修改為 "string(//node[1])"。
yuriucsal at NOSPAM dot yahoo dot com dot br
19 年前
此類別可以在 evaluate 方法尚未驗證時替代它。由 Yuri Bastos 和 João Gilberto Magalhães 製作。

<?php

class XPtahQuery
{
// function returns a DOMNodeList from a relative xPath
public static function selectNodes($pNode, $xPath)
{

$pos = strpos(self::getFullXpath($pNode),"/",1);
$xPathQuery = substr(self::getFullXpath($pNode),$pos);//to paste /#document[1]/
$xPathQueryFull = $xPathQuery. $xPath;
$domXPath = new DOMXPath($pNode->ownerDocument);
$rNodeList = $domXPath->query($xPathQueryFull);

return
$rNodeList;
}
// function returns a DOMNode from a xPath from other DOMNode
public static function selectSingleNode($pNode, $xPath)
{

$pos = strpos(self::getFullXpath($pNode),"/",1);
$xPathQuery = substr(self::getFullXpath($pNode),$pos);//to paste /#document[1]/
$xPathQueryFull = $xPathQuery. $xPath;
$domXPath = new DOMXPath($pNode->ownerDocument);
$rNode = $domXPath->query($xPathQueryFull)->item(0);

return
$rNode;
}
//utilitaries functions off selectSingleNode
private function getNodePos($pNode, $nodeName)
{
if(
$pNode == null)
{
return
0;
}
else
{
$var = 0;
if (
$pNode->previousSibling != null)
{
if (
$pNode->previousSibling->nodeName == $nodeName)
{
$var = 1;
}
}
return
self::getNodePos($pNode->previousSibling, $nodeName) + $var;
}
}
//utilitaries functions off selectSingleNode
private function getFullXpath($pNode)
{
if(
$pNode == null)
{
return
"";
}
else
{

return
self::getFullXpath($pNode->parentNode) . "/" . $pNode->nodeName . "[" .strval(self::getNodePos($pNode, $pNode->nodeName)+1) . "]";//+1 to get the real xPath index

}
}
}
?>
aazaharov81 at gmail dot com
9 年前
要根據 HTML 類別查詢 DOMNodes,請使用以下程式碼片段
<?php

// CssClassXPathSelector
function ccxs($class) {
return
'[contains(concat(" ", normalize-space(@class), " "), " ' . $class . ' ")]';
}

// 然後只需
$domitems = $this->xpath("//*[@id='searchResultsRows']//a" . ccxs('listing_row'));
?>
danny at webdevelopers dot eu
4 年前
區分傳回值 FALSE 與語法錯誤 FALSE 的唯一方法是重新執行以 string() 函式包裹的 XPath 表達式。它必須傳回空字串。如果它再次傳回 FALSE,則表示發生錯誤。

<?php

$ret
= $this->xp->evaluate($eval, $context);

// 錯誤偵測:DOMXPath::evaluate() 在發生錯誤時會回傳 FALSE
// DOMXPath::evaluate("boolean(/nothing)") 也會
// @workaround webdevelopers.eu
if ($ret === false && $this->xp->evaluate("string(".$eval.")" , $context) === false) {
throw new
Exception("無效的 XPath 表達式 ".json_encode($eval), 3491);
}
?>
To Top