home *** CD-ROM | disk | FTP | other *** search
- <?php
- //
- // +----------------------------------------------------------------------+
- // | PHP version 4.0 |
- // +----------------------------------------------------------------------+
- // | Copyright (c) 1997-2001 The PHP Group |
- // +----------------------------------------------------------------------+
- // | This source file is subject to version 2.02 of the PHP license, |
- // | that is bundled with this package in the file LICENSE, and is |
- // | available at through the world-wide-web at |
- // | http://www.php.net/license/2_02.txt. |
- // | If you did not receive a copy of the PHP license and are unable to |
- // | obtain it through the world-wide-web, please send a note to |
- // | license@php.net so we can mail you a copy immediately. |
- // +----------------------------------------------------------------------+
- // | Authors: Stig Bakken <ssb@fast.no> |
- // | |
- // +----------------------------------------------------------------------+
- //
- // $Id: Parser.php,v 1.16.2.3 2001/11/13 01:26:49 ssb Exp $
-
- require_once "PEAR.php";
-
- /**
- * XML Parser class. This is an XML parser based on PHP's "xml" extension,
- * based on the bundled expat library.
- *
- * @author Stig Bakken <ssb@fast.no>
- * @todo Tests that need to be made:
- * - error class
- * - mixing character encodings
- * - a test using all expat handlers
- * - options (folding, output charset)
- * - different parsing modes
- *
- * @notes - It requires PHP 4.0.4pl1 or greater
- * - From revision 1.17, the function names used by the 'func' mode
- * are in the format "xmltag_$elem", for example: use "xmltag_name"
- * to handle the <name></name> tags of your xml file.
- */
- class XML_Parser extends PEAR {
- // {{{ properties
-
- /**
- * @var resource XML parser handle
- */
- var $parser;
-
- /**
- * @var resource File handle if parsing from a file
- */
- var $fp;
-
- /**
- * @var boolean Whether to do case folding
- */
- var $folding = true;
-
- /**
- * @var string Mode of operation, one of "event" or "func"
- */
- var $mode;
-
- /**
- * Mapping from expat handler function to class method.
- *
- * @var array
- */
- var $handler = array(
- "character_data_handler" => "cdataHandler",
- "default_handler" => "defaultHandler",
- "processing_instruction_handler" => "piHandler",
- "unparsed_entitry_decl_handler" => "unparsedHandler",
- "notation_decl_handler" => "notationHandler",
- "external_entity_ref_handler" => "entityrefHandler"
- );
-
- /** @var string source encoding */
- var $srcenc;
-
- /** @var string target encoding */
- var $tgtenc;
-
- /*
- * Use call_user_func when php >= 4.0.7
- * @var boolean
- * @see setMode()
- */
- var $use_call_user_func = true;
- // }}}
- // {{{ constructor
-
- /**
- * Creates an XML parser.
- *
- * @param string source charset encoding, use NULL (default) to use
- * whatever the document specifies
- * @param string how this parser object should work, "event" for
- * startelement/endelement-type events, "func"
- * to have it call functions named after elements
- *
- * @see xml_parser_create
- */
- function XML_Parser($srcenc = null, $mode = "event", $tgtenc = null)
- {
- $this->PEAR('XML_Parser_Error');
-
- if ($srcenc === null) {
- $xp = @xml_parser_create();
- } else {
- $xp = @xml_parser_create($srcenc);
- }
- if (is_resource($xp)) {
- if ($tgtenc !== null) {
- if (!@xml_parser_set_option($xp, XML_OPTION_TARGET_ENCODING,
- $tgtenc)) {
- return $this->raiseError("invalid target encoding");
- }
- }
- $this->parser = $xp;
- $this->setMode($mode);
- xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, $this->folding);
- }
- $this->srcenc = $srcenc;
- $this->tgtenc = $tgtenc;
- }
- // }}}
-
- // {{{ setMode()
-
- /**
- * Sets the mode and all handler.
- *
- * @param string
- * @see $handler
- */
- function setMode($mode) {
-
- $this->mode = $mode;
-
- xml_set_object($this->parser, $this);
-
- switch ($mode) {
-
- case "func":
- // use call_user_func() when php >= 4.0.7
- // or call_user_method() if not
- if (version_compare(phpversion(), '4.0.7', 'lt')) {
- $this->use_call_user_func = false;
- } else {
- $this->use_call_user_func = true;
- }
-
- xml_set_element_handler($this->parser, "funcStartHandler", "funcEndHandler");
- break;
-
- case "event":
- xml_set_element_handler($this->parser, "startHandler", "endHandler");
- break;
- }
-
- foreach ($this->handler as $xml_func => $method)
- if (method_exists($this, $method)) {
- $xml_func = "xml_set_" . $xml_func;
- $xml_func($this->parser, $method);
- }
-
- }
-
- // }}}
- // {{{ setInputFile()
-
- /**
- * Defines
- *
- * @param string Filename (full path)
- * @return resource fopen handle of the given file
- * @throws XML_Parser_Error
- * @see setInput(), parse()
- * @access public
- */
- function setInputFile($file) {
-
- $fp = @fopen($file, "rb");
- if (is_resource($fp)) {
- $this->fp = $fp;
- return $fp;
- }
-
- return $this->raiseError($php_errormsg);
- }
-
- // }}}
- // {{{ setInput()
-
- /**
- * Sets the file handle to use with parse().
- *
- * @param resource fopen
- * @access public
- * @see parse(), setInputFile()
- */
- function setInput($fp) {
-
- if (is_resource($fp)) {
- $this->fp = $fp;
- return true;
- }
-
- return $this->raiseError("not a file resource");
- }
-
- // }}}
- // {{{ parse()
-
- /**
- * Central parsing function.
- *
- * @throws XML_Parser_Error
- * @return boolean true on success
- * @see parseString()
- * @access public
- */
- function parse() {
-
- if (!is_resource($this->fp)) {
- return $this->raiseError("no input");
- }
-
- while ($data = fread($this->fp, 2048)) {
-
- $err = $this->parseString($data, feof($this->fp));
- if (PEAR::isError($err)) {
- fclose($this->fp);
- return $err;
- }
-
- }
-
- fclose($this->fp);
-
- return true;
- }
-
- // }}}
- // {{{ parseString()
-
- /**
- * Parses a string.
- *
- * @param string XML data
- * @param boolean ???
- * @throws XML_Parser_Error
- * @return mixed true on success or a string with the xml parser error
- */
- function parseString($data, $eof = false) {
-
- if (!xml_parse($this->parser, $data, $eof)) {
- $err = $this->raiseError($this->parser);
- xml_parser_free($this->parser);
- return $err;
- }
-
- return true;
- }
-
- // }}}
- // {{{ funcStartHandler()
-
- function funcStartHandler($xp, $elem, $attribs)
- {
- $func = 'xmltag_' . $elem;
- if (method_exists($this, $func)) {
- if ($this->use_call_user_func) {
- call_user_func(array(&$this, $func), $xp, $elem, $attribs);
- } else {
- call_user_method($func, $this, $xp, $elem, $attribs);
- }
- }
-
- }
-
- // }}}
- // {{{ funcEndHandler()
-
- function funcEndHandler($xp, $elem)
- {
- $func = 'xmltag_' . $elem . '_';
- if (method_exists($this, $func)) {
- if ($this->use_call_user_func) {
- call_user_func(array(&$this, $func), $xp, $elem);
- } else {
- call_user_method($func, $this, $xp, $elem);
- }
- }
- }
-
- /**
- *
- * @abstract
- */
- function StartHandler($xp, $elem, &$attribs)
- {
- return NULL;
- }
-
-
- /**
- *
- * @abstract
- */
- function EndHandler($xp, $elem)
- {
- return NULL;
- }
-
-
- // }}}
- }
-
- class XML_Parser_Error extends PEAR_Error {
- // {{{ properties
-
- var $error_message_prefix = 'XML_Parser: ';
-
- // }}}
- // {{{ constructor()
-
- function XML_Parser_Error($msgorparser = 'unknown error', $code = 0, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE) {
-
- if (is_resource($msgorparser)) {
- $code = xml_get_error_code($msgorparser);
- $msgorparser = sprintf("%s at XML input line %d",
- xml_error_string($code),
- xml_get_current_line_number($msgorparser));
- }
- $this->PEAR_Error($msgorparser, $code, $mode, $level);
-
- }
-
- // }}}
- }
- ?>
-