4 * This file is part of the Mink package.
5 * (c) Konstantin Kudryashov <ever.zet@gmail.com>
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
11 namespace Behat\Mink\Selector\Xpath;
14 * XPath manipulation utility.
16 * @author Graham Bates
17 * @author Christophe Coevoet <stof@notk.org>
22 * Regex to find union operators not inside brackets.
24 const UNION_PATTERN = '/\|(?![^\[]*\])/';
27 * Prepends the XPath prefix to the given XPath.
29 * The returned XPath will match elements matching the XPath inside an element
30 * matching the prefix.
32 * @param string $xpath
33 * @param string $prefix
37 public function prepend($xpath, $prefix)
39 $expressions = array();
41 // If the xpath prefix contains a union we need to wrap it in parentheses.
42 if (preg_match(self::UNION_PATTERN, $prefix)) {
43 $prefix = '('.$prefix.')';
46 // Split any unions into individual expressions.
47 foreach (preg_split(self::UNION_PATTERN, $xpath) as $expression) {
48 $expression = trim($expression);
51 // If the union is inside some braces, we need to preserve the opening braces and apply
52 // the prefix only inside it.
53 if (preg_match('/^[\(\s*]+/', $expression, $matches)) {
54 $parenthesis = $matches[0];
55 $expression = substr($expression, strlen($parenthesis));
58 // add prefix before element selector
59 if (0 === strpos($expression, '/')) {
60 $expression = $prefix.$expression;
62 $expression = $prefix.'/'.$expression;
64 $expressions[] = $parenthesis.$expression;
67 return implode(' | ', $expressions);