[ Index ]
 

Code source de Joomla 1.0.13

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/includes/domit/ -> xml_saxy_parser.php (source)

   1  <?php
   2  /**
   3  * SAXY is a non-validating, but lightweight and fast SAX parser for PHP, modelled on the Expat parser
   4  * @package saxy-xmlparser
   5  * @subpackage saxy-xmlparser-main
   6  * @version 1.0
   7  * @copyright (C) 2004 John Heinstein. All rights reserved
   8  * @license http://www.gnu.org/copyleft/lesser.html LGPL License
   9  * @author John Heinstein <johnkarl@nbnet.nb.ca>
  10  * @link http://www.engageinteractive.com/saxy/ SAXY Home Page
  11  * SAXY is Free Software
  12  **/
  13  
  14  if (!defined('SAXY_INCLUDE_PATH')) {
  15      define('SAXY_INCLUDE_PATH', (dirname(__FILE__) . "/"));
  16  }
  17  
  18  /** current version of SAXY */
  19  define ('SAXY_VERSION', '1.0');
  20  
  21  /** default XML namespace */
  22  define ('SAXY_XML_NAMESPACE', 'http://www.w3.org/xml/1998/namespace');
  23  
  24  /** saxy parse state, before prolog is encountered */
  25  define('SAXY_STATE_PROLOG_NONE', 0);
  26  /** saxy parse state, in processing instruction */
  27  define('SAXY_STATE_PROLOG_PROCESSINGINSTRUCTION', 1);
  28  /** saxy parse state, an exclamation mark has been encountered */
  29  define('SAXY_STATE_PROLOG_EXCLAMATION', 2);
  30  /** saxy parse state, in DTD */
  31  define('SAXY_STATE_PROLOG_DTD', 3);
  32  /** saxy parse state, an inline DTD */
  33  define('SAXY_STATE_PROLOG_INLINEDTD', 4);
  34  /** saxy parse state, a comment */
  35  define('SAXY_STATE_PROLOG_COMMENT', 5);
  36  /** saxy parse state, processing main document */
  37  define('SAXY_STATE_PARSING', 6);
  38  /** saxy parse state, processing comment in main document */
  39  define('SAXY_STATE_PARSING_COMMENT', 7);
  40  
  41  //SAXY error codes; same as EXPAT error codes
  42  /** no error */
  43  define('SAXY_XML_ERROR_NONE', 0);
  44  /** out of memory error */
  45  define('SAXY_XML_ERROR_NO_MEMORY', 1);
  46  /** syntax error */
  47  define('SAXY_XML_ERROR_SYNTAX', 2);
  48  /** no elements in document */
  49  define('SAXY_XML_ERROR_NO_ELEMENTS', 3);
  50  /** invalid token encountered error */
  51  define('SAXY_XML_ERROR_INVALID_TOKEN', 4);
  52  /** unclosed token error */
  53  define('SAXY_XML_ERROR_UNCLOSED_TOKEN', 5);
  54  /** partial character error */
  55  define('SAXY_XML_ERROR_PARTIAL_CHAR', 6);
  56  /** mismatched tag error */
  57  define('SAXY_XML_ERROR_TAG_MISMATCH', 7);
  58  /** duplicate attribute error */
  59  define('SAXY_XML_ERROR_DUPLICATE_ATTRIBUTE', 8);
  60  /** junk after document element error */
  61  define('SAXY_XML_ERROR_JUNK_AFTER_DOC_ELEMENT', 9);
  62  /** parameter enitity reference error */
  63  define('SAXY_XML_ERROR_PARAM_ENTITY_REF', 10);
  64  /** undefined entity error */
  65  define('SAXY_XML_ERROR_UNDEFINED_ENTITY', 11);
  66  /** recursive entity error */
  67  define('SAXY_XML_ERROR_RECURSIVE_ENTITY_REF', 12);
  68  /** asynchronous entity error */
  69  define('SAXY_XML_ERROR_ASYNC_ENTITY', 13);
  70  /** bad character reference error */
  71  define('SAXY_XML_ERROR_BAD_CHAR_REF', 14);
  72  /** binary entity reference error */
  73  define('SAXY_XML_ERROR_BINARY_ENTITY_REF', 15);
  74  /** attribute external entity error */
  75  define('SAXY_XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF', 16);
  76  /** misplaced processing instruction error */
  77  define('SAXY_XML_ERROR_MISPLACED_XML_PI', 17);
  78  /** unknown encoding error */
  79  define('SAXY_XML_ERROR_UNKNOWN_ENCODING', 18);
  80  /** incorrect encoding error */
  81  define('SAXY_XML_ERROR_INCORRECT_ENCODING', 19);
  82  /** unclosed CDATA Section error */
  83  define('SAXY_XML_ERROR_UNCLOSED_CDATA_SECTION', 20);
  84  /** external entity handling error */
  85  define('SAXY_XML_ERROR_EXTERNAL_ENTITY_HANDLING', 21);
  86  
  87  require_once (SAXY_INCLUDE_PATH . 'xml_saxy_shared.php');
  88  
  89  /**
  90  * The SAX Parser class
  91  *
  92  * @package saxy-xmlparser
  93  * @subpackage saxy-xmlparser-main
  94  * @author John Heinstein <johnkarl@nbnet.nb.ca>
  95  */
  96  class SAXY_Parser extends SAXY_Parser_Base {
  97      /** @var int The current error number */
  98      var $errorCode = SAXY_XML_ERROR_NONE;
  99      /** @var Object A reference to the DocType event handler */
 100      var $DTDHandler = null;
 101      /** @var Object A reference to the Comment event handler */
 102      var $commentHandler = null;
 103      /** @var Object A reference to the Processing Instruction event handler */
 104      var $processingInstructionHandler = null;
 105      /** @var Object A reference to the Start Namespace Declaration event handler */
 106      var $startNamespaceDeclarationHandler = null;
 107      /** @var Object A reference to the End Namespace Declaration event handler */
 108      var $endNamespaceDeclarationHandler = null;
 109      /** @var boolean True if SAXY takes namespaces into consideration when parsing element tags */
 110      var $isNamespaceAware = false;
 111      /** @var array An indexed array containing associative arrays of namespace prefixes mapped to their namespace URIs */
 112      var $namespaceMap = array();
 113      /** @var array A stack used to determine when an end namespace event should be fired */
 114      var $namespaceStack = array();
 115      /** @var array A track used to track the uri of the current default namespace */
 116      var $defaultNamespaceStack = array();
 117      /** @var array A stack containing tag names of unclosed elements */
 118      var $elementNameStack = array();
 119  
 120      /**
 121      * Constructor for SAX parser
 122      */
 123  	function SAXY_Parser() {
 124          $this->SAXY_Parser_Base();
 125          $this->state = SAXY_STATE_PROLOG_NONE;
 126      } //SAXY_Parser
 127  
 128      /**
 129      * Sets a reference to the handler for the DocType event
 130      * @param mixed A reference to the DocType handler
 131      */
 132  	function xml_set_doctype_handler($handler) {
 133          $this->DTDHandler =& $handler;
 134      } //xml_set_doctype_handler
 135  
 136      /**
 137      * Sets a reference to the handler for the Comment event
 138      * @param mixed A reference to the Comment handler
 139      */
 140  	function xml_set_comment_handler($handler) {
 141          $this->commentHandler =& $handler;
 142      } //xml_set_comment_handler
 143  
 144      /**
 145      * Sets a reference to the handler for the Processing Instruction event
 146      * @param mixed A reference to the Processing Instruction handler
 147      */
 148  	function xml_set_processing_instruction_handler($handler) {
 149          $this->processingInstructionHandler =& $handler;
 150      } //xml_set_processing_instruction_handler
 151  
 152      /**
 153      * Sets a reference to the handler for the Start Namespace Declaration event
 154      * @param mixed A reference to the Start Namespace Declaration handler
 155      */
 156  	function xml_set_start_namespace_decl_handler($handler) {
 157          $this->startNamespaceDeclarationHandler =& $handler;
 158      } //xml_set_start_namespace_decl_handler
 159  
 160      /**
 161      * Sets a reference to the handler for the End Namespace Declaration event
 162      * @param mixed A reference to the Start Namespace Declaration handler
 163      */
 164  	function xml_set_end_namespace_decl_handler($handler) {
 165          $this->endNamespaceDeclarationHandler =& $handler;
 166      } //xml_set_end_namespace_decl_handler
 167  
 168      /**
 169      * Specifies whether SAXY is namespace sensitive
 170      * @param boolean True if SAXY is namespace aware
 171      */
 172  	function setNamespaceAwareness($isNamespaceAware) {
 173          $this->isNamespaceAware =& $isNamespaceAware;
 174      } //setNamespaceAwareness
 175  
 176      /**
 177      * Returns the current version of SAXY
 178      * @return Object The current version of SAXY
 179      */
 180  	function getVersion() {
 181          return SAXY_VERSION;
 182      } //getVersion
 183  
 184      /**
 185      * Processes the xml prolog, doctype, and any other nodes that exist outside of the main xml document
 186      * @param string The xml text to be processed
 187      * @return string The preprocessed xml text
 188      */
 189  	function preprocessXML($xmlText) {
 190          //strip prolog
 191          $xmlText = trim($xmlText);
 192          $startChar = -1;
 193          $total = strlen($xmlText);
 194  
 195          for ($i = 0; $i < $total; $i++) {
 196              $currentChar = $xmlText{$i};
 197  
 198              switch ($this->state) {
 199                  case SAXY_STATE_PROLOG_NONE:
 200                      if ($currentChar == '<') {
 201                          $nextChar = $xmlText{($i + 1)};
 202  
 203                          if ($nextChar == '?')  {
 204                              $this->state = SAXY_STATE_PROLOG_PROCESSINGINSTRUCTION;
 205                              $this->charContainer = '';
 206                          }
 207                          else if ($nextChar == '!') {
 208                              $this->state = SAXY_STATE_PROLOG_EXCLAMATION;
 209                              $this->charContainer .= $currentChar;
 210                              break;
 211                          }
 212                          else {
 213                              $this->charContainer = '';
 214                              $startChar  = $i;
 215                              $this->state = SAXY_STATE_PARSING;
 216                              return (substr($xmlText, $startChar));
 217                          }
 218                      }
 219  
 220                      break;
 221  
 222                  case SAXY_STATE_PROLOG_EXCLAMATION:
 223                      if ($currentChar == 'D') {
 224                          $this->state = SAXY_STATE_PROLOG_DTD;
 225                          $this->charContainer .= $currentChar;
 226                      }
 227                      else if ($currentChar == '-') {
 228                          $this->state = SAXY_STATE_PROLOG_COMMENT;
 229                          $this->charContainer = '';
 230                      }
 231                      else {
 232                          //will trap ! and add it
 233                          $this->charContainer .= $currentChar;
 234                      }
 235  
 236                      break;
 237  
 238                  case SAXY_STATE_PROLOG_PROCESSINGINSTRUCTION:
 239                      if ($currentChar == '>') {
 240                          $this->state = SAXY_STATE_PROLOG_NONE;
 241                          $this->parseProcessingInstruction($this->charContainer);
 242                          $this->charContainer = '';
 243                      }
 244                      else {
 245                          $this->charContainer .= $currentChar;
 246                      }
 247  
 248                      break;
 249  
 250                  case SAXY_STATE_PROLOG_COMMENT:
 251                      if ($currentChar == '>') {
 252                          $this->state = SAXY_STATE_PROLOG_NONE;
 253                          $this->parseComment($this->charContainer);
 254                          $this->charContainer = '';
 255                      }
 256                      else if ($currentChar == '-') {
 257                          if ((($xmlText{($i + 1)} == '-')  && ($xmlText{($i + 2)} == '>')) ||
 258                              ($xmlText{($i + 1)} == '>') ||
 259                              (($xmlText{($i - 1)} == '-')  && ($xmlText{($i - 2)}== '!')) ){
 260                              //do nothing
 261                          }
 262                          else {
 263                              $this->charContainer .= $currentChar;
 264                          }
 265                      }
 266                      else {
 267                          $this->charContainer .= $currentChar;
 268                      }
 269  
 270                      break;
 271  
 272                  case SAXY_STATE_PROLOG_DTD:
 273                      if ($currentChar == '[') {
 274                          $this->charContainer .= $currentChar;
 275                          $this->state = SAXY_STATE_PROLOG_INLINEDTD;
 276                      }
 277                      else if ($currentChar == '>') {
 278                          $this->state = SAXY_STATE_PROLOG_NONE;
 279  
 280                          if ($this->DTDHandler != null) {
 281                              $this->fireDTDEvent($this->charContainer . $currentChar);
 282                          }
 283  
 284                          $this->charContainer = '';
 285                      }
 286                      else {
 287                          $this->charContainer .= $currentChar;
 288                      }
 289  
 290                      break;
 291  
 292                  case SAXY_STATE_PROLOG_INLINEDTD:
 293                      $previousChar = $xmlText{($i - 1)};
 294  
 295                      if (($currentChar == '>') && ($previousChar == ']')){
 296                          $this->state = SAXY_STATE_PROLOG_NONE;
 297  
 298                          if ($this->DTDHandler != null) {
 299                              $this->fireDTDEvent($this->charContainer . $currentChar);
 300                          }
 301  
 302                          $this->charContainer = '';
 303                      }
 304                      else {
 305                          $this->charContainer .= $currentChar;
 306                      }
 307  
 308                      break;
 309  
 310              }
 311          }
 312      } //preprocessXML
 313  
 314      /**
 315      * The controlling method for the parsing process
 316      * @param string The xml text to be processed
 317      * @return boolean True if parsing is successful
 318      */
 319  	function parse ($xmlText) {
 320          $xmlText = $this->preprocessXML($xmlText);
 321          $total = strlen($xmlText);
 322  
 323          for ($i = 0; $i < $total; $i++) {
 324              $currentChar = $xmlText{$i};
 325  
 326              switch ($this->state) {
 327                  case SAXY_STATE_PARSING:
 328                      switch ($currentChar) {
 329                          case '<':
 330                              if (substr($this->charContainer, 0, SAXY_CDATA_LEN) == SAXY_SEARCH_CDATA) {
 331                                  $this->charContainer .= $currentChar;
 332                              }
 333                              else {
 334                                  $this->parseBetweenTags($this->charContainer);
 335                                  $this->charContainer = '';
 336                              }
 337                              break;
 338  
 339                          case '-':
 340                              if (($xmlText{($i - 1)} == '-') && ($xmlText{($i - 2)} == '!')
 341                                  && ($xmlText{($i - 3)} == '<')) {
 342                                  $this->state = SAXY_STATE_PARSING_COMMENT;
 343                                  $this->charContainer = '';
 344                              }
 345                              else {
 346                                  $this->charContainer .= $currentChar;
 347                              }
 348                              break;
 349  
 350                          case '>':
 351                              if ((substr($this->charContainer, 0, SAXY_CDATA_LEN) == SAXY_SEARCH_CDATA) &&
 352                                  !(($this->getCharFromEnd($this->charContainer, 0) == ']') &&
 353                                  ($this->getCharFromEnd($this->charContainer, 1) == ']'))) {
 354                                  $this->charContainer .= $currentChar;
 355                              }
 356                              else {
 357                                  $this->parseTag($this->charContainer);
 358                                  $this->charContainer = '';
 359                              }
 360                              break;
 361  
 362                          default:
 363                              $this->charContainer .= $currentChar;
 364                      }
 365  
 366                      break;
 367  
 368                  case SAXY_STATE_PARSING_COMMENT:
 369                      switch ($currentChar) {
 370                          case '>':
 371                              if (($xmlText{($i - 1)} == '-') && ($xmlText{($i - 2)} == '-')) {
 372                                  $this->fireCommentEvent(substr($this->charContainer, 0,
 373                                                      (strlen($this->charContainer) - 2)));
 374                                  $this->charContainer = '';
 375                                  $this->state = SAXY_STATE_PARSING;
 376                              }
 377                              else {
 378                                  $this->charContainer .= $currentChar;
 379                              }
 380                              break;
 381  
 382                          default:
 383                              $this->charContainer .= $currentChar;
 384                      }
 385  
 386                      break;
 387              }
 388          }
 389  
 390          return ($this->errorCode == 0);
 391      } //parse
 392  
 393      /**
 394      * Parses an element tag
 395      * @param string The interior text of the element tag
 396      */
 397  	function parseTag($tagText) {
 398          $tagText = trim($tagText);
 399          $firstChar = $tagText{0};
 400          $myAttributes = array();
 401  
 402          switch ($firstChar) {
 403              case '/':
 404                  $tagName = substr($tagText, 1);
 405                  $this->_fireEndElementEvent($tagName);
 406                  break;
 407  
 408              case '!':
 409                  $upperCaseTagText = strtoupper($tagText);
 410  
 411                  if (strpos($upperCaseTagText, SAXY_SEARCH_CDATA) !== false) { //CDATA Section
 412                      $total = strlen($tagText);
 413                      $openBraceCount = 0;
 414                      $textNodeText = '';
 415  
 416                      for ($i = 0; $i < $total; $i++) {
 417                          $currentChar = $tagText{$i};
 418  
 419                          if (($currentChar == ']') && ($tagText{($i + 1)} == ']')) {
 420                              break;
 421                          }
 422                          else if ($openBraceCount > 1) {
 423                              $textNodeText .= $currentChar;
 424                          }
 425                          else if ($currentChar == '[') { //this won't be reached after the first open brace is found
 426                              $openBraceCount ++;
 427                          }
 428                      }
 429  
 430                      if ($this->cDataSectionHandler == null) {
 431                          $this->fireCharacterDataEvent($textNodeText);
 432                      }
 433                      else {
 434                          $this->fireCDataSectionEvent($textNodeText);
 435                      }
 436                  }
 437                  else if (strpos($upperCaseTagText, SAXY_SEARCH_NOTATION) !== false) { //NOTATION node, discard
 438                      return;
 439                  }
 440                  /*
 441                  else if (substr($tagText, 0, 2) == '!-') { //comment node
 442                      if ($this->commentHandler != null) {
 443                          $this->fireCommentEvent(substr($tagText, 3, (strlen($tagText) - 5)));
 444                      }
 445                  }
 446                  */
 447                  break;
 448  
 449              case '?':
 450                  //Processing Instruction node
 451                  $this->parseProcessingInstruction($tagText);
 452                  break;
 453  
 454              default:
 455                  if ((strpos($tagText, '"') !== false) || (strpos($tagText, "'") !== false)) {
 456                      $total = strlen($tagText);
 457                      $tagName = '';
 458  
 459                      for ($i = 0; $i < $total; $i++) {
 460                          $currentChar = $tagText{$i};
 461  
 462                          if (($currentChar == ' ') || ($currentChar == "\t") ||
 463                              ($currentChar == "\n") || ($currentChar == "\r") ||
 464                              ($currentChar == "\x0B")) {
 465                              $myAttributes = $this->parseAttributes(substr($tagText, $i));
 466                              break;
 467                          }
 468                          else {
 469                              $tagName .= $currentChar;
 470                          }
 471                      }
 472  
 473                      if (strrpos($tagText, '/') == (strlen($tagText) - 1)) { //check $tagText, but send $tagName
 474                          $this->_fireStartElementEvent($tagName, $myAttributes);
 475                          $this->_fireEndElementEvent($tagName);
 476                      }
 477                      else {
 478                          $this->_fireStartElementEvent($tagName, $myAttributes);
 479                      }
 480                  }
 481                  else {
 482                      if (strpos($tagText, '/') !== false) {
 483                          $tagText = trim(substr($tagText, 0, (strrchr($tagText, '/') - 1)));
 484                          $this->_fireStartElementEvent($tagText, $myAttributes);
 485                          $this->_fireEndElementEvent($tagText);
 486                      }
 487                      else {
 488                          $this->_fireStartElementEvent($tagText, $myAttributes);
 489                      }
 490                  }
 491          }
 492      } //parseTag
 493  
 494       /**
 495      * Fires a start element event and pushes the element name onto the elementName stack
 496      * @param string The start element tag name
 497      * @param Array The start element attributes
 498      */
 499  	function _fireStartElementEvent($tagName, &$myAttributes) {
 500          $this->elementNameStack[] = $tagName;
 501  
 502          if ($this->isNamespaceAware) {
 503              $this->detectStartNamespaceDeclaration($myAttributes);
 504              $tagName = $this->expandNamespacePrefix($tagName);
 505  
 506              $this->expandAttributePrefixes($myAttributes);
 507          }
 508  
 509          $this->fireStartElementEvent($tagName, $myAttributes);
 510      } //_fireStartElementEvent
 511  
 512      /**
 513      * Expands attribute prefixes to full namespace uri
 514      * @param Array The start element attributes
 515      */
 516  	function expandAttributePrefixes(&$myAttributes) {
 517          $arTransform = array();
 518  
 519          foreach ($myAttributes as $key => $value) {
 520              if (strpos($key, 'xmlns') === false) {
 521                  if (strpos($key, ':') !== false) {
 522                      $expandedTag = $this->expandNamespacePrefix($key);
 523                      $arTransform[$key] = $expandedTag;
 524                  }
 525              }
 526          }
 527  
 528          foreach ($arTransform as $key => $value) {
 529              $myAttributes[$value] = $myAttributes[$key];
 530              unset($myAttributes[$key]);
 531          }
 532      } //expandAttributePrefixes
 533  
 534      /**
 535      * Expands the namespace prefix (if one exists) to the full namespace uri
 536      * @param string The tagName with the namespace prefix
 537      * @return string The tagName, with the prefix expanded to the namespace uri
 538      */
 539  	function expandNamespacePrefix($tagName) {
 540          $stackLen = count($this->defaultNamespaceStack);
 541          $defaultNamespace = $this->defaultNamespaceStack[($stackLen - 1)];
 542  
 543          $colonIndex = strpos($tagName, ':');
 544  
 545          if ($colonIndex !== false) {
 546              $prefix = substr($tagName, 0, $colonIndex);
 547  
 548              if ($prefix != 'xml') {
 549                  $tagName = $this->getNamespaceURI($prefix) . substr($tagName, $colonIndex);
 550              }
 551              else {
 552                  $tagName = SAXY_XML_NAMESPACE . substr($tagName, $colonIndex);
 553              }
 554          }
 555          else if ($defaultNamespace != '') {
 556              $tagName = $defaultNamespace . ':' . $tagName;
 557          }
 558  
 559          return $tagName;
 560      } //expandNamespacePrefix
 561  
 562      /**
 563      * Searches the namespaceMap for the specified prefix, and returns the full namespace URI
 564      * @param string The namespace prefix
 565      * @return string The namespace uri
 566      */
 567  	function getNamespaceURI($prefix) {
 568          $total = count($this->namespaceMap);
 569          $uri = $prefix; //in case uri can't be found, just send back prefix
 570                          //should really generate an error, but worry about this later
 571          //reset($this->namespaceMap);
 572  
 573          for ($i = ($total - 1); $i >= 0; $i--) {
 574              $currMap =& $this->namespaceMap[$i];
 575  
 576              if (isset($currMap[$prefix])) {
 577                  $uri = $currMap[$prefix];
 578                  break;
 579              }
 580          }
 581  
 582          return $uri;
 583      } //getNamespaceURI
 584  
 585      /**
 586      * Searches the attributes array for an xmlns declaration and fires an event if found
 587      * @param Array The start element attributes
 588      */
 589  	function detectStartNamespaceDeclaration(&$myAttributes) {
 590          $namespaceExists = false;
 591          $namespaceMapUpper = 0;
 592          $userDefinedDefaultNamespace = false;
 593          $total = count($myAttributes);
 594  
 595          foreach ($myAttributes as $key => $value) {
 596              if (strpos($key, 'xmlns') !== false) {
 597                  //add an array to store all namespaces for the current element
 598                  if (!$namespaceExists) {
 599                      $this->namespaceMap[] = array();
 600                      $namespaceMapUpper = count($this->namespaceMap) - 1;
 601                  }
 602  
 603                  //check for default namespace override, i.e. xmlns='...'
 604                  if (strpos($key, ':') !== false) {
 605                      $prefix = $namespaceMapKey = substr($key, 6);
 606                      $this->namespaceMap[$namespaceMapUpper][$namespaceMapKey] = $value;
 607                  }
 608                  else {
 609                      $prefix = '';
 610                      $userDefinedDefaultNamespace = true;
 611  
 612                      //if default namespace '', store in map using key ':'
 613                      $this->namespaceMap[$namespaceMapUpper][':'] = $value;
 614                      $this->defaultNamespaceStack[] = $value;
 615                  }
 616  
 617                  $this->fireStartNamespaceDeclarationEvent($prefix, $value);
 618                  $namespaceExists = true;
 619  
 620                  unset($myAttributes[$key]);
 621              }
 622          }
 623  
 624          //store the default namespace (inherited from the parent elements so grab last one)
 625          if (!$userDefinedDefaultNamespace) {
 626              $stackLen = count($this->defaultNamespaceStack);
 627              if ($stackLen == 0) {
 628                  $this->defaultNamespaceStack[] = '';
 629              }
 630              else {
 631                  $this->defaultNamespaceStack[] =
 632                      $this->defaultNamespaceStack[($stackLen - 1)];
 633              }
 634          }
 635  
 636          $this->namespaceStack[] = $namespaceExists;
 637      } //detectStartNamespaceDeclaration
 638  
 639      /**
 640      * Fires an end element event and pops the element name from the elementName stack
 641      * @param string The end element tag name
 642      */
 643  	function _fireEndElementEvent($tagName) {
 644          $lastTagName = array_pop($this->elementNameStack);
 645  
 646          //check for mismatched tag error
 647          if ($lastTagName != $tagName) {
 648              $this->errorCode = SAXY_XML_ERROR_TAG_MISMATCH;
 649          }
 650  
 651          if ($this->isNamespaceAware) {
 652              $tagName = $this->expandNamespacePrefix($tagName);
 653              $this->fireEndElementEvent($tagName);
 654              $this->detectEndNamespaceDeclaration();
 655              $defaultNamespace = array_pop($this->defaultNamespaceStack);
 656          }
 657          else {
 658              $this->fireEndElementEvent($tagName);
 659          }
 660      } //_fireEndElementEvent
 661  
 662      /**
 663      * Determines whether an end namespace declaration event should be fired
 664      */
 665  	function detectEndNamespaceDeclaration() {
 666          $isNamespaceEnded = array_pop($this->namespaceStack);
 667  
 668          if ($isNamespaceEnded) {
 669              $map = array_pop($this->namespaceMap);
 670  
 671              foreach ($map as $key => $value) {
 672                  if ($key == ':') {
 673                      $key = '';
 674                  }
 675                  $this->fireEndNamespaceDeclarationEvent($key);
 676              }
 677          }
 678      } //detectEndNamespaceDeclaration
 679  
 680      /**
 681      * Parses a processing instruction
 682      * @param string The interior text of the processing instruction
 683      */
 684  	function parseProcessingInstruction($data) {
 685          $endTarget = 0;
 686          $total = strlen($data);
 687  
 688          for ($x = 2; $x < $total; $x++) {
 689              if (trim($data{$x}) == '') {
 690                  $endTarget = $x;
 691                  break;
 692              }
 693          }
 694  
 695          $target = substr($data, 1, ($endTarget - 1));
 696          $data = substr($data, ($endTarget + 1), ($total - $endTarget - 2));
 697  
 698          if ($this->processingInstructionHandler != null) {
 699              $this->fireProcessingInstructionEvent($target, $data);
 700          }
 701      } //parseProcessingInstruction
 702  
 703      /**
 704      * Parses a comment
 705      * @param string The interior text of the comment
 706      */
 707  	function parseComment($data) {
 708          if ($this->commentHandler != null) {
 709              $this->fireCommentEvent($data);
 710          }
 711      } //parseComment
 712  
 713      /**
 714      * Fires a doctype event
 715      * @param string The doctype data
 716      */
 717  	function fireDTDEvent($data) {
 718          call_user_func($this->DTDHandler, $this, $data);
 719      } //fireDTDEvent
 720  
 721      /**
 722      * Fires a comment event
 723      * @param string The text of the comment
 724      */
 725  	function fireCommentEvent($data) {
 726          call_user_func($this->commentHandler, $this, $data);
 727      } //fireCommentEvent
 728  
 729      /**
 730      * Fires a processing instruction event
 731      * @param string The processing instruction data
 732      */
 733  	function fireProcessingInstructionEvent($target, $data) {
 734          call_user_func($this->processingInstructionHandler, $this, $target, $data);
 735      } //fireProcessingInstructionEvent
 736  
 737      /**
 738      * Fires a start namespace declaration event
 739      * @param string The namespace prefix
 740      * @param string The namespace uri
 741      */
 742  	function fireStartNamespaceDeclarationEvent($prefix, $uri) {
 743          call_user_func($this->startNamespaceDeclarationHandler, $this, $prefix, $uri);
 744      } //fireStartNamespaceDeclarationEvent
 745  
 746      /**
 747      * Fires an end namespace declaration event
 748      * @param string The namespace prefix
 749      */
 750  	function fireEndNamespaceDeclarationEvent($prefix) {
 751          call_user_func($this->endNamespaceDeclarationHandler, $this, $prefix);
 752      } //fireEndNamespaceDeclarationEvent
 753  
 754      /**
 755      * Returns the current error code
 756      * @return int The current error code
 757      */
 758  	function xml_get_error_code() {
 759          return $this->errorCode;
 760      } //xml_get_error_code
 761  
 762      /**
 763      * Returns a textual description of the error code
 764      * @param int The error code
 765      * @return string The error message
 766      */
 767  	function xml_error_string($code) {
 768          switch ($code) {
 769              case SAXY_XML_ERROR_NONE:
 770                  return "No error";
 771                  break;
 772              case SAXY_XML_ERROR_NO_MEMORY:
 773                  return "Out of memory";
 774                  break;
 775              case SAXY_XML_ERROR_SYNTAX:
 776                  return "Syntax error";
 777                  break;
 778              case SAXY_XML_ERROR_NO_ELEMENTS:
 779                  return "No elements in document";
 780                  break;
 781              case SAXY_XML_ERROR_INVALID_TOKEN:
 782                  return "Invalid token";
 783                  break;
 784              case SAXY_XML_ERROR_UNCLOSED_TOKEN:
 785                  return "Unclosed token";
 786                  break;
 787              case SAXY_XML_ERROR_PARTIAL_CHAR:
 788                  return "Partial character";
 789                  break;
 790              case SAXY_XML_ERROR_TAG_MISMATCH:
 791                  return "Tag mismatch";
 792                  break;
 793              case SAXY_XML_ERROR_DUPLICATE_ATTRIBUTE:
 794                  return "Duplicate attribute";
 795                  break;
 796              case SAXY_XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
 797                  return "Junk encountered after document element";
 798                  break;
 799              case SAXY_XML_ERROR_PARAM_ENTITY_REF:
 800                  return "Parameter entity reference error";
 801                  break;
 802              case SAXY_XML_ERROR_UNDEFINED_ENTITY:
 803                  return "Undefined entity";
 804                  break;
 805              case SAXY_XML_ERROR_RECURSIVE_ENTITY_REF:
 806                  return "Recursive entity reference";
 807                  break;
 808              case SAXY_XML_ERROR_ASYNC_ENTITY:
 809                  return "Asynchronous internal entity found in external entity";
 810                  break;
 811              case SAXY_XML_ERROR_BAD_CHAR_REF:
 812                  return "Bad character reference";
 813                  break;
 814              case SAXY_XML_ERROR_BINARY_ENTITY_REF:
 815                  return "Binary entity reference";
 816                  break;
 817              case SAXY_XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
 818                  return "Attribute external entity reference";
 819                  break;
 820              case SAXY_XML_ERROR_MISPLACED_XML_PI:
 821                  return "Misplaced processing instruction";
 822                  break;
 823              case SAXY_XML_ERROR_UNKNOWN_ENCODING:
 824                  return "Unknown encoding";
 825                  break;
 826              case SAXY_XML_ERROR_INCORRECT_ENCODING:
 827                  return "Incorrect encoding";
 828                  break;
 829              case SAXY_XML_ERROR_UNCLOSED_CDATA_SECTION:
 830                  return "Unclosed CDATA Section";
 831                  break;
 832              case SAXY_XML_ERROR_EXTERNAL_ENTITY_HANDLING:
 833                  return "Problem in external entity handling";
 834                  break;
 835              default:
 836                  return "No definition for error code " . $code;
 837                  break;
 838          }
 839      } //xml_error_string
 840  
 841  } //SAXY_Parser
 842  ?>


Généré le : Wed Nov 21 14:43:32 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics