You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
2.1 KiB

3 years ago
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\CssSelector;
  11. use Symfony\Component\CssSelector\Parser\Shortcut\ClassParser;
  12. use Symfony\Component\CssSelector\Parser\Shortcut\ElementParser;
  13. use Symfony\Component\CssSelector\Parser\Shortcut\EmptyStringParser;
  14. use Symfony\Component\CssSelector\Parser\Shortcut\HashParser;
  15. use Symfony\Component\CssSelector\XPath\Extension\HtmlExtension;
  16. use Symfony\Component\CssSelector\XPath\Translator;
  17. /**
  18. * CssSelectorConverter is the main entry point of the component and can convert CSS
  19. * selectors to XPath expressions.
  20. *
  21. * @author Christophe Coevoet <stof@notk.org>
  22. */
  23. class CssSelectorConverter
  24. {
  25. private $translator;
  26. private $cache;
  27. private static $xmlCache = [];
  28. private static $htmlCache = [];
  29. /**
  30. * @param bool $html Whether HTML support should be enabled. Disable it for XML documents
  31. */
  32. public function __construct(bool $html = true)
  33. {
  34. $this->translator = new Translator();
  35. if ($html) {
  36. $this->translator->registerExtension(new HtmlExtension($this->translator));
  37. $this->cache = &self::$htmlCache;
  38. } else {
  39. $this->cache = &self::$xmlCache;
  40. }
  41. $this->translator
  42. ->registerParserShortcut(new EmptyStringParser())
  43. ->registerParserShortcut(new ElementParser())
  44. ->registerParserShortcut(new ClassParser())
  45. ->registerParserShortcut(new HashParser())
  46. ;
  47. }
  48. /**
  49. * Translates a CSS expression to its XPath equivalent.
  50. *
  51. * Optionally, a prefix can be added to the resulting XPath
  52. * expression with the $prefix parameter.
  53. *
  54. * @return string
  55. */
  56. public function toXPath(string $cssExpr, string $prefix = 'descendant-or-self::')
  57. {
  58. return $this->cache[$prefix][$cssExpr] ?? $this->cache[$prefix][$cssExpr] = $this->translator->cssToXPath($cssExpr, $prefix);
  59. }
  60. }