PageRenderTime 25ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/manageQuickBooks/QuickBooks/XML/Parser.php

https://github.com/kjavitz/SalesIgniter1
PHP | 240 lines | 92 code | 28 blank | 120 comment | 14 complexity | 655523878bb2c3b65847f938691920f3 MD5 | raw file
  1. <?php
  2. /**
  3. * Simple QuickBooks XML parsing class
  4. *
  5. * Copyright (c) 2010-04-16 Keith Palmer / ConsoliBYTE, LLC.
  6. * All rights reserved. This program and the accompanying materials
  7. * are made available under the terms of the Eclipse Public License v1.0
  8. * which accompanies this distribution, and is available at
  9. * http://www.opensource.org/licenses/eclipse-1.0.php
  10. *
  11. * This is intended as a simple alternative to the PHP SimpleXML or DOM
  12. * extensions (some of the machines I'm working on don't have the SimpleXML
  13. * extension enabled) for parsing XML documents.
  14. *
  15. * @author Keith Palmer <keith@consolibyte.com>
  16. * @license LICENSE.txt
  17. *
  18. * @package QuickBooks
  19. * @subpackage XML
  20. */
  21. /**
  22. * XML base constants
  23. */
  24. QuickBooks_Loader::load('/QuickBooks/XML.php');
  25. /**
  26. * XML_Node class
  27. */
  28. QuickBooks_Loader::load('/QuickBooks/XML/Node.php');
  29. /**
  30. * XML_Document class
  31. */
  32. QuickBooks_Loader::load('/QuickBooks/XML/Document.php');
  33. /**
  34. * XML backend interface
  35. */
  36. QuickBooks_Loader::load('/QuickBooks/XML/Backend.php');
  37. /**
  38. * XML parser backends
  39. */
  40. QuickBooks_Loader::import('/QuickBooks/XML/Backend');
  41. /**
  42. * QuickBooks XML Parser
  43. *
  44. * Create an instance of the QuickBooks_XML parser by calling the constructor
  45. * with either a file-path or the contents of an XML document.
  46. * <code>
  47. * $xml = '<Tag1><NestedTag age="25" gender="male"><AnotherTag>Keith</AnotherTag></NestedTag></Tag1>';
  48. *
  49. * // Create the new object
  50. * $Parser = new QuickBooks_XML_Parser($xml);
  51. *
  52. * // Parse the XML document
  53. * $errnum = 0;
  54. * $errmsg = '';
  55. * if ($Parser->validate($errnum, $errmsg))
  56. * {
  57. * $Doc = $Parser->parse($errnum, $errmsg);
  58. *
  59. * // Now fetch some stuff from the parsed document
  60. * print('Hello there ' . $Doc->getChildDataAt('Tag1 NestedTag AnotherTag') . "\n");
  61. * print_r($Doc->getChildAttributesAt('Tag1 NestedTag'));
  62. * print("\n");
  63. * print('Root tag name is: ' . $Doc->name() . "\n");
  64. *
  65. * $NestedTag = $Doc->getChildAt('Tag1 NestedTag');
  66. * print_r($NestedTag);
  67. * }
  68. * </code>
  69. */
  70. class QuickBooks_XML_Parser
  71. {
  72. /**
  73. *
  74. */
  75. protected $_xml;
  76. /**
  77. * What back-end XML parser to use
  78. * @var string
  79. */
  80. protected $_backend;
  81. /**
  82. *
  83. */
  84. const BACKEND_SIMPLEXML = 'simplexml';
  85. /**
  86. *
  87. */
  88. const BACKEND_BUILTIN = 'builtin';
  89. /**
  90. * Create a new QuickBooks_XML parser object
  91. *
  92. * @param string $xml_or_file
  93. */
  94. public function __construct($xml_or_file = null, $use_backend = null)
  95. {
  96. $xml_or_file = $this->_read($xml_or_file);
  97. $this->_xml = $xml_or_file;
  98. if (is_null($use_backend) and
  99. function_exists('simplexml_load_string'))
  100. {
  101. $use_backend = QuickBooks_XML::PARSER_SIMPLEXML;
  102. }
  103. else if (is_null($use_backend))
  104. {
  105. $use_backend = QuickBooks_XML::PARSER_BUILTIN;
  106. }
  107. $class = 'QuickBooks_XML_Backend_' . ucfirst(strtolower($use_backend));
  108. $this->_backend = new $class($xml_or_file);
  109. }
  110. /**
  111. * Read an open file descriptor, XML file, or string
  112. *
  113. * @param mixed $mixed
  114. * @return string
  115. */
  116. protected function _read($mixed)
  117. {
  118. if (empty($mixed))
  119. {
  120. return '';
  121. }
  122. else if (is_resource($mixed) and
  123. get_resource_type($mixed) == 'stream')
  124. {
  125. $buffer = '';
  126. $tmp = '';
  127. while ($tmp = fread($mixed, 8192))
  128. {
  129. $buffer .= $tmp;
  130. }
  131. return $buffer;
  132. }
  133. else if (substr(trim($mixed), 0, 1) != '<')
  134. {
  135. return file_get_contents($mixed);
  136. }
  137. return $mixed;
  138. }
  139. /**
  140. * Load the XML parser with data from a string or file
  141. *
  142. * @param string $xml_or_file An XML string or
  143. * @return integer
  144. */
  145. public function load($xml_or_file)
  146. {
  147. $xml_or_file = $this->_read($xml_or_file);
  148. $this->_xml = $xml_or_file;
  149. return $this->_backend->load($xml_or_file);
  150. }
  151. /**
  152. * Check if the XML document is valid
  153. *
  154. * *** WARNING *** This does not check against the actual QuickBooks
  155. * schemas, and in reality even the XML validation stuff it *does* do is
  156. * pretty light. You should probably double check any validation you're
  157. * doing in a better XML validator.
  158. *
  159. * @param integer $errnum
  160. * @param string $errmsg
  161. * @return boolean
  162. */
  163. public function validate(&$errnum, &$errmsg)
  164. {
  165. return $this->_backend->validate($errnum, $errmsg);
  166. }
  167. /**
  168. *
  169. */
  170. public function beautify(&$errnum, &$errmsg, $compress_empty_elements = true)
  171. {
  172. $errnum = 0;
  173. $errmsg = '';
  174. $Node = $this->parse($errnum, $errmsg);
  175. if (!$errnum and is_object($Node))
  176. {
  177. return $Node->asXML($compress_empty_elements);
  178. }
  179. return false;
  180. }
  181. /**
  182. * Parse an XML document into an XML node structure
  183. *
  184. * This function returns either a QuickBooks_XML_Node on success, or false
  185. * on failure. You can use the ->validate() method first so you can tell
  186. * whether or not the parser will succeed.
  187. *
  188. * @param integer $errnum
  189. * @param string $errmsg
  190. * @return QuickBooks_XML_Node
  191. */
  192. public function parse(&$errnum, &$errmsg)
  193. {
  194. if (!strlen($this->_xml))
  195. {
  196. $errnum = QuickBooks_XML::ERROR_CONTENT;
  197. $errmsg = 'No XML content to parse.';
  198. return false;
  199. }
  200. // first, let's remove all of the comments
  201. if ($this->validate($errnum, $errmsg))
  202. {
  203. return $this->_backend->parse($errnum, $errmsg);
  204. }
  205. return false;
  206. }
  207. public function backend()
  208. {
  209. $str = get_class($this->_backend);
  210. return str_replace('quickbooks_xml_backend_', '', strtolower($str));
  211. }
  212. }