請注意,此方法無法區分傳回 FALSE 的成功結果和錯誤。
例如,以下程式碼會成功執行並傳回 FALSE
<?php $xpath->evaluate("1 = 0"); ?>
當您預期布林值時,一種解決方法是將結果用 string() 包裹起來。例如:
<?php $xpath->evaluate("string(1 = 0)"); ?>
這將在成功時傳回字串「false」,或在錯誤時傳回布林值 FALSE。
(PHP 5 >= 5.1.0, PHP 7, PHP 8)
DOMXPath::evaluate — 評估給定的 XPath 運算式,並盡可能返回類型化的結果
執行給定的 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
請注意,此方法無法區分傳回 FALSE 的成功結果和錯誤。
例如,以下程式碼會成功執行並傳回 FALSE
<?php $xpath->evaluate("1 = 0"); ?>
當您預期布林值時,一種解決方法是將結果用 string() 包裹起來。例如:
<?php $xpath->evaluate("string(1 = 0)"); ?>
這將在成功時傳回字串「false」,或在錯誤時傳回布林值 FALSE。
如果您的表達式傳回節點集,您將獲得 DOMNodeList 而不是類型化結果。請嘗試將表達式從 "//node[1]" 修改為 "string(//node[1])"。
此類別可以在 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
}
}
}
?>
要根據 HTML 類別查詢 DOMNodes,請使用以下程式碼片段
<?php
// CssClassXPathSelector
function ccxs($class) {
return '[contains(concat(" ", normalize-space(@class), " "), " ' . $class . ' ")]';
}
// 然後只需
$domitems = $this->xpath("//*[@id='searchResultsRows']//a" . ccxs('listing_row'));
?>
區分傳回值 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);
}
?>