/ojs/ojs-2.2.1/classes/xml/XMLParser.inc.php

https://github.com/mcrider/pkpUpgradeTestSuite · PHP · 214 lines · 104 code · 37 blank · 73 comment · 14 complexity · 11ab66965abfb8b5f473be27856b8c0c MD5 · raw file

  1. <?php
  2. /**
  3. * @defgroup xml
  4. */
  5. /**
  6. * @file classes/xml/XMLParser.inc.php
  7. *
  8. * Copyright (c) 2003-2008 John Willinsky
  9. * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
  10. *
  11. * @class XMLParser
  12. * @ingroup xml
  13. *
  14. * @brief Generic class for parsing an XML document into a data structure.
  15. */
  16. // $Id: XMLParser.inc.php,v 1.15 2008/07/01 01:16:11 asmecher Exp $
  17. // The default character encodings
  18. define('XML_PARSER_SOURCE_ENCODING', Config::getVar('i18n', 'client_charset'));
  19. define('XML_PARSER_TARGET_ENCODING', Config::getVar('i18n', 'client_charset'));
  20. import('xml.XMLParserDOMHandler');
  21. class XMLParser {
  22. /** @var int original magic_quotes_runtime setting */
  23. var $magicQuotes;
  24. /** @var object instance of XMLParserHandler */
  25. var $handler;
  26. /**
  27. * Constructor.
  28. * Initialize parser and set parser options.
  29. */
  30. function XMLParser() {
  31. // magic_quotes_runtime must be disabled for XML parsing
  32. $this->magicQuotes = get_magic_quotes_runtime();
  33. set_magic_quotes_runtime(0);
  34. }
  35. /**
  36. * Parse an XML file using the specified handler.
  37. * If no handler has been specified, XMLParserDOMHandler is used by default, returning a tree structure representing the document.
  38. * @param $file string full path to the XML file
  39. * @return object actual return type depends on the handler
  40. */
  41. function &parse($file) {
  42. $parser = &$this->createParser();
  43. if (!isset($this->handler)) {
  44. // Use default handler for parsing
  45. $handler =& new XMLParserDOMHandler();
  46. $this->setHandler($handler);
  47. }
  48. xml_set_object($parser, $this->handler);
  49. xml_set_element_handler($parser, "startElement", "endElement");
  50. xml_set_character_data_handler($parser, "characterData");
  51. import('file.FileWrapper');
  52. $wrapper = &FileWrapper::wrapper($file);
  53. while (is_object($newWrapper = $wrapper->open())) if (is_object($newWrapper)) { // Handle redirects
  54. unset($wrapper);
  55. $wrapper =& $newWrapper;
  56. unset ($newWrapper);
  57. }
  58. if (!$wrapper) {
  59. $result = false;
  60. return $result;
  61. }
  62. while ($data = $wrapper->read()) {
  63. if (!xml_parse($parser, $data, $wrapper->eof())) {
  64. echo xml_error_string(xml_get_error_code($parser));
  65. $this->destroyParser($parser);
  66. $result = false;
  67. $wrapper->close();
  68. return $result;
  69. }
  70. }
  71. $wrapper->close();
  72. $this->destroyParser($parser);
  73. $result = &$this->handler->getResult();
  74. return $result;
  75. }
  76. /**
  77. * Set the handler to use for parse(...).
  78. * @param $handler XMLParserHandler
  79. */
  80. function setHandler(&$handler) {
  81. $this->handler =& $handler;
  82. }
  83. /**
  84. * Parse an XML file using xml_parse_into_struct and return data in an array.
  85. * This is best suited for XML documents with fairly simple structure.
  86. * @param $file string full path to the XML file
  87. * @param $tagsToMatch array optional, if set tags not in the array will be skipped
  88. * @return array a struct of the form ($TAG => array('attributes' => array( ... ), 'value' => $VALUE), ... )
  89. */
  90. function &parseStruct($file, $tagsToMatch = array()) {
  91. $parser = &$this->createParser();
  92. import('file.FileWrapper');
  93. $wrapper = &FileWrapper::wrapper($file);
  94. $fileContents = $wrapper->contents();
  95. if (!$fileContents) {
  96. $result = false;
  97. return $result;
  98. }
  99. xml_parse_into_struct($parser, $fileContents, $values, $tags);
  100. $this->destroyParser($parser);
  101. // Clean up data struct, removing undesired tags if necessary
  102. foreach ($tags as $key => $indices) {
  103. if (!empty($tagsToMatch) && !in_array($key, $tagsToMatch)) {
  104. continue;
  105. }
  106. $data[$key] = array();
  107. foreach ($indices as $index) {
  108. if (!isset($values[$index]['type']) || ($values[$index]['type'] != 'open' && $values[$index]['type'] != 'complete')) {
  109. continue;
  110. }
  111. $data[$key][] = array(
  112. 'attributes' => isset($values[$index]['attributes']) ? $values[$index]['attributes'] : array(),
  113. 'value' => isset($values[$index]['value']) ? trim($values[$index]['value']) : ''
  114. );
  115. }
  116. }
  117. return $data;
  118. }
  119. /**
  120. * Initialize a new XML parser.
  121. * @return resource
  122. */
  123. function &createParser() {
  124. $parser = xml_parser_create(XML_PARSER_SOURCE_ENCODING);
  125. xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, XML_PARSER_TARGET_ENCODING);
  126. xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
  127. return $parser;
  128. }
  129. /**
  130. * Destroy XML parser.
  131. * @param $parser resource
  132. */
  133. function destroyParser(&$parser) {
  134. xml_parser_free($parser);
  135. unset($parser);
  136. }
  137. /**
  138. * Perform required clean up for this object.
  139. */
  140. function destroy() {
  141. // Set magic_quotes_runtime back to original setting
  142. set_magic_quotes_runtime($this->magicQuotes);
  143. unset($this);
  144. }
  145. }
  146. /**
  147. * Interface for handler class used by XMLParser.
  148. * All XML parser handler classes must implement these methods.
  149. */
  150. class XMLParserHandler {
  151. /**
  152. * Callback function to act as the start element handler.
  153. */
  154. function startElement(&$parser, $tag, $attributes) {
  155. }
  156. /**
  157. * Callback function to act as the end element handler.
  158. */
  159. function endElement(&$parser, $tag) {
  160. }
  161. /**
  162. * Callback function to act as the character data handler.
  163. */
  164. function characterData(&$parser, $data) {
  165. }
  166. /**
  167. * Returns a resulting data structure representing the parsed content.
  168. * The format of this object is specific to the handler.
  169. * @return mixed
  170. */
  171. function &getResult() {
  172. // Default: Return null (must be by ref).
  173. $nullVar = null;
  174. return $nullVar;
  175. }
  176. }
  177. ?>