DOMXPath::evaluate

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

DOMXPath::evaluate 评估给定的 XPath 表达式,并在可能的情况下返回类型化的结果

说明

public DOMXPath::evaluate(string $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

参见

添加注释

用户贡献的注释 5 个注释

4
daniel at danielnorton dot com
13 年前
请注意,此方法未提供任何方法来区分返回 FALSE 的成功结果和错误。

例如,这将成功并返回 FALSE

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

当您知道自己期待布尔值时,一种解决方法是使用 string() 包装结果。例如

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

这将在成功时返回字符串 "false",或在错误时返回布尔值 FALSE。
4
Damien Bezborodov
13 年前
如果您的表达式返回节点集,您将获得 DOMNodeList 而不是类型化的结果。相反,尝试将您的表达式从 "//node[1]" 修改为 "string(//node[1])"。
4
yuriucsal at NOSPAM dot yahoo dot com dot br
19 年前
此类可以在该方法未验证时替代 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 索引

}
}
}
?>
1
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'));
?>
1
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("Invalid XPath expression ".json_encode($eval), 3491);
}
?>
To Top