Ver Fonte

Merge pull request #602 from croensch/issue-504

Fixes #504 - Cannot parse huge documents in Zend_Dom_Query
Frank Brückner há 10 anos atrás
pai
commit
ac7a10dab2
2 ficheiros alterados com 46 adições e 4 exclusões
  1. 26 4
      library/Zend/Dom/Query.php
  2. 20 0
      tests/Zend/Dom/QueryTest.php

+ 26 - 4
library/Zend/Dom/Query.php

@@ -48,13 +48,14 @@ class Zend_Dom_Query
     /**#@+
      * Document types
      */
+    const DOC_DOM   = 'docDom';
     const DOC_XML   = 'docXml';
     const DOC_HTML  = 'docHtml';
     const DOC_XHTML = 'docXhtml';
     /**#@-*/
 
     /**
-     * @var string
+     * @var string|DOMDocument
      */
     protected $_document;
 
@@ -85,7 +86,7 @@ class Zend_Dom_Query
     /**
      * Constructor
      *
-     * @param null|string $document
+     * @param null|string|DOMDocument $document
      * @param null|string $encoding
      */
     public function __construct($document = null, $encoding = null)
@@ -119,12 +120,15 @@ class Zend_Dom_Query
     /**
      * Set document to query
      *
-     * @param  string $document
+     * @param  string|DOMDocument $document
      * @param  null|string $encoding Document encoding
      * @return Zend_Dom_Query
      */
     public function setDocument($document, $encoding = null)
     {
+        if ($document instanceof DOMDocument) {
+            return $this->setDocumentDom($document);
+        }
         if (0 === strlen($document)) {
             return $this;
         }
@@ -143,6 +147,20 @@ class Zend_Dom_Query
     }
 
     /**
+     * @param DOMDocument $document
+     * @param string $encoding
+     */
+    public function setDocumentDom(DOMDocument $document)
+    {
+        $this->_document = $document;
+        $this->_docType  = self::DOC_DOM;
+        if (null !== $document->encoding) {
+            $this->setEncoding($document->encoding);
+        }
+        return $this;
+    }
+
+    /**
      * Register HTML document
      *
      * @param  string $document
@@ -196,7 +214,7 @@ class Zend_Dom_Query
     /**
      * Retrieve current document
      *
-     * @return string
+     * @return string|DOMDocument
      */
     public function getDocument()
     {
@@ -259,6 +277,10 @@ class Zend_Dom_Query
         }
         $type   = $this->getDocumentType();
         switch ($type) {
+            case self::DOC_DOM:
+                $domDoc = $this->_document;
+                $success = true;
+                break;
             case self::DOC_XML:
                 try {
                     $domDoc = Zend_Xml_Security::scan($document, $domDoc);

+ 20 - 0
tests/Zend/Dom/QueryTest.php

@@ -143,6 +143,8 @@ class Zend_Dom_QueryTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(Zend_Dom_Query::DOC_XML, $this->query->getDocumentType());
         $this->query->setDocument('<html><body></body></html>');
         $this->assertEquals(Zend_Dom_Query::DOC_HTML, $this->query->getDocumentType());
+        $this->query->setDocument(new DOMDocument());
+        $this->assertEquals(Zend_Dom_Query::DOC_DOM, $this->query->getDocumentType());
     }
 
     public function testQueryingWithoutRegisteringDocumentShouldThrowException()
@@ -229,6 +231,24 @@ class Zend_Dom_QueryTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(2, count($result), $result->getXpathQuery());
     }
 
+    public function testQueryOnDomDocument()
+    {
+        $xml = <<<EOF
+<?xml version="1.0" encoding="UTF-8" ?>
+<foo>
+    <bar class="baz"/>
+</foo>
+EOF;
+        $document = new DOMDocument();
+        $document->loadXML($xml, 524288 /* LIBXML_PARSEHUGE */);
+        $this->query->setDocument($document);
+        $test = $this->query->query('.baz');
+        $this->assertTrue($test instanceof Zend_Dom_Query_Result);
+        $testDocument = $test->getDocument();
+        $this->assertTrue($testDocument instanceof DOMDocument);
+        $this->assertEquals('UTF-8', $testDocument->encoding);
+    }
+
     /**
      * @group ZF-9243
      */