[ Index ] |
|
Code source de LifeType 1.2.4 |
1 <?php 2 // 3 // +----------------------------------------------------------------------+ 4 // | PHP Version 4 | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 1997-2004 The PHP Group | 7 // +----------------------------------------------------------------------+ 8 // | This source file is subject to version 3.0 of the PHP license, | 9 // | that is bundled with this package in the file LICENSE, and is | 10 // | available at through the world-wide-web at | 11 // | http://www.php.net/license/3_0.txt. | 12 // | If you did not receive a copy of the PHP license and are unable to | 13 // | obtain it through the world-wide-web, please send a note to | 14 // | license@php.net so we can mail you a copy immediately. | 15 // +----------------------------------------------------------------------+ 16 // | Author: Stig Bakken <ssb@fast.no> | 17 // | Tomas V.V.Cox <cox@idecnet.com> | 18 // | Stephan Schmidt <schst@php-tools.net> | 19 // +----------------------------------------------------------------------+ 20 // 21 // $Id: Parser.php,v 1.15 2004/10/04 16:56:49 schst Exp $ 22 23 /** 24 * XML Parser class. 25 * 26 * This is an XML parser based on PHP's "xml" extension, 27 * based on the bundled expat library. 28 * 29 * @category XML 30 * @package XML_Parser 31 * @author Stig Bakken <ssb@fast.no> 32 * @author Tomas V.V.Cox <cox@idecnet.com> 33 * @author Stephan Schmidt <schst@php-tools.net> 34 */ 35 36 /** 37 * uses PEAR's error handling 38 */ 39 //require_once 'PEAR.php'; 40 41 /** 42 * resource could not be created 43 */ 44 define('XML_PARSER_ERROR_NO_RESOURCE', 200); 45 46 /** 47 * unsupported mode 48 */ 49 define('XML_PARSER_ERROR_UNSUPPORTED_MODE', 201); 50 51 /** 52 * invalid encoding was given 53 */ 54 define('XML_PARSER_ERROR_INVALID_ENCODING', 202); 55 56 /** 57 * specified file could not be read 58 */ 59 define('XML_PARSER_ERROR_FILE_NOT_READABLE', 203); 60 61 /** 62 * invalid input 63 */ 64 define('XML_PARSER_ERROR_INVALID_INPUT', 204); 65 66 /** 67 * remote file cannot be retrieved in safe mode 68 */ 69 define('XML_PARSER_ERROR_REMOTE', 205); 70 71 /** 72 * \ingroup XML 73 * 74 * XML Parser class. 75 * 76 * This is an XML parser based on PHP's "xml" extension, 77 * based on the bundled expat library. 78 * 79 * Notes: 80 * - It requires PHP 4.0.4pl1 or greater 81 * - From revision 1.17, the function names used by the 'func' mode 82 * are in the format "xmltag_$elem", for example: use "xmltag_name" 83 * to handle the <name></name> tags of your xml file. 84 * 85 * @category XML 86 * @package XML_Parser 87 * @author Stig Bakken <ssb@fast.no> 88 * @author Tomas V.V.Cox <cox@idecnet.com> 89 * @author Stephan Schmidt <schst@php-tools.net> 90 * @todo create XML_Parser_Namespace to parse documents with namespaces 91 * @todo create XML_Parser_Pull 92 * @todo Tests that need to be made: 93 * - mixing character encodings 94 * - a test using all expat handlers 95 * - options (folding, output charset) 96 * - different parsing modes 97 */ 98 class XML_Parser 99 { 100 // {{{ properties 101 102 /** 103 * XML parser handle 104 * 105 * @var resource 106 * @see xml_parser_create() 107 */ 108 var $parser; 109 110 /** 111 * File handle if parsing from a file 112 * 113 * @var resource 114 */ 115 var $fp; 116 117 /** 118 * Whether to do case folding 119 * 120 * If set to true, all tag and attribute names will 121 * be converted to UPPER CASE. 122 * 123 * @var boolean 124 */ 125 var $folding = true; 126 127 /** 128 * Mode of operation, one of "event" or "func" 129 * 130 * @var string 131 */ 132 var $mode; 133 134 /** 135 * Mapping from expat handler function to class method. 136 * 137 * @var array 138 */ 139 var $handler = array( 140 'character_data_handler' => 'cdataHandler', 141 'default_handler' => 'defaultHandler', 142 'processing_instruction_handler' => 'piHandler', 143 'unparsed_entity_decl_handler' => 'unparsedHandler', 144 'notation_decl_handler' => 'notationHandler', 145 'external_entity_ref_handler' => 'entityrefHandler' 146 ); 147 148 /** 149 * source encoding 150 * 151 * @var string 152 */ 153 var $srcenc; 154 155 /** 156 * target encoding 157 * 158 * @var string 159 */ 160 var $tgtenc; 161 162 /** 163 * handler object 164 * 165 * @var object 166 */ 167 var $_handlerObj; 168 169 // }}} 170 // {{{ constructor 171 172 /** 173 * Creates an XML parser. 174 * 175 * This is needed for PHP4 compatibility, it will 176 * call the constructor, when a new instance is created. 177 * 178 * @param string $srcenc source charset encoding, use NULL (default) to use 179 * whatever the document specifies 180 * @param string $mode how this parser object should work, "event" for 181 * startelement/endelement-type events, "func" 182 * to have it call functions named after elements 183 * @param string $tgenc a valid target encoding 184 */ 185 function XML_Parser($srcenc = null, $mode = 'event', $tgtenc = null) 186 { 187 XML_Parser::__construct($srcenc, $mode, $tgtenc); 188 } 189 // }}} 190 191 /** 192 * PHP5 constructor 193 * 194 * @param string $srcenc source charset encoding, use NULL (default) to use 195 * whatever the document specifies 196 * @param string $mode how this parser object should work, "event" for 197 * startelement/endelement-type events, "func" 198 * to have it call functions named after elements 199 * @param string $tgenc a valid target encoding 200 */ 201 function __construct($srcenc = null, $mode = 'event', $tgtenc = null) 202 { 203 $this->mode = $mode; 204 $this->srcenc = $srcenc; 205 $this->tgtenc = $tgtenc; 206 } 207 // }}} 208 209 /** 210 * Sets the mode of the parser. 211 * 212 * Possible modes are: 213 * - func 214 * - event 215 * 216 * You can set the mode using the second parameter 217 * in the constructor. 218 * 219 * This method is only needed, when switching to a new 220 * mode at a later point. 221 * 222 * @access public 223 * @param string mode, either 'func' or 'event' 224 * @return boolean|object true on success, PEAR_Error otherwise 225 */ 226 function setMode($mode) 227 { 228 if ($mode != 'func' && $mode != 'event') { 229 $this->raiseError('Unsupported mode given', XML_PARSER_ERROR_UNSUPPORTED_MODE); 230 } 231 232 $this->mode = $mode; 233 return true; 234 } 235 236 /** 237 * Sets the object, that will handle the XML events 238 * 239 * This allows you to create a handler object independent of the 240 * parser object that you are using and easily switch the underlying 241 * parser. 242 * 243 * If no object will be set, XML_Parser assumes that you 244 * extend this class and handle the events in $this. 245 * 246 * @access public 247 * @param object object to handle the events 248 * @return boolean will always return true 249 * @since v1.2.0beta3 250 */ 251 function setHandlerObj(&$obj) 252 { 253 $this->_handlerObj = &$obj; 254 return true; 255 } 256 257 /** 258 * Init the element handlers 259 * 260 * @access private 261 */ 262 function _initHandlers() 263 { 264 if (!is_resource($this->parser)) { 265 return false; 266 } 267 268 if (!is_object($this->_handlerObj)) { 269 $this->_handlerObj = &$this; 270 } 271 switch ($this->mode) { 272 273 case 'func': 274 xml_set_object($this->parser, $this); 275 xml_set_element_handler($this->parser, 'funcStartHandler', 'funcEndHandler'); 276 break; 277 278 case 'event': 279 xml_set_object($this->parser, $this->_handlerObj); 280 xml_set_element_handler($this->parser, 'startHandler', 'endHandler'); 281 break; 282 default: 283 return $this->raiseError('Unsupported mode given', XML_PARSER_ERROR_UNSUPPORTED_MODE); 284 break; 285 } 286 287 288 /** 289 * set additional handlers for character data, entities, etc. 290 */ 291 foreach ($this->handler as $xml_func => $method) { 292 if (method_exists($this->_handlerObj, $method)) { 293 $xml_func = 'xml_set_' . $xml_func; 294 $xml_func($this->parser, $method); 295 } 296 } 297 } 298 299 // {{{ _create() 300 301 /** 302 * create the XML parser resource 303 * 304 * Has been moved from the constructor to avoid 305 * problems with object references. 306 * 307 * Furthermore it allows us returning an error 308 * if something fails. 309 * 310 * @access private 311 * @return boolean|object true on success, PEAR_Error otherwise 312 * 313 * @see xml_parser_create 314 */ 315 function _create() 316 { 317 if ($this->srcenc === null) { 318 $xp = @xml_parser_create(); 319 } else { 320 $xp = @xml_parser_create($this->srcenc); 321 } 322 if (is_resource($xp)) { 323 if ($this->tgtenc !== null) { 324 if (!@xml_parser_set_option($xp, XML_OPTION_TARGET_ENCODING, 325 $this->tgtenc)) { 326 return $this->raiseError('invalid target encoding', XML_PARSER_ERROR_INVALID_ENCODING); 327 } 328 } 329 $this->parser = $xp; 330 $result = $this->_initHandlers($this->mode); 331 if ($this->isError($result)) { 332 return $result; 333 } 334 xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, $this->folding); 335 336 return true; 337 } 338 return $this->raiseError('Unable to create XML parser resource.', XML_PARSER_ERROR_NO_RESOURCE); 339 } 340 341 // }}} 342 // {{{ reset() 343 344 /** 345 * Reset the parser. 346 * 347 * This allows you to use one parser instance 348 * to parse multiple XML documents. 349 * 350 * @access public 351 * @return boolean|object true on success, PEAR_Error otherwise 352 */ 353 function reset() 354 { 355 $result = $this->_create(); 356 if ($this->isError( $result )) { 357 return $result; 358 } 359 } 360 361 // }}} 362 // {{{ setInputFile() 363 364 /** 365 * Sets the input xml file to be parsed 366 * 367 * @param string Filename (full path) 368 * @return resource fopen handle of the given file 369 * @throws XML_Parser_Error 370 * @see setInput(), setInputString(), parse() 371 * @access public 372 */ 373 function setInputFile($file) 374 { 375 /** 376 * check, if file is a remote file 377 */ 378 if (eregi('^(http|ftp)://', substr($file, 0, 10))) { 379 if (!ini_get('safe_mode')) { 380 ini_set('allow_url_fopen', 1); 381 } else { 382 return $this->raiseError('Remote files cannot be parsed, as safe mode is enabled.', XML_PARSER_ERROR_REMOTE); 383 } 384 } 385 386 $fp = @fopen($file, 'rb'); 387 if (is_resource($fp)) { 388 $this->fp = $fp; 389 return $fp; 390 } 391 return $this->raiseError('File could not be opened.', XML_PARSER_ERROR_FILE_NOT_READABLE); 392 } 393 394 // }}} 395 // {{{ setInputString() 396 397 /** 398 * XML_Parser::setInputString() 399 * 400 * Sets the xml input from a string 401 * 402 * @param string $data a string containing the XML document 403 * @return null 404 **/ 405 function setInputString($data) 406 { 407 $this->fp = $data; 408 return null; 409 } 410 411 // }}} 412 // {{{ setInput() 413 414 /** 415 * Sets the file handle to use with parse(). 416 * 417 * You should use setInputFile() or setInputString() if you 418 * pass a string 419 * 420 * @param mixed $fp Can be either a resource returned from fopen(), 421 * a URL, a local filename or a string. 422 * @access public 423 * @see parse() 424 * @uses setInputString(), setInputFile() 425 */ 426 function setInput($fp) 427 { 428 if (is_resource($fp)) { 429 $this->fp = $fp; 430 return true; 431 } 432 // see if it's an absolute URL (has a scheme at the beginning) 433 elseif (eregi('^[a-z]+://', substr($fp, 0, 10))) { 434 return $this->setInputFile($fp); 435 } 436 // see if it's a local file 437 elseif (file_exists($fp)) { 438 return $this->setInputFile($fp); 439 } 440 // it must be a string 441 else { 442 $this->fp = $fp; 443 return true; 444 } 445 446 return $this->raiseError('Illegal input format', XML_PARSER_ERROR_INVALID_INPUT); 447 } 448 449 // }}} 450 // {{{ parse() 451 452 /** 453 * Central parsing function. 454 * 455 * @return true|object PEAR error returns true on success, or a PEAR_Error otherwise 456 * @access public 457 */ 458 function parse() 459 { 460 /** 461 * reset the parser 462 */ 463 $result = $this->reset(); 464 if ($this->isError($result)) { 465 return $result; 466 } 467 // if $this->fp was fopened previously 468 if (is_resource($this->fp)) { 469 470 while ($data = fread($this->fp, 4096)) { 471 if (!$this->_parseString($data, feof($this->fp))) { 472 return $this->raiseError(); 473 } 474 } 475 // otherwise, $this->fp must be a string 476 } else { 477 if (!$this->_parseString($this->fp, true)) { 478 return $this->raiseError(); 479 } 480 } 481 $this->free(); 482 483 return true; 484 } 485 486 /** 487 * XML_Parser::_parseString() 488 * 489 * @param string $data 490 * @param boolean $eof 491 * @return bool 492 * @access private 493 * @see parseString() 494 **/ 495 function _parseString($data, $eof = false) 496 { 497 return xml_parse($this->parser, $data, $eof); 498 } 499 500 // }}} 501 // {{{ parseString() 502 503 /** 504 * XML_Parser::parseString() 505 * 506 * Parses a string. 507 * 508 * @param string $data XML data 509 * @param boolean $eof If set and TRUE, data is the last piece of data sent in this parser 510 * @throws XML_Parser_Error 511 * @return Pear Error|true true on success or a PEAR Error 512 * @see _parseString() 513 */ 514 function parseString($data, $eof = false) 515 { 516 if (!isset($this->parser) || !is_resource($this->parser)) { 517 $this->reset(); 518 } 519 520 if (!$this->_parseString($data, $eof)) { 521 return $this->raiseError(); 522 } 523 524 if ($eof === true) { 525 $this->free(); 526 } 527 return true; 528 } 529 530 /** 531 * XML_Parser::free() 532 * 533 * Free the internal resources associated with the parser 534 * 535 * @return null 536 **/ 537 function free() 538 { 539 if (is_resource($this->parser)) { 540 xml_parser_free($this->parser); 541 unset( $this->parser ); 542 } 543 if (isset($this->fp) && is_resource($this->fp)) { 544 fclose($this->fp); 545 } 546 unset($this->fp); 547 return null; 548 } 549 550 /** 551 * XML_Parser::raiseError() 552 * 553 * Trows a XML_Parser_Error and free's the internal resources 554 * 555 * @param string $msg the error message 556 * @param integer $ecode the error message code 557 * @return XML_Parser_Error 558 **/ 559 function raiseError($msg = null, $ecode = 0) 560 { 561 $msg = !is_null($msg) ? $msg : $this->parser; 562 $err = &new XML_Parser_Error($msg, $ecode); 563 $this->free(); 564 565 return $err; 566 } 567 568 // }}} 569 // {{{ funcStartHandler() 570 571 function funcStartHandler($xp, $elem, $attribs) 572 { 573 $func = 'xmltag_' . $elem; 574 if (method_exists($this->_handlerObj, $func)) { 575 call_user_func(array(&$this->_handlerObj, $func), $xp, $elem, $attribs); 576 } 577 } 578 579 // }}} 580 // {{{ funcEndHandler() 581 582 function funcEndHandler($xp, $elem) 583 { 584 $func = 'xmltag_' . $elem . '_'; 585 if (method_exists($this->_handlerObj, $func)) { 586 call_user_func(array(&$this->_handlerObj, $func), $xp, $elem); 587 } 588 } 589 590 // }}} 591 // {{{ startHandler() 592 593 /** 594 * 595 * @abstract 596 */ 597 function startHandler($xp, $elem, &$attribs) 598 { 599 return NULL; 600 } 601 602 // }}} 603 // {{{ endHandler() 604 605 /** 606 * 607 * @abstract 608 */ 609 function endHandler($xp, $elem) 610 { 611 return NULL; 612 } 613 614 function isError( $obj ) 615 { 616 return( is_a( $obj, "XML_Parser_Error" )); 617 } 618 619 // }}}me 620 } 621 622 /** 623 * error class, replaces PEAR_Error 624 * 625 * An instance of this class will be returned 626 * if an error occurs inside XML_Parser. 627 * 628 * There are three advantages over using the standard PEAR_Error: 629 * - All messages will be prefixed 630 * - check for XML_Parser error, using is_a( $error, 'XML_Parser_Error' ) 631 * - messages can be generated from the xml_parser resource 632 * 633 * @package XML_Parser 634 * @access public 635 * @see PEAR_Error 636 */ 637 class XML_Parser_Error 638 { 639 // {{{ properties 640 641 /** 642 * prefix for all messages 643 * 644 * @var string 645 */ 646 var $error_message_prefix = 'XML_Parser: '; 647 648 // }}} 649 // {{{ constructor() 650 /** 651 * construct a new error instance 652 * 653 * You may either pass a message or an xml_parser resource as first 654 * parameter. If a resource has been passed, the last error that 655 * happened will be retrieved and returned. 656 * 657 * @access public 658 * @param string|resource message or parser resource 659 * @param integer error code 660 * @param integer error handling 661 * @param integer error level 662 */ 663 function XML_Parser_Error($msgorparser = 'unknown error', $code = 0, $mode = PEAR_ERROR_RETURN, $level = E_USER_NOTICE) 664 { 665 if (is_resource($msgorparser)) { 666 $code = xml_get_error_code($msgorparser); 667 $msgorparser = sprintf('%s at XML input line %d', 668 xml_error_string($code), 669 xml_get_current_line_number($msgorparser)); 670 } 671 $this->msgorparser = $msgorparser; 672 $this->code = $code; 673 $this->mode = $mode; 674 $this->level = $level; 675 } 676 677 // }}} 678 } 679 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Mon Nov 26 21:04:15 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |