DOMXPath::evaluate

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

DOMXPath::evaluate β€” ВычисляСт XPath-Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Ссли Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ

ОписаниС

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

ΠœΠ΅Ρ‚ΠΎΠ΄ выполняСт XPath-Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ expression ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.

Бписок ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²

expression

Π’Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ XPath, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ трСбуСтся Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ.

contextNode

ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ contextNode ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ для выполнСния ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… XPath-запросов. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ запросы Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта.

registerNodeNS
Π Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΈ автоматичСски прСфиксы пространства ΠΈΠΌΡ‘Π½ Π² области видимости контСкстного ΡƒΠ·Π»Π° для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° DOMXPath. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ Ρ€ΡƒΡ‡Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° DOMXPath::registerNamespace() для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ пространства ΠΈΠΌΡ‘Π½ Π² области видимости. Когда прСфиксы пространства ΠΈΠΌΡ‘Π½ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΡƒΡŽΡ‚, рСгистрируСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ прСфикс пространства ΠΈΠΌΡ‘Π½ Π±Π»ΠΈΠ·Π»Π΅ΠΆΠ°Ρ‰Π΅Π³ΠΎ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ°.

Ошибки

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ PHP-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ошибки:

  • ΠœΠ΅Ρ‚ΠΎΠ΄ выбрасываСт ΠΎΡˆΠΈΠ±ΠΊΡƒ Error, Ссли Π² Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΈ Π²Ρ‹Π·Π²Π°Π»ΠΈ PHP-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°, Π½ΠΎ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠΉ callback-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ рСгистрировали, ΠΈΠ»ΠΈ Ссли callback-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ с Ρ‚Π°ΠΊΠΈΠΌ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ Π½Π΅ зарСгистрировали.
  • ΠœΠ΅Ρ‚ΠΎΠ΄ выбрасываСт ΠΎΡˆΠΈΠ±ΠΊΡƒ TypeError, Ссли ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· XPath-выраТСния синтаксисом php:function вмСсто строкового названия ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.
  • ΠœΠ΅Ρ‚ΠΎΠ΄ выбрасываСт ΠΎΡˆΠΈΠ±ΠΊΡƒ Error, Ссли callback-функция вмСсто DOM-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния

ΠœΠ΅Ρ‚ΠΎΠ΄ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΈΠ»ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ DOMNodeList с ΡƒΠ·Π»Π°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ XPath-Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΡŽ expression.

ΠœΠ΅Ρ‚ΠΎΠ΄ DOMXPath::evaluate() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ false, Ссли Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ expression сформировали Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΈΠ»ΠΈ Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ contextNode ΠΏΠ΅Ρ€Π΅Π΄Π°Π»ΠΈ нСдопустимый ΡƒΠ·Π΅Π».

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #1 ΠŸΡ€ΠΈΠΌΠ΅Ρ€ подсчёта английских ΠΊΠ½ΠΈΠ³

<?php

$doc
= new DOMDocument();

$doc->load('examples/book-dcobook.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";

?>

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

Π€Π°ΠΉΠ» содСрТит 2 английских ΠΊΠ½ΠΈΠ³ΠΈ

Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅

  • DOMXPath::query() - ВычисляСт XPath-Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅
οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 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 ΒΆ
15 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 ΒΆ
21 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 ΒΆ
11 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 ΒΆ
6 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);
        }
?>