getDomDocument()); $xpathNamespaces = $document->getXpathNamespaces(); foreach ($xpathNamespaces as $prefix => $namespaceUri) { $xpath->registerNamespace($prefix, $namespaceUri); } if ($xpathPhpfunctions = $document->getXpathPhpFunctions()) { $xpath->registerNamespace('php', 'http://php.net/xpath'); ($xpathPhpfunctions === true) ? $xpath->registerPHPFunctions() : $xpath->registerPHPFunctions($xpathPhpfunctions); } $nodeList = $xpath->queryWithErrorException($expression); return new NodeList($nodeList); } /** * Transform CSS expression to XPath * * @param string $path * @return string */ public static function cssToXpath($path) { $path = (string) $path; if (strstr($path, ',')) { $paths = explode(',', $path); $expressions = array(); foreach ($paths as $path) { $xpath = static::cssToXpath(trim($path)); if (is_string($xpath)) { $expressions[] = $xpath; } elseif (is_array($xpath)) { $expressions = array_merge($expressions, $xpath); } } return implode('|', $expressions); } $paths = array('//'); $path = preg_replace('|\s+>\s+|', '>', $path); $segments = preg_split('/\s+/', $path); foreach ($segments as $key => $segment) { $pathSegment = static::_tokenize($segment); if (0 == $key) { if (0 === strpos($pathSegment, '[contains(')) { $paths[0] .= '*' . ltrim($pathSegment, '*'); } else { $paths[0] .= $pathSegment; } continue; } if (0 === strpos($pathSegment, '[contains(')) { foreach ($paths as $pathKey => $xpath) { $paths[$pathKey] .= '//*' . ltrim($pathSegment, '*'); $paths[] = $xpath . $pathSegment; } } else { foreach ($paths as $pathKey => $xpath) { $paths[$pathKey] .= '//' . $pathSegment; } } } if (1 == count($paths)) { return $paths[0]; } return implode('|', $paths); } /** * Tokenize CSS expressions to XPath * * @param string $expression * @return string */ protected static function _tokenize($expression) { // Child selectors $expression = str_replace('>', '/', $expression); // IDs $expression = preg_replace('|#([a-z][a-z0-9_-]*)|i', '[@id=\'$1\']', $expression); $expression = preg_replace('|(?