/** @internal */ static function _evalPath($node, $path, $context) { if ($node === null) { // nothing is passed in current matcher, this happens when p₁ in single(p₁, p₂) matches nothing return null; } else { if ($path instanceof Matcher || $path instanceof \Closure) { // key => multipath return $path($node, $context); } elseif (is_array($path) || is_object($path)) { // key => array(paths) return Matcher::_extractPaths($node, $path, $context); } elseif (is_string($path)) { // key => path $matches = $context->xpathAll($node, $path); if (is_scalar($matches)) { return $matches; } else { if (count($matches) === 0) { return null; } else { return call_user_func($context->getExtractor(), $matches[0]); } } } elseif (is_int($path)) { // key => position of child element $ns = $context->position($node, $path); return empty($ns) ? null : call_user_func($context->getExtractor(), reset($ns)); } else { throw new \Exception("Invalid path. Expected string, int, array, stdClass object, Matcher object of function, " . gettype($path) . " given"); } } }