314 Zeilen
		
	
	
	
		
			8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			314 Zeilen
		
	
	
	
		
			8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Zend Framework
 | |
|  *
 | |
|  * LICENSE
 | |
|  *
 | |
|  * This source file is subject to the new BSD license that is bundled
 | |
|  * with this package in the file LICENSE.txt.
 | |
|  * It is also available through the world-wide-web at this URL:
 | |
|  * http://framework.zend.com/license/new-bsd
 | |
|  * If you did not receive a copy of the license and are unable to
 | |
|  * obtain it through the world-wide-web, please send an email
 | |
|  * to license@zend.com so we can send you a copy immediately.
 | |
|  *
 | |
|  * @category   Zend
 | |
|  * @package    Zend_Dom
 | |
|  * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 | |
|  * @license    http://framework.zend.com/license/new-bsd     New BSD License
 | |
|  * @version    $Id$
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * @see Zend_Dom_Query_Css2Xpath
 | |
|  */
 | |
| require_once 'Zend/Dom/Query/Css2Xpath.php';
 | |
| 
 | |
| /**
 | |
|  * @see Zend_Dom_Query_Result
 | |
|  */
 | |
| require_once 'Zend/Dom/Query/Result.php';
 | |
| 
 | |
| /**
 | |
|  * Query DOM structures based on CSS selectors and/or XPath
 | |
|  *
 | |
|  * @package    Zend_Dom
 | |
|  * @subpackage Query
 | |
|  * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 | |
|  * @license    http://framework.zend.com/license/new-bsd     New BSD License
 | |
|  */
 | |
| class Zend_Dom_Query
 | |
| {
 | |
|     /**#@+
 | |
|      * Document types
 | |
|      */
 | |
|     const DOC_XML   = 'docXml';
 | |
|     const DOC_HTML  = 'docHtml';
 | |
|     const DOC_XHTML = 'docXhtml';
 | |
|     /**#@-*/
 | |
| 
 | |
|     /**
 | |
|      * @var string
 | |
|      */
 | |
|     protected $_document;
 | |
| 
 | |
|     /**
 | |
|      * DOMDocument errors, if any
 | |
|      * @var false|array
 | |
|      */
 | |
|     protected $_documentErrors = false;
 | |
| 
 | |
|     /**
 | |
|      * Document type
 | |
|      * @var string
 | |
|      */
 | |
|     protected $_docType;
 | |
| 
 | |
|     /**
 | |
|      * Document encoding
 | |
|      * @var null|string
 | |
|      */
 | |
|     protected $_encoding;
 | |
| 
 | |
|     /**
 | |
|      * XPath namespaces
 | |
|      * @var array
 | |
|      */
 | |
|     protected $_xpathNamespaces = array();
 | |
| 
 | |
|     /**
 | |
|      * Constructor
 | |
|      *
 | |
|      * @param  null|string $document
 | |
|      * @return void
 | |
|      */
 | |
|     public function __construct($document = null, $encoding = null)
 | |
|     {
 | |
|         $this->setEncoding($encoding);
 | |
|         $this->setDocument($document);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set document encoding
 | |
|      *
 | |
|      * @param  string $encoding
 | |
|      * @return Zend_Dom_Query
 | |
|      */
 | |
|     public function setEncoding($encoding)
 | |
|     {
 | |
|         $this->_encoding = (null === $encoding) ? null : (string) $encoding;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get document encoding
 | |
|      *
 | |
|      * @return null|string
 | |
|      */
 | |
|     public function getEncoding()
 | |
|     {
 | |
|         return $this->_encoding;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set document to query
 | |
|      *
 | |
|      * @param  string $document
 | |
|      * @param  null|string $encoding Document encoding
 | |
|      * @return Zend_Dom_Query
 | |
|      */
 | |
|     public function setDocument($document, $encoding = null)
 | |
|     {
 | |
|         if (0 === strlen($document)) {
 | |
|             return $this;
 | |
|         }
 | |
|         // breaking XML declaration to make syntax highlighting work
 | |
|         if ('<' . '?xml' == substr(trim($document), 0, 5)) {
 | |
|             return $this->setDocumentXml($document, $encoding);
 | |
|         }
 | |
|         if (strstr($document, 'DTD XHTML')) {
 | |
|             return $this->setDocumentXhtml($document, $encoding);
 | |
|         }
 | |
|         return $this->setDocumentHtml($document, $encoding);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Register HTML document
 | |
|      *
 | |
|      * @param  string $document
 | |
|      * @param  null|string $encoding Document encoding
 | |
|      * @return Zend_Dom_Query
 | |
|      */
 | |
|     public function setDocumentHtml($document, $encoding = null)
 | |
|     {
 | |
|         $this->_document = (string) $document;
 | |
|         $this->_docType  = self::DOC_HTML;
 | |
|         if (null !== $encoding) {
 | |
|             $this->setEncoding($encoding);
 | |
|         }
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Register XHTML document
 | |
|      *
 | |
|      * @param  string $document
 | |
|      * @param  null|string $encoding Document encoding
 | |
|      * @return Zend_Dom_Query
 | |
|      */
 | |
|     public function setDocumentXhtml($document, $encoding = null)
 | |
|     {
 | |
|         $this->_document = (string) $document;
 | |
|         $this->_docType  = self::DOC_XHTML;
 | |
|         if (null !== $encoding) {
 | |
|             $this->setEncoding($encoding);
 | |
|         }
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Register XML document
 | |
|      *
 | |
|      * @param  string $document
 | |
|      * @param  null|string $encoding Document encoding
 | |
|      * @return Zend_Dom_Query
 | |
|      */
 | |
|     public function setDocumentXml($document, $encoding = null)
 | |
|     {
 | |
|         $this->_document = (string) $document;
 | |
|         $this->_docType  = self::DOC_XML;
 | |
|         if (null !== $encoding) {
 | |
|             $this->setEncoding($encoding);
 | |
|         }
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Retrieve current document
 | |
|      *
 | |
|      * @return string
 | |
|      */
 | |
|     public function getDocument()
 | |
|     {
 | |
|         return $this->_document;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get document type
 | |
|      *
 | |
|      * @return string
 | |
|      */
 | |
|     public function getDocumentType()
 | |
|     {
 | |
|         return $this->_docType;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get any DOMDocument errors found
 | |
|      *
 | |
|      * @return false|array
 | |
|      */
 | |
|     public function getDocumentErrors()
 | |
|     {
 | |
|         return $this->_documentErrors;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Perform a CSS selector query
 | |
|      *
 | |
|      * @param  string $query
 | |
|      * @return Zend_Dom_Query_Result
 | |
|      */
 | |
|     public function query($query)
 | |
|     {
 | |
|         $xpathQuery = Zend_Dom_Query_Css2Xpath::transform($query);
 | |
|         return $this->queryXpath($xpathQuery, $query);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Perform an XPath query
 | |
|      *
 | |
|      * @param  string|array $xpathQuery
 | |
|      * @param  string $query CSS selector query
 | |
|      * @return Zend_Dom_Query_Result
 | |
|      */
 | |
|     public function queryXpath($xpathQuery, $query = null)
 | |
|     {
 | |
|         if (null === ($document = $this->getDocument())) {
 | |
|             require_once 'Zend/Dom/Exception.php';
 | |
|             throw new Zend_Dom_Exception('Cannot query; no document registered');
 | |
|         }
 | |
| 
 | |
|         $encoding = $this->getEncoding();
 | |
|         libxml_use_internal_errors(true);
 | |
|         if (null === $encoding) {
 | |
|             $domDoc = new DOMDocument('1.0');
 | |
|         } else {
 | |
|             $domDoc = new DOMDocument('1.0', $encoding);
 | |
|         }
 | |
|         $type   = $this->getDocumentType();
 | |
|         switch ($type) {
 | |
|             case self::DOC_XML:
 | |
|                 $success = $domDoc->loadXML($document);
 | |
|                 break;
 | |
|             case self::DOC_HTML:
 | |
|             case self::DOC_XHTML:
 | |
|             default:
 | |
|                 $success = $domDoc->loadHTML($document);
 | |
|                 break;
 | |
|         }
 | |
|         $errors = libxml_get_errors();
 | |
|         if (!empty($errors)) {
 | |
|             $this->_documentErrors = $errors;
 | |
|             libxml_clear_errors();
 | |
|         }
 | |
|         libxml_use_internal_errors(false);
 | |
| 
 | |
|         if (!$success) {
 | |
|             require_once 'Zend/Dom/Exception.php';
 | |
|             throw new Zend_Dom_Exception(sprintf('Error parsing document (type == %s)', $type));
 | |
|         }
 | |
| 
 | |
|         $nodeList   = $this->_getNodeList($domDoc, $xpathQuery);
 | |
|         return new Zend_Dom_Query_Result($query, $xpathQuery, $domDoc, $nodeList);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Register XPath namespaces
 | |
|      *
 | |
|      * @param   array $xpathNamespaces
 | |
|      * @return  void
 | |
|      */
 | |
|     public function registerXpathNamespaces($xpathNamespaces)
 | |
|     {
 | |
|         $this->_xpathNamespaces = $xpathNamespaces;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Prepare node list
 | |
|      *
 | |
|      * @param  DOMDocument $document
 | |
|      * @param  string|array $xpathQuery
 | |
|      * @return array
 | |
|      */
 | |
|     protected function _getNodeList($document, $xpathQuery)
 | |
|     {
 | |
|         $xpath      = new DOMXPath($document);
 | |
|         foreach ($this->_xpathNamespaces as $prefix => $namespaceUri) {
 | |
|             $xpath->registerNamespace($prefix, $namespaceUri);
 | |
|         }
 | |
|         $xpathQuery = (string) $xpathQuery;
 | |
|         if (preg_match_all('|\[contains\((@[a-z0-9_-]+),\s?\' |i', $xpathQuery, $matches)) {
 | |
|             foreach ($matches[1] as $attribute) {
 | |
|                 $queryString = '//*[' . $attribute . ']';
 | |
|                 $attributeName = substr($attribute, 1);
 | |
|                 $nodes = $xpath->query($queryString);
 | |
|                 foreach ($nodes as $node) {
 | |
|                     $attr = $node->attributes->getNamedItem($attributeName);
 | |
|                     $attr->value = ' ' . $attr->value . ' ';
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return $xpath->query($xpathQuery);
 | |
|     }
 | |
| }
 |