PHP 8.5.0 Alpha 2 available for testing

DOMXPath::evaluate

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

DOMXPath::evaluate Evalúa una expresión XPath dada y devuelve un resultado tipado si es posible

Descripción

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

Ejecuta la expresión XPath expression y devuelve un resultado tipado si es posible.

Parámetros

expression

La expresión XPath a ejecutar.

contextNode

El argumento opcional contextNode puede ser especificado para realizar consultas XPath relativas. Por omisión, las consultas son relativas al elemento root.

registerNodeNS

Indica si se deben registrar automáticamente los prefijos de espacio de nombres en vigor del nodo de contexto en el objeto DOMXPath. Esto puede ser utilizado para evitar tener que llamar manualmente a DOMXPath::registerNamespace() para cada espacio de nombres en vigor. En caso de conflicto de prefijos de espacio de nombres, solo se registra el prefijo de espacio de nombres descendiente más cercano.

Errores/Excepciones

Los siguientes errores pueden ocurrir al utilizar una expresión que invoca retrollamadas PHP.

  • Lanza una Error si una retrollamada PHP es invocada pero ninguna retrollamada está registrada, o si la retrollamada nombrada no está registrada.
  • Lanza una TypeError si la sintaxis php:function es utilizada y el nombre del gestor no es un string.
  • Lanza una Error si un objeto no-DOM es devuelto por una retrollamada.

Valores devueltos

Devuelve un resultado tipado si es posible o un DOMNodeList que contiene todos los nodos que coinciden con la expresión XPath expression.

Si el argumento expression está mal formado o bien si el argumento contextNode es inválido, el método DOMXPath::evaluate() devolverá false.

Ejemplos

Ejemplo #1 Recuperación del número total de libros en inglés

<?php

$doc
= new DOMDocument;

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

$xpath = new DOMXPath($doc);

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

// nuestra consulta es relativa al nodo tbody
$query = 'count(row/entry[. = "en"])';

$entries = $xpath->evaluate($query, $tbody);
echo
"Hay $entries libros en inglés\n";

?>

El ejemplo anterior mostrará :

Hay 2 libros en inglés

Ver también

add a note

User Contributed Notes 5 notes

up
4
daniel at danielnorton dot com
14 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
14 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
4
yuriucsal at NOSPAM dot yahoo dot com dot br
20 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