In CSS, a selector is used to identify which element or elements in a DOM are being selected for the application of a particular style. Effectively, selectors function as a query language for a structured document -- almost always HTML or XML. This class provides an event-based parser for CSS selectors. It can be used, for example, as a basis for writing a DOM query engine based on CSS.
 /**
  * @param DOMNode $node
  * @param string  $selector
  * @return bool
  * @throws \QueryPath\CSS\ParseException
  */
 public function matches(DOMNode $node, $selector)
 {
     $traverser = new DOMTraverser(new \SPLObjectStorage());
     $handler = new Selector();
     $parser = new Parser($selector, $handler);
     $parser->parse();
     foreach ($handler as $selectorGroup) {
         if ($traverser->matchesSelector($node, $selectorGroup)) {
             return true;
         }
     }
     return false;
 }
示例#2
0
 /**
  * Given a selector, find the matches in the given DOM.
  *
  * This is the main function for querying the DOM using a CSS
  * selector.
  *
  * @param string $selector
  *   The selector.
  * @retval object SPLObjectStorage
  *   An SPLObjectStorage containing a list of matched
  *   DOMNode objects.
  */
 public function find($selector)
 {
     // Setup
     $handler = new Selector();
     $parser = new Parser($selector, $handler);
     $parser->parse();
     $this->selector = $handler;
     //$selector = $handler->toArray();
     $found = $this->newMatches();
     foreach ($handler as $selectorGroup) {
         // fprintf(STDOUT, "Selector group.\n");
         // Initialize matches if necessary.
         if ($this->initialized) {
             $candidates = $this->matches;
         } else {
             //if (empty($selectorGroup)) {
             // fprintf(STDOUT, "%s", print_r($handler->toArray(), TRUE));
             //}
             $candidates = $this->initialMatch($selectorGroup[0], $this->matches);
             //$this->initialized = TRUE;
         }
         foreach ($candidates as $candidate) {
             // fprintf(STDOUT, "Testing %s against %s.\n", $candidate->tagName, $selectorGroup[0]);
             if ($this->matchesSelector($candidate, $selectorGroup)) {
                 // $this->debug('Attaching ' . $candidate->nodeName);
                 $found->attach($candidate);
             }
         }
     }
     $this->setMatches($found);
     return $this;
 }
 public function testAllCombo()
 {
     $selector = '*|ele1 > ele2.class1 + ns1|ele3.class2[attr=simple] ~
  .class2[attr2~="longer string of text."]:pseudoClass(value)
  .class3::pseudoElement';
     $expect = array(new TestEvent(TestEvent::elementNS, 'ele1', '*'), new TestEvent(TestEvent::directDescendant), new TestEvent(TestEvent::element, 'ele2'), new TestEvent(TestEvent::elementClass, 'class1'), new TestEvent(TestEvent::adjacent), new TestEvent(TestEvent::elementNS, 'ele3', 'ns1'), new TestEvent(TestEvent::elementClass, 'class2'), new TestEvent(TestEvent::attribute, 'attr', 'simple', EventHandler::isExactly), new TestEvent(TestEvent::sibling), new TestEvent(TestEvent::elementClass, 'class2'), new TestEvent(TestEvent::attribute, 'attr2', 'longer string of text.', EventHandler::containsWithSpace), new TestEvent(TestEvent::pseudoClass, 'pseudoClass', 'value'), new TestEvent(TestEvent::anyDescendant), new TestEvent(TestEvent::elementClass, 'class3'), new TestEvent(TestEvent::pseudoElement, 'pseudoElement'));
     $handler = new TestEventHandler();
     $handler->expects($expect);
     $parser = new Parser($selector, $handler);
     $parser->parse();
     //$handler->dumpStack();
     $this->assertTrue($handler->success());
     /*
     // Again, with spaces this time:
     $selector = ' *|ele1 > ele2. class1 + ns1|ele3. class2[ attr=simple] ~ .class2[attr2 ~= "longer string of text."]:pseudoClass(value) .class3::pseudoElement';
     
     $handler = new TestEventHandler();
     $handler->expects($expect);
     $parser = new Parser($selector, $handler);
     $parser->parse();
     
     $handler->dumpStack();
     $this->assertTrue($handler->success());
     */
 }