예제 #1
0
 /**
  * Parse the HTML
  */
 protected function parse()
 {
     // Buffers
     $current_tag_buffer = array();
     $buffer_parent = $this->_document;
     $buffer_last_tag = '';
     // Do the split
     $len = strlen($this->_html);
     for ($i = 0; $i < $len; $i++) {
         $chr = $this->_html[$i];
         // Have we hit a new tag?
         if ($chr == '<') {
             $closing = false;
             $saved_i = $i;
             $tag_name = $this->parseTagName($i, $closing);
             $tag_attrs = array();
             if (!$closing && $this->_html[$i] == ' ') {
                 $tag_attrs = $this->parseAttributes($i, $closing);
             }
             // Are we to close something?
             if ($closing) {
                 // Are we expecting this to be closed?
                 if ($tag_name !== $buffer_last_tag) {
                     throw new \Exception("Parser error: Encountered closing " . $tag_name . " was expecting " . $buffer_last_tag);
                 }
                 // Store contents
                 $start = $current_tag_buffer[spl_object_hash($buffer_parent)];
                 $buffer_parent->setContents(substr($this->_html, $start, $saved_i - $start));
                 // We want to go back a bit
                 $buffer_parent = $buffer_parent->parent();
                 if (!$buffer_parent) {
                     $buffer_parent = $this->_document;
                 }
                 $buffer_last_tag = $buffer_parent->name();
                 continue;
             }
             // Are we to create something?
             if (!$closing) {
                 if (!$this->_document) {
                     $buffer_parent = $this->_document = PureTree::buildRoot($tag_name, $tag_attrs);
                 } else {
                     $buffer_parent = $buffer_parent->createChild($tag_name, $tag_attrs);
                 }
                 $current_tag_buffer[spl_object_hash($buffer_parent)] = $i + 1;
                 // Is this a self closing tag?
                 if ($this->_html[$i] == "/") {
                     $i++;
                     $buffer_parent = $buffer_parent->parent();
                     if (!$buffer_parent) {
                         $buffer_parent = $this->_document;
                     }
                     continue;
                 }
                 $buffer_last_tag = $tag_name;
                 continue;
             }
             $i++;
         }
     }
 }
예제 #2
0
 public function test_TreeQuery()
 {
     $root = PureTree::buildRoot('html', array(), '<head><title>Welcome</title></head><body><h1>Lorum!</h1><p>String 1</p><p>String 2 <span>Example</span></p></body></html');
     $head = $root->createChild("head", array(), '<title>Welcome</title>');
     $title = $head->createChild("title", array(), 'Welcome');
     $body = $root->createChild("body", array(), '<h1>Lorum!</h1><p>String 1</p><p>String 2</p>');
     $h1 = $body->createChild("h1", array(), 'Lorum!');
     $p1 = $body->createChild("p", array(), 'String 1');
     $p2 = $body->createChild("p", array(), 'String 2 <span>Example</span>');
     $span = $p2->createChild("span", array(), 'Example');
     // Now test querying
     $result = $root->query("title");
     $this->assertEquals(1, count($result));
     $this->assertEquals($title, $result);
     // More complex query
     $result = $root->query("html > head > title");
     $this->assertEquals(1, count($result));
     $this->assertEquals($title, $result);
     // Another query
     $result = $root->query("html head title");
     $this->assertEquals(1, count($result));
     $this->assertEquals($title, $result);
     // Another query
     $result = $root->query("html title");
     $this->assertEquals(1, count($result));
     $this->assertEquals($title, $result);
     // Another query
     $result = $root->query("head > title");
     $this->assertEquals(1, count($result));
     $this->assertEquals($title, $result);
     // Another query
     $result = $root->query("head");
     $this->assertEquals(1, count($result));
     $this->assertEquals($head, $result);
     // Test the '>' priorities
     $result = $root->query("body > span");
     $this->assertEquals(null, $result);
     // Test the '+' priorities
     $result = $root->query("h1 + p");
     $this->assertEquals($p1, $result);
 }
예제 #3
0
 public function test_runPath()
 {
     $root = PureTree::buildRoot('html', array(), '');
     $head = $root->createChild("head", array(), '');
     $title = $head->createChild("title", array(), '');
     $body = $root->createChild("body", array(), '');
     $h1 = $body->createChild("h1", array("class" => "ipsum"), '');
     $p1 = $body->createChild("p", array("id" => "example"), '');
     $p2 = $body->createChild("p", array("class" => "example lorum"), '');
     $p3 = $p2->createChild("p", array("class" => "lorum"), '');
     $p4 = $p2->createChild("p", array("class" => "ipsum singleton", "data-select" => "me"), '');
     $query = new TestableQuery("html");
     $result = $query->run($root);
     $this->assertEquals(array($root), $result);
     $query = new TestableQuery("p");
     $result = $query->run($root);
     $this->assertEquals(4, count($result));
     $query = new TestableQuery("html title");
     $result = $query->run($root);
     $this->assertEquals(array($title), $result);
     $query = new TestableQuery("html html");
     $result = $query->run($root);
     $this->assertEquals(0, count($result));
     $query = new TestableQuery("p p");
     $result = $query->run($root);
     $this->assertEquals(array($p3, $p4), $result);
     $query = new TestableQuery("html body h1");
     $result = $query->run($root);
     $this->assertEquals(array($h1), $result);
     // Selector magic
     $query = new TestableQuery("html > title");
     $result = $query->run($root);
     $this->assertEquals(0, count($result));
     $query = new TestableQuery("html > head");
     $result = $query->run($root);
     $this->assertEquals(array($head), $result);
     $query = new TestableQuery("html > head > title");
     $result = $query->run($root);
     $this->assertEquals(array($title), $result);
     $query = new TestableQuery("html body h1 + p");
     $result = $query->run($root);
     $this->assertEquals(array($p1), $result);
     $query = new TestableQuery("h1 + p");
     $result = $query->run($root);
     $this->assertEquals(array($p1), $result);
     $query = new TestableQuery("p + p");
     $result = $query->run($root);
     $this->assertEquals(array($p2, $p4), $result);
     $query = new TestableQuery("p *");
     $result = $query->run($root);
     $this->assertEquals(array($p3, $p4), $result);
     $query = new TestableQuery("html > head *");
     $result = $query->run($root);
     $this->assertEquals(array($title), $result);
     $query = new TestableQuery("*");
     $result = $query->run($root);
     $this->assertEquals(9, count($result));
     $query = new TestableQuery("#example");
     $result = $query->run($root);
     $this->assertEquals(array($p1), $result);
     $query = new TestableQuery(".example");
     $result = $query->run($root);
     $this->assertEquals(array($p2), $result);
     $query = new TestableQuery(".lorum");
     $result = $query->run($root);
     $this->assertEquals(array($p2, $p3), $result);
     $query = new TestableQuery("body .lorum");
     $result = $query->run($root);
     $this->assertEquals(array($p2, $p3), $result);
     $query = new TestableQuery("html > body .lorum");
     $result = $query->run($root);
     $this->assertEquals(array($p2, $p3), $result);
     $query = new TestableQuery("body > .lorum");
     $result = $query->run($root);
     $this->assertEquals(array($p2), $result);
     $query = new TestableQuery("* > .lorum");
     $result = $query->run($root);
     $this->assertEquals(array($p2, $p3), $result);
     $query = new TestableQuery("* .lorum");
     $result = $query->run($root);
     $this->assertEquals(array($p2, $p3), $result);
     $query = new TestableQuery("p.ipsum");
     $result = $query->run($root);
     $this->assertEquals(array($p4), $result);
     $query = new TestableQuery("body > h1.ipsum");
     $result = $query->run($root);
     $this->assertEquals(array($h1), $result);
     $query = new TestableQuery("body > p.example.lorum");
     $result = $query->run($root);
     $this->assertEquals(array($p2), $result);
     $query = new TestableQuery("p.example.lorum");
     $result = $query->run($root);
     $this->assertEquals(array($p2), $result);
     $query = new TestableQuery("p:first-child");
     $result = $query->run($root);
     $this->assertEquals(array($p3), $result);
     $query = new TestableQuery("p.lorum:first-child");
     $result = $query->run($root);
     $this->assertEquals(array($p3), $result);
     $query = new TestableQuery("body *:first-child");
     $result = $query->run($root);
     $this->assertEquals(array($h1, $p3), $result);
     $query = new TestableQuery("body > *:first-child");
     $result = $query->run($root);
     $this->assertEquals(array($h1), $result);
     $query = new TestableQuery("p:last-child");
     $result = $query->run($root);
     $this->assertEquals(array($p2, $p4), $result);
     $query = new TestableQuery("body p:last-child");
     $result = $query->run($root);
     $this->assertEquals(array($p2, $p4), $result);
     $query = new TestableQuery("body > p:last-child");
     $result = $query->run($root);
     $this->assertEquals(array($p2), $result);
     $query = new TestableQuery("body *:nth-child(0)");
     $result = $query->run($root);
     $this->assertEquals(array($h1, $p3), $result);
     $query = new TestableQuery("body p:nth-child(1)");
     $result = $query->run($root);
     $this->assertEquals(array($p1, $p4), $result);
     $query = new TestableQuery("body p:nth-child(even)");
     $result = $query->run($root);
     $this->assertEquals(array($p2, $p3), $result);
     $query = new TestableQuery("body p:nth-child(odd)");
     $result = $query->run($root);
     $this->assertEquals(array($p1, $p4), $result);
     $query = new TestableQuery("body p[data-select=me]");
     $result = $query->run($root);
     $this->assertEquals(array($p4), $result);
     $query = new TestableQuery("p[data-select=me]");
     $result = $query->run($root);
     $this->assertEquals(array($p4), $result);
     $query = new TestableQuery("p[data-select=me,class=ipsum]");
     $result = $query->run($root);
     $this->assertEquals(array($p4), $result);
     $query = new TestableQuery("p[class=ipsum+singleton]");
     $result = $query->run($root);
     $this->assertEquals(array($p4), $result);
     $query = new TestableQuery("p > p[data-select=me,class=ipsum+singleton]:last-child");
     $result = $query->run($root);
     $this->assertEquals(array($p4), $result);
 }