PageRenderTime 28ms CodeModel.GetById 14ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/class/xml/saxparser.php

https://gitlab.com/VoyaTrax/vtCMS
PHP | 373 lines | 204 code | 40 blank | 129 comment | 20 complexity | 92b35e8f4b9bae6070b1cd73adeb3159 MD5 | raw file
  1<?php
  2// $Id: saxparser.php 2 2005-11-02 18:23:29Z skalpa $
  3/*******************************************************************************
  4    Location: <b>xml/SaxParser.class</b><br>
  5     <br>
  6    Provides basic functionality to read and parse XML documents.  Subclasses
  7    must implement all the their custom handlers by using add* function methods.
  8    They may also use the handle*() methods to parse a specific XML begin and end
  9    tags, but this is not recommended as it is more difficult.<br>
 10    <br>
 11    Copyright &copy; 2001 eXtremePHP.  All rights reserved.<br>
 12    <br>
 13    @author Ken Egervari<br>
 14*******************************************************************************/
 15
 16class SaxParser
 17{
 18    var $level;
 19    var $parser;
 20
 21    var $isCaseFolding;
 22    var $targetEncoding;
 23
 24    /* Custom Handler Variables */
 25    var $tagHandlers = array();
 26
 27    /* Tag stack */
 28    var $tags = array();
 29
 30    /* Xml Source Input */
 31    var $xmlInput;
 32
 33    var $errors = array();
 34
 35    /****************************************************************************
 36        Creates a SaxParser object using a FileInput to represent the stream
 37        of XML data to parse.  Use the static methods createFileInput or
 38        createStringInput to construct xml input source objects to supply
 39        to the constructor, or the implementor can construct them individually.
 40    ****************************************************************************/
 41    function __construct($input)
 42    {
 43        $this->level = 0;
 44        $this->parser = xml_parser_create('UTF-8');
 45        xml_set_object($this->parser, $this);
 46        $this->input =& $input;
 47        $this->setCaseFolding(false);
 48        $this->useUtfEncoding();
 49        xml_set_element_handler($this->parser, 'handleBeginElement','handleEndElement');
 50        xml_set_character_data_handler($this->parser, 'handleCharacterData');
 51        xml_set_processing_instruction_handler($this->parser, 'handleProcessingInstruction');
 52        xml_set_default_handler($this->parser, 'handleDefault');
 53        xml_set_unparsed_entity_decl_handler($this->parser, 'handleUnparsedEntityDecl');
 54        xml_set_notation_decl_handler($this->parser, 'handleNotationDecl');
 55        xml_set_external_entity_ref_handler($this->parser, 'handleExternalEntityRef');
 56    }
 57
 58    /*---------------------------------------------------------------------------
 59        Property Methods
 60    ---------------------------------------------------------------------------*/
 61
 62    function getCurrentLevel()
 63    {
 64        return $this->level;
 65    }
 66
 67    /****************************************************************************
 68        * @param $isCaseFolding
 69        * @returns void
 70    ****************************************************************************/
 71    function setCaseFolding($isCaseFolding)
 72    {
 73        assert(is_bool($isCaseFolding));
 74
 75        $this->isCaseFolding = $isCaseFolding;
 76        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, $this->isCaseFolding);
 77    }
 78
 79    /****************************************************************************
 80        * @returns void
 81    ****************************************************************************/
 82    function useIsoEncoding()
 83    {
 84        $this->targetEncoding = 'ISO-8859-1';
 85        xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->targetEncoding);
 86    }
 87
 88    /****************************************************************************
 89        * @returns void
 90    ****************************************************************************/
 91    function useAsciiEncoding()
 92    {
 93        $this->targetEncoding = 'US-ASCII';
 94        xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->targetEncoding);
 95    }
 96
 97    /****************************************************************************
 98        * @returns void
 99    ****************************************************************************/
100    function useUtfEncoding()
101    {
102        $this->targetEncoding = 'UTF-8';
103        xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->targetEncoding);
104    }
105
106    /****************************************************************************
107        Returns the name of the xml tag being parsed
108        * @returns string
109    ****************************************************************************/
110    function getCurrentTag()
111    {
112        return $this->tags[count($this->tags) - 1];
113    }
114
115    function getParentTag()
116    {
117        if (isset($this->tags[count($this->tags) - 2])) {
118            return $this->tags[count($this->tags) - 2];
119        }
120        return false;
121    }
122
123
124
125    /*---------------------------------------------------------------------------
126        Parser methods
127    ---------------------------------------------------------------------------*/
128
129    /****************************************************************************
130        * @returns void
131    ****************************************************************************/
132    function parse()
133    {
134        if (!is_bool($this->input)) {
135            if (!xml_parse($this->parser, $this->input)) {
136                $this->setErrors($this->getXmlError());
137                return false;
138            }
139            //if (!$fp = fopen($this->input, 'r')) {
140            //    $this->setErrors('Could not open file: '.$this->input);
141            //    return false;
142            //}
143        } else {
144            while ($data = fread($this->input, 4096)) {
145                if (!xml_parse($this->parser, str_replace("'", "&apos;", $data), feof($this->input))) {
146                    $this->setErrors($this->getXmlError());
147                    fclose($this->input);
148                    return false;
149                }
150            }
151            fclose($this->input);
152        }
153        return true;
154    }
155
156    /****************************************************************************
157        * @returns void
158    ****************************************************************************/
159    function free()
160    {
161        xml_parser_free($this->parser);
162
163        if (!method_exists($this, '__destruct')) {
164            unset($this->parser);
165        }
166        else {
167            $this->__destruct();
168        }
169    }
170
171    /****************************************************************************
172        * @private
173        * @returns string
174    ****************************************************************************/
175    function getXmlError()
176    {
177        return sprintf("XmlParse error: %s at line %d", xml_error_string(xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser));
178    }
179
180    /*---------------------------------------------------------------------------
181        Custom Handler Methods
182    ---------------------------------------------------------------------------*/
183
184    /****************************************************************************
185        Adds a callback function to be called when a tag is encountered.<br>
186        Functions that are added must be of the form:<br>
187        <b>functionName( $attributes )</b>
188        * @param $tagName string.  The name of the tag currently being parsed.
189        * @param $functionName string.  The name of the function in XmlDocument's
190        subclass.
191        * @returns void
192    ****************************************************************************/
193    function addTagHandler($tagHandler)
194    {
195        $name = $tagHandler->getName();
196        if (is_array($name)) {
197            foreach ($name as $n) {
198                $this->tagHandlers[$n] = $tagHandler;
199            }
200        } else {
201            $this->tagHandlers[$name] = $tagHandler;
202        }
203    }
204
205
206    /*---------------------------------------------------------------------------
207        Private Handler Methods
208    ---------------------------------------------------------------------------*/
209
210    /****************************************************************************
211        Callback function that executes whenever a the start of a tag
212        occurs when being parsed.
213        * @param $parser int.  The handle to the parser.
214        * @param $tagName string.  The name of the tag currently being parsed.
215        * @param $attributesArray attay.  The list of attributes associated with
216        the tag.
217        * @private
218        * @returns void
219    ****************************************************************************/
220    function handleBeginElement($parser, $tagName, $attributesArray)
221    {
222        array_push($this->tags, $tagName);
223        $this->level++;
224        if (isset($this->tagHandlers[$tagName]) && is_subclass_of($this->tagHandlers[$tagName], 'xmltaghandler')) {
225            $this->tagHandlers[$tagName]->handleBeginElement($this, $attributesArray);
226        } else {
227			$this->handleBeginElementDefault($parser, $tagName, $attributesArray);
228		}
229    }
230
231    /****************************************************************************
232        Callback function that executes whenever the end of a tag
233        occurs when being parsed.
234        * @param $parser int.  The handle to the parser.
235        * @param $tagName string.  The name of the tag currently being parsed.
236        * @private
237        * @returns void
238    ****************************************************************************/
239    function handleEndElement($parser, $tagName)
240    {
241        array_pop($this->tags);
242        if (isset($this->tagHandlers[$tagName]) && is_subclass_of($this->tagHandlers[$tagName], 'xmltaghandler')) {
243            $this->tagHandlers[$tagName]->handleEndElement($this);
244        } else {
245			$this->handleEndElementDefault($parser, $tagName);
246		}
247        $this->level--;
248    }
249
250    /****************************************************************************
251        Callback function that executes whenever character data is encountered
252        while being parsed.
253        * @param $parser int.  The handle to the parser.
254        * @param $data string.  Character data inside the tag
255        * @returns void
256    ****************************************************************************/
257    function handleCharacterData($parser, $data)
258    {
259        $tagHandler = $this->tagHandlers[$this->getCurrentTag()];
260        if (isset($tagHandler) && is_subclass_of($tagHandler, 'xmltaghandler')) {
261            $tagHandler->handleCharacterData($this, $data);
262        } else {
263			$this->handleCharacterDataDefault($parser, $data);
264		}
265    }
266
267    /****************************************************************************
268        * @param $parser int.  The handle to the parser.
269        * @returns void
270    ****************************************************************************/
271    function handleProcessingInstruction($parser, $target, $data)
272    {
273//        if($target == 'php') {
274//            eval($data);
275//        }
276    }
277
278    /****************************************************************************
279        * @param $parser int.  The handle to the parser.
280        * @returns void
281    ****************************************************************************/
282    function handleDefault($parser, $data)
283    {
284
285    }
286
287    /****************************************************************************
288        * @param $parser int.  The handle to the parser.
289        * @returns void
290    ****************************************************************************/
291    function handleUnparsedEntityDecl($parser, $entityName, $base, $systemId, $publicId, $notationName)
292    {
293
294    }
295
296    /****************************************************************************
297        * @param $parser int.  The handle to the parser.
298        * @returns void
299    ****************************************************************************/
300    function handleNotationDecl($parser, $notationName, $base, $systemId, $publicId)
301    {
302
303    }
304
305    /****************************************************************************
306        * @param $parser int.  The handle to the parser.
307        * @returns void
308    ****************************************************************************/
309    function handleExternalEntityRef($parser, $openEntityNames, $base, $systemId, $publicId)
310    {
311
312    }
313
314	/**
315	 * The default tag handler method for a tag with no handler
316	 *
317	 * @abstract
318	 */
319	function handleBeginElementDefault($parser, $tagName, $attributesArray)
320	{
321	}
322
323	/**
324	 * The default tag handler method for a tag with no handler
325	 *
326	 * @abstract
327	 */
328	function handleEndElementDefault($parser, $tagName)
329	{
330	}
331
332	/**
333	 * The default tag handler method for a tag with no handler
334	 *
335	 * @abstract
336	 */
337	function handleCharacterDataDefault($parser, $data)
338	{
339	}
340
341	/**
342	 * Sets error messages
343	 *
344	 * @param	$error	string	an error message
345	 */
346    function setErrors($error)
347    {
348        $this->errors[] = trim($error);
349    }
350
351	/**
352	 * Gets all the error messages
353	 *
354	 * @param	$ashtml	bool	return as html?
355	 * @return	mixed
356	 */
357    function &getErrors($ashtml = true)
358    {
359        if (!$ashtml) {
360            return $this->errors;
361        } else {
362        	$ret = '';
363        	if (count($this->errors) > 0) {
364            	foreach ($this->errors as $error) {
365            	    $ret .= $error.'<br />';
366            	}
367        	}
368        	return $ret;
369        }
370    }
371}
372
373?>