1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\CssSelector\XPath; 13 14/** 15 * XPath expression translator interface. 16 * 17 * This component is a port of the Python cssselect library, 18 * which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect. 19 * 20 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com> 21 * 22 * @internal 23 */ 24class XPathExpr 25{ 26 private $path; 27 private $element; 28 private $condition; 29 30 public function __construct(string $path = '', string $element = '*', string $condition = '', bool $starPrefix = false) 31 { 32 $this->path = $path; 33 $this->element = $element; 34 $this->condition = $condition; 35 36 if ($starPrefix) { 37 $this->addStarPrefix(); 38 } 39 } 40 41 public function getElement(): string 42 { 43 return $this->element; 44 } 45 46 /** 47 * @return $this 48 */ 49 public function addCondition(string $condition): self 50 { 51 $this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition; 52 53 return $this; 54 } 55 56 public function getCondition(): string 57 { 58 return $this->condition; 59 } 60 61 /** 62 * @return $this 63 */ 64 public function addNameTest(): self 65 { 66 if ('*' !== $this->element) { 67 $this->addCondition('name() = '.Translator::getXpathLiteral($this->element)); 68 $this->element = '*'; 69 } 70 71 return $this; 72 } 73 74 /** 75 * @return $this 76 */ 77 public function addStarPrefix(): self 78 { 79 $this->path .= '*/'; 80 81 return $this; 82 } 83 84 /** 85 * Joins another XPathExpr with a combiner. 86 * 87 * @return $this 88 */ 89 public function join(string $combiner, self $expr): self 90 { 91 $path = $this->__toString().$combiner; 92 93 if ('*/' !== $expr->path) { 94 $path .= $expr->path; 95 } 96 97 $this->path = $path; 98 $this->element = $expr->element; 99 $this->condition = $expr->condition; 100 101 return $this; 102 } 103 104 public function __toString(): string 105 { 106 $path = $this->path.$this->element; 107 $condition = null === $this->condition || '' === $this->condition ? '' : '['.$this->condition.']'; 108 109 return $path.$condition; 110 } 111} 112