请注意,此方法未提供任何方法来区分返回 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 表达式,并在可能的情况下返回类型化的结果
$expression
, ?DOMNode $contextNode
= null
, bool $registerNodeNS
= true
): mixed执行给定的 XPath expression
,并在可能的情况下返回类型化的结果。
expression
要执行的 XPath 表达式。
contextNode
可选的 contextNode
可以指定用于进行相对 XPath 查询。默认情况下,查询相对于根元素。
registerNodeNS
是否自动将上下文节点的范围内的命名空间前缀注册到 DOMXPath 对象。这可以用于避免需要为每个范围内的命名空间手动调用 DOMXPath::registerNamespace()。当命名空间前缀冲突存在时,只注册最近的子代命名空间前缀。
如果可能,返回类型化的结果,或者返回包含与给定 XPath expression
匹配的所有节点的 DOMNodeList。
如果 expression
格式错误或 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 "There are $entries english books\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
{
// 函数从相对 XPath 返回 DOMNodeList
public static function selectNodes($pNode, $xPath)
{
$pos = strpos(self::getFullXpath($pNode),"/",1);
$xPathQuery = substr(self::getFullXpath($pNode),$pos);// 粘贴 /#document[1]/
$xPathQueryFull = $xPathQuery. $xPath;
$domXPath = new DOMXPath($pNode->ownerDocument);
$rNodeList = $domXPath->query($xPathQueryFull);
return $rNodeList;
}
// 函数从其他 DOMNode 的 XPath 返回 DOMNode
public static function selectSingleNode($pNode, $xPath)
{
$pos = strpos(self::getFullXpath($pNode),"/",1);
$xPathQuery = substr(self::getFullXpath($pNode),$pos);// 粘贴 /#document[1]/
$xPathQueryFull = $xPathQuery. $xPath;
$domXPath = new DOMXPath($pNode->ownerDocument);
$rNode = $domXPath->query($xPathQueryFull)->item(0);
return $rNode;
}
// 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;
}
}
// 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 获取真实的 XPath 索引
}
}
}
?>
要通过 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("Invalid XPath expression ".json_encode($eval), 3491);
}
?>