PageRenderTime 49ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Dom/Query.php

https://github.com/jverkoey/snaapilookup
PHP | 221 lines | 100 code | 18 blank | 103 comment | 8 complexity | 693b8355d44024cfeb741db1fd1cc684 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Dom
  17. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. */
  20. /**
  21. * @see Zend_Dom_Query_Css2Xpath
  22. */
  23. require_once 'Zend/Dom/Query/Css2Xpath.php';
  24. /**
  25. * @see Zend_Dom_Query_Result
  26. */
  27. require_once 'Zend/Dom/Query/Result.php';
  28. /**
  29. * Query DOM structures based on CSS selectors and/or XPath
  30. *
  31. * @package Zend_Dom
  32. * @subpackage Query
  33. * @copyright Copyright (C) 2008 - Present, Zend Technologies, Inc.
  34. * @license New BSD {@link http://framework.zend.com/license/new-bsd}
  35. */
  36. class Zend_Dom_Query
  37. {
  38. /**#@+
  39. * @const string Document types
  40. */
  41. const DOC_XML = 'docXml';
  42. const DOC_HTML = 'docHtml';
  43. const DOC_XHTML = 'docXhtml';
  44. /**#@-*/
  45. /**
  46. * @var string
  47. */
  48. protected $_document;
  49. /**
  50. * Document type
  51. * @var string
  52. */
  53. protected $_docType;
  54. /**
  55. * Constructor
  56. *
  57. * @param null|string $document
  58. * @return void
  59. */
  60. public function __construct($document = null)
  61. {
  62. if (null !== $document) {
  63. $this->setDocument($document);
  64. }
  65. }
  66. /**
  67. * Set document to query
  68. *
  69. * @param string $document
  70. * @return Zend_Dom_Query
  71. */
  72. public function setDocument($document)
  73. {
  74. if ('<?xml' == substr(trim($document), 0, 5)) {
  75. return $this->setDocumentXml($document);
  76. }
  77. if (strstr($document, 'DTD XHTML')) {
  78. return $this->setDocumentXhtml($document);
  79. }
  80. return $this->setDocumentHtml($document);
  81. }
  82. /**
  83. * Register HTML document
  84. *
  85. * @param string $document
  86. * @return Zend_Dom_Query
  87. */
  88. public function setDocumentHtml($document)
  89. {
  90. $this->_document = (string) $document;
  91. $this->_docType = self::DOC_HTML;
  92. return $this;
  93. }
  94. /**
  95. * Register XHTML document
  96. *
  97. * @param string $document
  98. * @return Zend_Dom_Query
  99. */
  100. public function setDocumentXhtml($document)
  101. {
  102. $this->_document = (string) $document;
  103. $this->_docType = self::DOC_XHTML;
  104. return $this;
  105. }
  106. /**
  107. * Register XML document
  108. *
  109. * @param string $document
  110. * @return Zend_Dom_Query
  111. */
  112. public function setDocumentXml($document)
  113. {
  114. $this->_document = (string) $document;
  115. $this->_docType = self::DOC_XML;
  116. return $this;
  117. }
  118. /**
  119. * Retrieve current document
  120. *
  121. * @return string
  122. */
  123. public function getDocument()
  124. {
  125. return $this->_document;
  126. }
  127. /**
  128. * Get document type
  129. *
  130. * @return string
  131. */
  132. public function getDocumentType()
  133. {
  134. return $this->_docType;
  135. }
  136. /**
  137. * Perform a CSS selector query
  138. *
  139. * @param string $query
  140. * @return Zend_Dom_Query_Result
  141. */
  142. public function query($query)
  143. {
  144. $xpathQuery = Zend_Dom_Query_Css2Xpath::transform($query);
  145. return $this->queryXpath($xpathQuery, $query);
  146. }
  147. /**
  148. * Perform an XPath query
  149. *
  150. * @param string $xpathQuery
  151. * @param string $query CSS selector query
  152. * @return Zend_Dom_Query_Result
  153. */
  154. public function queryXpath($xpathQuery, $query = null)
  155. {
  156. if (null === ($document = $this->getDocument())) {
  157. require_once 'Zend/Dom/Exception.php';
  158. throw new Zend_Dom_Exception('Cannot query; no document registered');
  159. }
  160. $domDoc = new DOMDocument;
  161. $type = $this->getDocumentType();
  162. switch ($type) {
  163. case self::DOC_XML:
  164. $success = @$domDoc->loadXML($document);
  165. break;
  166. case self::DOC_HTML:
  167. case self::DOC_XHTML:
  168. default:
  169. $success = @$domDoc->loadHTML($document);
  170. break;
  171. }
  172. if (!$success) {
  173. require_once 'Zend/Dom/Exception.php';
  174. throw new Zend_Dom_Exception(sprintf('Error parsing document (type == %s)', $type));
  175. }
  176. $nodeList = $this->_getNodeList($domDoc, $xpathQuery);
  177. return new Zend_Dom_Query_Result($query, $xpathQuery, $domDoc, $nodeList);
  178. }
  179. /**
  180. * Prepare node list
  181. *
  182. * @param DOMDocument $document
  183. * @param string|array $xpathQuery
  184. * @return array
  185. */
  186. protected function _getNodeList($document, $xpathQuery)
  187. {
  188. $xpath = new DOMXPath($document);
  189. $xpathQuery = (string) $xpathQuery;
  190. if (preg_match_all('|\[contains\((@[a-z0-9_-]+),\s?\' |i', $xpathQuery, $matches)) {
  191. foreach ($matches[1] as $attribute) {
  192. $queryString = '//*[' . $attribute . ']';
  193. $attributeName = substr($attribute, 1);
  194. $nodes = $xpath->query($queryString);
  195. foreach ($nodes as $node) {
  196. $attr = $node->attributes->getNamedItem($attributeName);
  197. $attr->value = ' ' . $attr->value . ' ';
  198. }
  199. }
  200. }
  201. return $xpath->query($xpathQuery);
  202. }
  203. }