PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/pear/XML/Parser/Simple.php

http://github.com/moodle/moodle
PHP | 326 lines | 96 code | 21 blank | 209 comment | 10 complexity | e972793f4be2ecbe79d672eaacb0036f MD5 | raw file
Possible License(s): MIT, AGPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, Apache-2.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * XML_Parser
  5. *
  6. * XML Parser's Simple parser class
  7. *
  8. * PHP versions 4 and 5
  9. *
  10. * LICENSE:
  11. *
  12. * Copyright (c) 2002-2008 The PHP Group
  13. * All rights reserved.
  14. *
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions
  17. * are met:
  18. *
  19. * * Redistributions of source code must retain the above copyright
  20. * notice, this list of conditions and the following disclaimer.
  21. * * Redistributions in binary form must reproduce the above copyright
  22. * notice, this list of conditions and the following disclaimer in the
  23. * documentation and/or other materials provided with the distribution.
  24. * * The name of the author may not be used to endorse or promote products
  25. * derived from this software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  28. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  29. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  30. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  31. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  32. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  33. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  34. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  35. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  36. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. * @category XML
  40. * @package XML_Parser
  41. * @author Stephan Schmidt <schst@php.net>
  42. * @copyright 2004-2008 Stephan Schmidt <schst@php.net>
  43. * @license http://opensource.org/licenses/bsd-license New BSD License
  44. * @version CVS: $Id$
  45. * @link http://pear.php.net/package/XML_Parser
  46. */
  47. /**
  48. * built on XML_Parser
  49. */
  50. require_once 'XML/Parser.php';
  51. /**
  52. * Simple XML parser class.
  53. *
  54. * This class is a simplified version of XML_Parser.
  55. * In most XML applications the real action is executed,
  56. * when a closing tag is found.
  57. *
  58. * XML_Parser_Simple allows you to just implement one callback
  59. * for each tag that will receive the tag with its attributes
  60. * and CData.
  61. *
  62. * <code>
  63. * require_once '../Parser/Simple.php';
  64. *
  65. * class myParser extends XML_Parser_Simple
  66. * {
  67. * function myParser()
  68. * {
  69. * $this->XML_Parser_Simple();
  70. * }
  71. *
  72. * function handleElement($name, $attribs, $data)
  73. * {
  74. * printf('handle %s<br>', $name);
  75. * }
  76. * }
  77. *
  78. * $p = &new myParser();
  79. *
  80. * $result = $p->setInputFile('myDoc.xml');
  81. * $result = $p->parse();
  82. * </code>
  83. *
  84. * @category XML
  85. * @package XML_Parser
  86. * @author Stephan Schmidt <schst@php.net>
  87. * @copyright 2004-2008 The PHP Group
  88. * @license http://opensource.org/licenses/bsd-license New BSD License
  89. * @version Release: @package_version@
  90. * @link http://pear.php.net/package/XML_Parser
  91. */
  92. class XML_Parser_Simple extends XML_Parser
  93. {
  94. /**
  95. * element stack
  96. *
  97. * @access private
  98. * @var array
  99. */
  100. var $_elStack = array();
  101. /**
  102. * all character data
  103. *
  104. * @access private
  105. * @var array
  106. */
  107. var $_data = array();
  108. /**
  109. * element depth
  110. *
  111. * @access private
  112. * @var integer
  113. */
  114. var $_depth = 0;
  115. /**
  116. * Mapping from expat handler function to class method.
  117. *
  118. * @var array
  119. */
  120. var $handler = array(
  121. 'default_handler' => 'defaultHandler',
  122. 'processing_instruction_handler' => 'piHandler',
  123. 'unparsed_entity_decl_handler' => 'unparsedHandler',
  124. 'notation_decl_handler' => 'notationHandler',
  125. 'external_entity_ref_handler' => 'entityrefHandler'
  126. );
  127. /**
  128. * Creates an XML parser.
  129. *
  130. * This is needed for PHP4 compatibility, it will
  131. * call the constructor, when a new instance is created.
  132. *
  133. * @param string $srcenc source charset encoding, use NULL (default) to use
  134. * whatever the document specifies
  135. * @param string $mode how this parser object should work, "event" for
  136. * handleElement(), "func" to have it call functions
  137. * named after elements (handleElement_$name())
  138. * @param string $tgtenc a valid target encoding
  139. */
  140. function XML_Parser_Simple($srcenc = null, $mode = 'event', $tgtenc = null)
  141. {
  142. $this->XML_Parser($srcenc, $mode, $tgtenc);
  143. }
  144. /**
  145. * inits the handlers
  146. *
  147. * @return mixed
  148. * @access private
  149. */
  150. function _initHandlers()
  151. {
  152. if (!is_object($this->_handlerObj)) {
  153. $this->_handlerObj = &$this;
  154. }
  155. if ($this->mode != 'func' && $this->mode != 'event') {
  156. return $this->raiseError('Unsupported mode given',
  157. XML_PARSER_ERROR_UNSUPPORTED_MODE);
  158. }
  159. xml_set_object($this->parser, $this->_handlerObj);
  160. xml_set_element_handler($this->parser, array(&$this, 'startHandler'),
  161. array(&$this, 'endHandler'));
  162. xml_set_character_data_handler($this->parser, array(&$this, 'cdataHandler'));
  163. /**
  164. * set additional handlers for character data, entities, etc.
  165. */
  166. foreach ($this->handler as $xml_func => $method) {
  167. if (method_exists($this->_handlerObj, $method)) {
  168. $xml_func = 'xml_set_' . $xml_func;
  169. $xml_func($this->parser, $method);
  170. }
  171. }
  172. }
  173. /**
  174. * Reset the parser.
  175. *
  176. * This allows you to use one parser instance
  177. * to parse multiple XML documents.
  178. *
  179. * @access public
  180. * @return boolean|object true on success, PEAR_Error otherwise
  181. */
  182. function reset()
  183. {
  184. $this->_elStack = array();
  185. $this->_data = array();
  186. $this->_depth = 0;
  187. $result = $this->_create();
  188. if ($this->isError($result)) {
  189. return $result;
  190. }
  191. return true;
  192. }
  193. /**
  194. * start handler
  195. *
  196. * Pushes attributes and tagname onto a stack
  197. *
  198. * @param resource $xp xml parser resource
  199. * @param string $elem element name
  200. * @param array &$attribs attributes
  201. *
  202. * @return mixed
  203. * @access private
  204. * @final
  205. */
  206. function startHandler($xp, $elem, &$attribs)
  207. {
  208. array_push($this->_elStack, array(
  209. 'name' => $elem,
  210. 'attribs' => $attribs
  211. ));
  212. $this->_depth++;
  213. $this->_data[$this->_depth] = '';
  214. }
  215. /**
  216. * end handler
  217. *
  218. * Pulls attributes and tagname from a stack
  219. *
  220. * @param resource $xp xml parser resource
  221. * @param string $elem element name
  222. *
  223. * @return mixed
  224. * @access private
  225. * @final
  226. */
  227. function endHandler($xp, $elem)
  228. {
  229. $el = array_pop($this->_elStack);
  230. $data = $this->_data[$this->_depth];
  231. $this->_depth--;
  232. switch ($this->mode) {
  233. case 'event':
  234. $this->_handlerObj->handleElement($el['name'], $el['attribs'], $data);
  235. break;
  236. case 'func':
  237. $func = 'handleElement_' . $elem;
  238. if (strchr($func, '.')) {
  239. $func = str_replace('.', '_', $func);
  240. }
  241. if (method_exists($this->_handlerObj, $func)) {
  242. call_user_func(array(&$this->_handlerObj, $func),
  243. $el['name'], $el['attribs'], $data);
  244. }
  245. break;
  246. }
  247. }
  248. /**
  249. * handle character data
  250. *
  251. * @param resource $xp xml parser resource
  252. * @param string $data data
  253. *
  254. * @return void
  255. * @access private
  256. * @final
  257. */
  258. function cdataHandler($xp, $data)
  259. {
  260. $this->_data[$this->_depth] .= $data;
  261. }
  262. /**
  263. * handle a tag
  264. *
  265. * Implement this in your parser
  266. *
  267. * @param string $name element name
  268. * @param array $attribs attributes
  269. * @param string $data character data
  270. *
  271. * @return void
  272. * @access public
  273. * @abstract
  274. */
  275. function handleElement($name, $attribs, $data)
  276. {
  277. }
  278. /**
  279. * get the current tag depth
  280. *
  281. * The root tag is in depth 0.
  282. *
  283. * @access public
  284. * @return integer
  285. */
  286. function getCurrentDepth()
  287. {
  288. return $this->_depth;
  289. }
  290. /**
  291. * add some string to the current ddata.
  292. *
  293. * This is commonly needed, when a document is parsed recursively.
  294. *
  295. * @param string $data data to add
  296. *
  297. * @return void
  298. * @access public
  299. */
  300. function addToData($data)
  301. {
  302. $this->_data[$this->_depth] .= $data;
  303. }
  304. }
  305. ?>