Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Css Selector Laravel Package

symfony/css-selector

Symfony CssSelector converts CSS selectors into XPath expressions, making it easy to query DOM/XML documents with familiar CSS syntax. Part of the Symfony Components ecosystem, with full docs and issue tracking in the main Symfony repository.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require symfony/css-selector
    

    No additional configuration is required—this is a standalone component.

  2. First Use Case: Convert a CSS selector to an XPath expression for DOM traversal:

    use Symfony\Component\CssSelector\CssSelectorConverter;
    use Symfony\Component\CssSelector\CssSelectorConverterInterface;
    
    $converter = new CssSelectorConverter();
    $xpath = $converter->toXPath('div.active > p');
    // Output: "//div[contains(@class, 'active')]/p"
    
  3. Where to Look First:

    • Official Documentation for API details.
    • Source Code for advanced use cases (e.g., custom pseudo-selectors).
    • Laravel Integration: Pair with DOMDocument or SimpleXML for DOM manipulation:
      $dom = new DOMDocument();
      $dom->loadHTML($html);
      $xpath = new DOMXPath($dom);
      $nodes = $xpath->query($converter->toXPath('div:is(.active, .selected)'));
      

Implementation Patterns

Core Workflows

1. Basic Selector Conversion

  • Use Case: Convert CSS selectors to XPath for DOM queries.
  • Pattern:
    $converter = new CssSelectorConverter();
    $xpath = $converter->toXPath('article.header h1');
    // Output: "//article[contains(@class, 'header')]/h1"
    
  • Laravel Integration:
    use Illuminate\Support\Facades\File;
    $html = File::get('path/to/file.html');
    $dom = new DOMDocument();
    $dom->loadHTML($html);
    $xpath = new DOMXPath($dom);
    $nodes = $xpath->query($converter->toXPath('div.content > p'));
    

2. Handling Dynamic Classes with :is() and :where()

  • Use Case: Target multiple classes or states dynamically (e.g., A/B testing, conditional UI).
  • Pattern:
    $xpath = $converter->toXPath('div:is(.active, .selected)');
    // Output: "//div[contains(@class, 'active') or contains(@class, 'selected')]"
    
  • Laravel Example (Web Scraping):
    $scraper = new Spatie\WebScraper\WebScraper();
    $scraper->scrape('https://example.com')->css('div:is(.user--active, .user--premium)')->each(function ($node) {
        // Process nodes
    });
    

3. Attribute Selectors

  • Use Case: Query elements by attributes (e.g., data-*, aria-*).
  • Pattern:
    $xpath = $converter->toXPath('[data-role="button"]');
    // Output: "//*[@data-role='button']"
    
  • Laravel Example (Accessibility Audits):
    $xpath = $converter->toXPath('[aria-label]:is(:focus, :hover)');
    $nodes = $dom->xpath->query($xpath);
    

4. Pseudo-Selectors

  • Use Case: Leverage pseudo-selectors like :nth-child, :first-of-type, etc.
  • Pattern:
    $xpath = $converter->toXPath('li:nth-child(odd)');
    // Output: "//li[position() mod 2 = 1]"
    
  • Laravel Example (Pagination):
    $activePage = $converter->toXPath('li.active a');
    $nodes = $dom->xpath->query($activePage);
    

5. Combining with Laravel’s DOM Tools

  • Use Case: Use with DOMDocument, SimpleXML, or spatie/laravel-web-scraper.
  • Pattern:
    use Spatie\WebScraper\WebScraper;
    $scraper = new WebScraper();
    $scraper->scrape('https://example.com')->css('div:is(.desktop, .mobile)')->get();
    
  • Custom XPath Helper:
    if (!class_exists('App\Helpers\XPathHelper')) {
        class XPathHelper {
            public static function query($html, $selector) {
                $converter = new CssSelectorConverter();
                $dom = new DOMDocument();
                $dom->loadHTML($html);
                $xpath = new DOMXPath($dom);
                return $xpath->query($converter->toXPath($selector));
            }
        }
    }
    

Integration Tips

1. Caching XPath Expressions

  • Use Case: Avoid redundant conversions in performance-critical paths (e.g., scraping loops).
  • Pattern:
    $cache = new \Symfony\Component\Cache\Simple\FilesystemCache();
    $converter = new CssSelectorConverter();
    $xpath = $cache->get('xpath_div_active', function () use ($converter) {
        return $converter->toXPath('div.active');
    });
    

2. Error Handling

  • Use Case: Gracefully handle invalid selectors (e.g., custom pseudo-selectors).
  • Pattern:
    try {
        $xpath = $converter->toXPath('div:custom-pseudo');
    } catch (\Symfony\Component\CssSelector\Exception\CssSelectorException $e) {
        // Fallback to regex or alternative logic
        $xpath = '//div[contains(@class, "custom")]';
    }
    

3. Testing Selectors

  • Use Case: Validate selectors in PHPUnit/Pest tests.
  • Pattern:
    use Symfony\Component\CssSelector\CssSelectorConverter;
    use PHPUnit\Framework\TestCase;
    
    class SelectorTest extends TestCase {
        public function testSelectorConversion() {
            $converter = new CssSelectorConverter();
            $xpath = $converter->toXPath('div:is(.active, .selected)');
            $this->assertEquals(
                "//div[contains(@class, 'active') or contains(@class, 'selected')]",
                $xpath
            );
        }
    }
    

4. Blade Directives

  • Use Case: Use in Blade templates for dynamic XPath queries.
  • Pattern:
    // In a Blade component
    @php
        $converter = new \Symfony\Component\CssSelector\CssSelectorConverter();
        $xpath = $converter->toXPath('div:is('.request('theme').', .default)');
    @endphp
    <div x-data="{ nodes: @js($xpath->query($dom)->toArray()) }"></div>
    

5. Performance Optimization

  • Use Case: Optimize for high-throughput scraping (e.g., 10K+ selectors).
  • Pattern:
    // Enable LRU cache (built-in since v7.4.6)
    $converter = new CssSelectorConverter();
    $xpath = $converter->toXPath('div:is(.active, .selected)'); // Cached automatically
    

Gotchas and Tips

Pitfalls

1. Parent Selector Combinators

  • Issue: Selectors like div > :is(p, span) may behave unexpectedly if the parent (div) is not explicitly defined in the DOM.
  • Fix: Ensure the parent selector is valid in your HTML/XML structure. Test with:
    $xpath = $converter->toXPath('ul > li:is(.item, .highlight)');
    

2. Memory Exhaustion in Loops

  • Issue: While the LRU cache mitigates this, repeatedly converting the same selectors in tight loops (e.g., scraping 100K+ pages) can still cause memory bloat.
  • Fix: Clear the cache manually or use a smaller cache size:
    $converter = new CssSelectorConverter();
    $converter->setCache(new \Symfony\Component\Cache\Adapter\FilesystemAdapter('', 0, '/tmp/css-selector-cache'));
    

3. Unsupported Pseudo-Selectors

  • Issue: Custom or non-standard pseudo-selectors (e.g., :my-custom-pseudo) will throw CssSelectorException.
  • Fix: Handle exceptions or use a fallback:
    try {
        $xpath = $converter->toXPath('div:my-custom-pseudo');
    } catch (\Symfony\Component\CssSelector\Exception\CssSelectorException $e) {
        $xpath = '//div'; // Fallback
    }
    

4. **PHP 8.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai