DOMXPath::evaluate

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

DOMXPath::evaluate Avalia a expressão XPath fornecida e retorna um resultado tipado se possível

Descrição

public DOMXPath::evaluate(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true): mixed

Executa a expressão XPath expression fornecida e retorna um resultado tipado se possível.

Parâmetros

expression

A expressão XPath a ser executada.

contextNode

O contextNode opcional pode ser especificado para realizar consultas XPath relativas. Por padrão, as consultas são relativas ao elemento raiz.

registerNodeNS

Define se deve-se registrar automaticamente os prefixos de espaços de nomes dentro do escopo no nó de contexto para o objeto DOMXPath. Isto pode ser usado para evitar a necessidade de se chamar DOMXPath::registerNamespace() manuallmente para cada espaço de nome dentro do escopo. Quando existir um conflito entre prefixos de espaços de nomes, apenas o prefixo do espaço de nome descendente mais próximo será registrado.

Erros/Exceções

Os seguintes erros são possíveis ao usar uma expressão que invoca retornos de chamada PHP.

  • Lança um Error se um retorno de chamada do PHP for invocado, mas não houver nenhum retorno de chamada registrado ou se o retorno de chamada nomeado não tiver sido registrado.
  • Lança um TypeError se a sintaxe php:function for usada e o nome do manipulador não for uma string.
  • Lança um Error se um objeto não DOM foi retornado de um retorno de chamada.

Valor Retornado

Retorna um resultado tipado se possível ou uma DOMNodeList contendo todos os nós que correspondem à expressão XPath expression.

Se a expression estiver malformada ou o contextNode for inválido, DOMXPath::evaluate() retorna false.

Exemplos

Exemplo #1 Obtendo a contagem de todos os livros em inglês

<?php

$doc
= new DOMDocument;

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

$xpath = new DOMXPath($doc);

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

// nossa consulta é relativa ao nó tbody
$query = 'count(row/entry[. = "en"])';

$entries = $xpath->evaluate($query, $tbody);
echo
"There are $entries english books\n";

?>

O exemplo acima produzirá:

There are 2 english books

Veja Também

adicione uma nota

Notas Enviadas por Usuários (em inglês) 5 notes

up
4
daniel at danielnorton dot com
13 years ago
Note that this method does not provide any means to distinguish between a successful result that returns FALSE and an error.

For example, this will succeed and return FALSE:

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

One workaround when you know you are expecting a Boolean is to wrap the result with string(). e.g.

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

This will return a string "false" on success, or the Boolean FALSE on error.
up
4
Damien Bezborodov
13 years ago
If your expression returns a node set, you will get a DOMNodeList instead of a typed result. Instead, try modifying your expression from "//node[1]" to "string(//node[1])".
up
3
yuriucsal at NOSPAM dot yahoo dot com dot br
19 years ago
this class can substitute the method evaluate while it is not validated. Made for Yuri Bastos and 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

}
}
}
?>
up
1
aazaharov81 at gmail dot com
10 years ago
To query DOMNodes by their HTML classes, use such snippet
<?php

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

// then just
$domitems = $this->xpath("//*[@id='searchResultsRows']//a" . ccxs('listing_row'));
?>
up
1
danny at webdevelopers dot eu
5 years ago
The only way how to distinguish FALSE returned value from syntax error FALSE is to re-run the XPath expression wrapped in string() function. If must return empty string. If it returns FALSE again then it is an error.

<?php

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

// Error detection: DOMXPath::evaluate() returns FALSE on error
// so does 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