home *** CD-ROM | disk | FTP | other *** search
- <?php
- // $Id: saxparser.php 2 2005-11-02 18:23:29Z skalpa $
- /*******************************************************************************
- Location: <b>xml/SaxParser.class</b><br>
- <br>
- Provides basic functionality to read and parse XML documents. Subclasses
- must implement all the their custom handlers by using add* function methods.
- They may also use the handle*() methods to parse a specific XML begin and end
- tags, but this is not recommended as it is more difficult.<br>
- <br>
- Copyright © 2001 eXtremePHP. All rights reserved.<br>
- <br>
- @author Ken Egervari<br>
- *******************************************************************************/
-
- class SaxParser
- {
- var $level;
- var $parser;
-
- var $isCaseFolding;
- var $targetEncoding;
-
- /* Custom Handler Variables */
- var $tagHandlers = array();
-
- /* Tag stack */
- var $tags = array();
-
- /* Xml Source Input */
- var $xmlInput;
-
- var $errors = array();
-
- /****************************************************************************
- Creates a SaxParser object using a FileInput to represent the stream
- of XML data to parse. Use the static methods createFileInput or
- createStringInput to construct xml input source objects to supply
- to the constructor, or the implementor can construct them individually.
- ****************************************************************************/
- function SaxParser(&$input)
- {
- $this->level = 0;
- $this->parser = xml_parser_create('UTF-8');
- xml_set_object($this->parser, $this);
- $this->input =& $input;
- $this->setCaseFolding(false);
- $this->useUtfEncoding();
- xml_set_element_handler($this->parser, 'handleBeginElement','handleEndElement');
- xml_set_character_data_handler($this->parser, 'handleCharacterData');
- xml_set_processing_instruction_handler($this->parser, 'handleProcessingInstruction');
- xml_set_default_handler($this->parser, 'handleDefault');
- xml_set_unparsed_entity_decl_handler($this->parser, 'handleUnparsedEntityDecl');
- xml_set_notation_decl_handler($this->parser, 'handleNotationDecl');
- xml_set_external_entity_ref_handler($this->parser, 'handleExternalEntityRef');
- }
-
- /*---------------------------------------------------------------------------
- Property Methods
- ---------------------------------------------------------------------------*/
-
- function getCurrentLevel()
- {
- return $this->level;
- }
-
- /****************************************************************************
- * @param $isCaseFolding
- * @returns void
- ****************************************************************************/
- function setCaseFolding($isCaseFolding)
- {
- assert(is_bool($isCaseFolding));
-
- $this->isCaseFolding = $isCaseFolding;
- xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, $this->isCaseFolding);
- }
-
- /****************************************************************************
- * @returns void
- ****************************************************************************/
- function useIsoEncoding()
- {
- $this->targetEncoding = 'ISO-8859-1';
- xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->targetEncoding);
- }
-
- /****************************************************************************
- * @returns void
- ****************************************************************************/
- function useAsciiEncoding()
- {
- $this->targetEncoding = 'US-ASCII';
- xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->targetEncoding);
- }
-
- /****************************************************************************
- * @returns void
- ****************************************************************************/
- function useUtfEncoding()
- {
- $this->targetEncoding = 'UTF-8';
- xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->targetEncoding);
- }
-
- /****************************************************************************
- Returns the name of the xml tag being parsed
- * @returns string
- ****************************************************************************/
- function getCurrentTag()
- {
- return $this->tags[count($this->tags) - 1];
- }
-
- function getParentTag()
- {
- if (isset($this->tags[count($this->tags) - 2])) {
- return $this->tags[count($this->tags) - 2];
- }
- return false;
- }
-
-
-
- /*---------------------------------------------------------------------------
- Parser methods
- ---------------------------------------------------------------------------*/
-
- /****************************************************************************
- * @returns void
- ****************************************************************************/
- function parse()
- {
- if (!is_resource($this->input)) {
- if (!xml_parse($this->parser, $this->input)) {
- $this->setErrors($this->getXmlError());
- return false;
- }
- //if (!$fp = fopen($this->input, 'r')) {
- // $this->setErrors('Could not open file: '.$this->input);
- // return false;
- //}
- } else {
- while ($data = fread($this->input, 4096)) {
- if (!xml_parse($this->parser, str_replace("'", "'", $data), feof($this->input))) {
- $this->setErrors($this->getXmlError());
- fclose($this->input);
- return false;
- }
- }
- fclose($this->input);
- }
- return true;
- }
-
- /****************************************************************************
- * @returns void
- ****************************************************************************/
- function free()
- {
- xml_parser_free($this->parser);
-
- if (!method_exists($this, '__destruct')) {
- unset($this);
- }
- else {
- $this->__destruct();
- }
- }
-
- /****************************************************************************
- * @private
- * @returns string
- ****************************************************************************/
- function getXmlError()
- {
- return sprintf("XmlParse error: %s at line %d", xml_error_string(xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser));
- }
-
- /*---------------------------------------------------------------------------
- Custom Handler Methods
- ---------------------------------------------------------------------------*/
-
- /****************************************************************************
- Adds a callback function to be called when a tag is encountered.<br>
- Functions that are added must be of the form:<br>
- <b>functionName( $attributes )</b>
- * @param $tagName string. The name of the tag currently being parsed.
- * @param $functionName string. The name of the function in XmlDocument's
- subclass.
- * @returns void
- ****************************************************************************/
- function addTagHandler(&$tagHandler)
- {
- $name = $tagHandler->getName();
- if (is_array($name)) {
- foreach ($name as $n) {
- $this->tagHandlers[$n] =& $tagHandler;
- }
- } else {
- $this->tagHandlers[$name] =& $tagHandler;
- }
- }
-
-
- /*---------------------------------------------------------------------------
- Private Handler Methods
- ---------------------------------------------------------------------------*/
-
- /****************************************************************************
- Callback function that executes whenever a the start of a tag
- occurs when being parsed.
- * @param $parser int. The handle to the parser.
- * @param $tagName string. The name of the tag currently being parsed.
- * @param $attributesArray attay. The list of attributes associated with
- the tag.
- * @private
- * @returns void
- ****************************************************************************/
- function handleBeginElement($parser, $tagName, $attributesArray)
- {
- array_push($this->tags, $tagName);
- $this->level++;
- if (isset($this->tagHandlers[$tagName]) && is_subclass_of($this->tagHandlers[$tagName], 'xmltaghandler')) {
- $this->tagHandlers[$tagName]->handleBeginElement($this, $attributesArray);
- } else {
- $this->handleBeginElementDefault($parser, $tagName, $attributesArray);
- }
- }
-
- /****************************************************************************
- Callback function that executes whenever the end of a tag
- occurs when being parsed.
- * @param $parser int. The handle to the parser.
- * @param $tagName string. The name of the tag currently being parsed.
- * @private
- * @returns void
- ****************************************************************************/
- function handleEndElement($parser, $tagName)
- {
- array_pop($this->tags);
- if (isset($this->tagHandlers[$tagName]) && is_subclass_of($this->tagHandlers[$tagName], 'xmltaghandler')) {
- $this->tagHandlers[$tagName]->handleEndElement($this);
- } else {
- $this->handleEndElementDefault($parser, $tagName);
- }
- $this->level--;
- }
-
- /****************************************************************************
- Callback function that executes whenever character data is encountered
- while being parsed.
- * @param $parser int. The handle to the parser.
- * @param $data string. Character data inside the tag
- * @returns void
- ****************************************************************************/
- function handleCharacterData($parser, $data)
- {
- $tagHandler =& $this->tagHandlers[$this->getCurrentTag()];
- if (isset($tagHandler) && is_subclass_of($tagHandler, 'xmltaghandler')) {
- $tagHandler->handleCharacterData($this, $data);
- } else {
- $this->handleCharacterDataDefault($parser, $data);
- }
- }
-
- /****************************************************************************
- * @param $parser int. The handle to the parser.
- * @returns void
- ****************************************************************************/
- function handleProcessingInstruction($parser, &$target, &$data)
- {
- // if($target == 'php') {
- // eval($data);
- // }
- }
-
- /****************************************************************************
- * @param $parser int. The handle to the parser.
- * @returns void
- ****************************************************************************/
- function handleDefault($parser, $data)
- {
-
- }
-
- /****************************************************************************
- * @param $parser int. The handle to the parser.
- * @returns void
- ****************************************************************************/
- function handleUnparsedEntityDecl($parser, $entityName, $base, $systemId, $publicId, $notationName)
- {
-
- }
-
- /****************************************************************************
- * @param $parser int. The handle to the parser.
- * @returns void
- ****************************************************************************/
- function handleNotationDecl($parser, $notationName, $base, $systemId, $publicId)
- {
-
- }
-
- /****************************************************************************
- * @param $parser int. The handle to the parser.
- * @returns void
- ****************************************************************************/
- function handleExternalEntityRef($parser, $openEntityNames, $base, $systemId, $publicId)
- {
-
- }
-
- /**
- * The default tag handler method for a tag with no handler
- *
- * @abstract
- */
- function handleBeginElementDefault($parser, $tagName, $attributesArray)
- {
- }
-
- /**
- * The default tag handler method for a tag with no handler
- *
- * @abstract
- */
- function handleEndElementDefault($parser, $tagName)
- {
- }
-
- /**
- * The default tag handler method for a tag with no handler
- *
- * @abstract
- */
- function handleCharacterDataDefault($parser, $data)
- {
- }
-
- /**
- * Sets error messages
- *
- * @param $error string an error message
- */
- function setErrors($error)
- {
- $this->errors[] = trim($error);
- }
-
- /**
- * Gets all the error messages
- *
- * @param $ashtml bool return as html?
- * @return mixed
- */
- function &getErrors($ashtml = true)
- {
- if (!$ashtml) {
- return $this->errors;
- } else {
- $ret = '';
- if (count($this->errors) > 0) {
- foreach ($this->errors as $error) {
- $ret .= $error.'<br />';
- }
- }
- return $ret;
- }
- }
- }
-
- ?>