1<?php 2/* vim: set expandtab tabstop=4 shiftwidth=4: */ 3// 4// +----------------------------------------------------------------------+ 5// | PHP Version 4 | 6// +----------------------------------------------------------------------+ 7// | Copyright (c) 1997-2002 The PHP Group | 8// +----------------------------------------------------------------------+ 9// | This source file is subject to version 2.02 of the PHP license, | 10// | that is bundled with this package in the file LICENSE, and is | 11// | available at through the world-wide-web at | 12// | http://www.php.net/license/3_0.txt. | 13// | If you did not receive a copy of the PHP license and are unable to | 14// | obtain it through the world-wide-web, please send a note to | 15// | license@php.net so we can mail you a copy immediately. | 16// +----------------------------------------------------------------------+ 17// | Authors: Alexander Zhukov <alex@veresk.ru> Original port from Python | 18// | Authors: Harry Fuecks <hfuecks@phppatterns.com> Port to PEAR + more | 19// | Authors: Many @ Sitepointforums Advanced PHP Forums | 20// +----------------------------------------------------------------------+ 21// 22// $Id: XML_HTMLSax_States.php,v 1.7 2003/12/04 23:35:20 harryf Exp $ 23// 24/** 25* Main parser components 26* @package XML_HTMLSax 27* @version $Id: XML_HTMLSax_States.php,v 1.7 2003/12/04 23:35:20 harryf Exp $ 28*/ 29/** 30* Define parser states 31*/ 32define('XML_HTMLSAX_STATE_STOP', 0); 33define('XML_HTMLSAX_STATE_START', 1); 34define('XML_HTMLSAX_STATE_TAG', 2); 35define('XML_HTMLSAX_STATE_OPENING_TAG', 3); 36define('XML_HTMLSAX_STATE_CLOSING_TAG', 4); 37define('XML_HTMLSAX_STATE_ESCAPE', 6); 38define('XML_HTMLSAX_STATE_JASP', 7); 39define('XML_HTMLSAX_STATE_PI', 8); 40/** 41* StartingState searches for the start of any XML tag 42* @package XML_HTMLSax 43* @access protected 44*/ 45class XML_HTMLSax_StartingState { 46 /** 47 * @param XML_HTMLSax_StateParser subclass 48 * @return constant XML_HTMLSAX_STATE_TAG 49 * @access protected 50 */ 51 function parse(&$context) { 52 $data = $context->scanUntilString('<'); 53 if ($data != '') { 54 $context->handler_object_data-> 55 {$context->handler_method_data}($context->htmlsax, $data); 56 } 57 $context->IgnoreCharacter(); 58 return XML_HTMLSAX_STATE_TAG; 59 } 60} 61/** 62* Decides which state to move one from after StartingState 63* @package XML_HTMLSax 64* @access protected 65*/ 66class XML_HTMLSax_TagState { 67 /** 68 * @param XML_HTMLSax_StateParser subclass 69 * @return constant the next state to move into 70 * @access protected 71 */ 72 function parse(&$context) { 73 switch($context->ScanCharacter()) { 74 case '/': 75 return XML_HTMLSAX_STATE_CLOSING_TAG; 76 break; 77 case '?': 78 return XML_HTMLSAX_STATE_PI; 79 break; 80 case '%': 81 return XML_HTMLSAX_STATE_JASP; 82 break; 83 case '!': 84 return XML_HTMLSAX_STATE_ESCAPE; 85 break; 86 default: 87 $context->unscanCharacter(); 88 return XML_HTMLSAX_STATE_OPENING_TAG; 89 } 90 } 91} 92/** 93* Dealing with closing XML tags 94* @package XML_HTMLSax 95* @access protected 96*/ 97class XML_HTMLSax_ClosingTagState { 98 /** 99 * @param XML_HTMLSax_StateParser subclass 100 * @return constant XML_HTMLSAX_STATE_START 101 * @access protected 102 */ 103 function parse(&$context) { 104 $tag = $context->scanUntilCharacters('/>'); 105 if ($tag != '') { 106 $char = $context->scanCharacter(); 107 if ($char == '/') { 108 $char = $context->scanCharacter(); 109 if ($char != '>') { 110 $context->unscanCharacter(); 111 } 112 } 113 $context->handler_object_element-> 114 {$context->handler_method_closing}($context->htmlsax, $tag, FALSE); 115 } 116 return XML_HTMLSAX_STATE_START; 117 } 118} 119/** 120* Dealing with opening XML tags 121* @package XML_HTMLSax 122* @access protected 123*/ 124class XML_HTMLSax_OpeningTagState { 125 /** 126 * Handles attributes 127 * @param string attribute name 128 * @param string attribute value 129 * @return void 130 * @access protected 131 * @see XML_HTMLSax_AttributeStartState 132 */ 133 function parseAttributes(&$context) { 134 $Attributes = array(); 135 136 $context->ignoreWhitespace(); 137 $attributename = $context->scanUntilCharacters("=/> \n\r\t"); 138 while ($attributename != '') { 139 $attributevalue = NULL; 140 $context->ignoreWhitespace(); 141 $char = $context->scanCharacter(); 142 if ($char == '=') { 143 $context->ignoreWhitespace(); 144 $char = $context->ScanCharacter(); 145 if ($char == '"') { 146 $attributevalue= $context->scanUntilString('"'); 147 $context->IgnoreCharacter(); 148 } else if ($char == "'") { 149 $attributevalue = $context->scanUntilString("'"); 150 $context->IgnoreCharacter(); 151 } else { 152 $context->unscanCharacter(); 153 $attributevalue = 154 $context->scanUntilCharacters("> \n\r\t"); 155 } 156 } else if ($char !== NULL) { 157 $attributevalue = true; 158 $context->unscanCharacter(); 159 } 160 $Attributes[$attributename] = $attributevalue; 161 162 $context->ignoreWhitespace(); 163 $attributename = $context->scanUntilCharacters("=/> \n\r\t"); 164 } 165 return $Attributes; 166 } 167 168 /** 169 * @param XML_HTMLSax_StateParser subclass 170 * @return constant XML_HTMLSAX_STATE_START 171 * @access protected 172 */ 173 function parse(&$context) { 174 $tag = $context->scanUntilCharacters("/> \n\r\t"); 175 if ($tag != '') { 176 $this->attrs = array(); 177 $Attributes = $this->parseAttributes($context); 178 $char = $context->scanCharacter(); 179 if ($char == '/') { 180 $char = $context->scanCharacter(); 181 if ($char != '>') { 182 $context->unscanCharacter(); 183 } 184 $context->handler_object_element-> 185 {$context->handler_method_opening}($context->htmlsax, $tag, 186 $Attributes, TRUE); 187 $context->handler_object_element-> 188 {$context->handler_method_closing}($context->htmlsax, $tag, 189 TRUE); 190 } else { 191 $context->handler_object_element-> 192 {$context->handler_method_opening}($context->htmlsax, $tag, 193 $Attributes, FALSE); 194 } 195 } 196 return XML_HTMLSAX_STATE_START; 197 } 198} 199 200/** 201* Deals with XML escapes handling comments and CDATA correctly 202* @package XML_HTMLSax 203* @access protected 204*/ 205class XML_HTMLSax_EscapeState { 206 /** 207 * @param XML_HTMLSax_StateParser subclass 208 * @return constant XML_HTMLSAX_STATE_START 209 * @access protected 210 */ 211 function parse(&$context) { 212 if ($context->parser_options['XML_OPTION_FULL_ESCAPES']==0) { 213 $char = $context->ScanCharacter(); 214 if ($char == '-') { 215 $char = $context->ScanCharacter(); 216 if ($char == '-') { 217 $text = $context->scanUntilString('-->'); 218 $context->IgnoreCharacter(); 219 $context->IgnoreCharacter(); 220 } else { 221 $context->unscanCharacter(); 222 $text = $context->scanUntilString('>'); 223 } 224 } else if ( $char == '[') { 225 $context->scanUntilString('CDATA['); 226 for ( $i=0;$i<6;$i++ ) { 227 $context->IgnoreCharacter(); 228 } 229 $text = $context->scanUntilString(']]>'); 230 $context->IgnoreCharacter(); 231 $context->IgnoreCharacter(); 232 } else { 233 $context->unscanCharacter(); 234 $text = $context->scanUntilString('>'); 235 } 236 } else { 237 $text = $context->scanUntilString('>'); 238 } 239 $context->IgnoreCharacter(); 240 if ($text != '') { 241 $context->handler_object_escape-> 242 {$context->handler_method_escape}($context->htmlsax, $text); 243 } 244 return XML_HTMLSAX_STATE_START; 245 } 246} 247/** 248* Deals with JASP/ASP markup 249* @package XML_HTMLSax 250* @access protected 251*/ 252class XML_HTMLSax_JaspState { 253 /** 254 * @param XML_HTMLSax_StateParser subclass 255 * @return constant XML_HTMLSAX_STATE_START 256 * @access protected 257 */ 258 function parse(&$context) { 259 $text = $context->scanUntilString('%>'); 260 if ($text != '') { 261 $context->handler_object_jasp-> 262 {$context->handler_method_jasp}($context->htmlsax, $text); 263 } 264 $context->IgnoreCharacter(); 265 $context->IgnoreCharacter(); 266 return XML_HTMLSAX_STATE_START; 267 } 268} 269/** 270* Deals with XML processing instructions 271* @package XML_HTMLSax 272* @access protected 273*/ 274class XML_HTMLSax_PiState { 275 /** 276 * @param XML_HTMLSax_StateParser subclass 277 * @return constant XML_HTMLSAX_STATE_START 278 * @access protected 279 */ 280 function parse(&$context) { 281 $target = $context->scanUntilCharacters(" \n\r\t"); 282 $data = $context->scanUntilString('?>'); 283 if ($data != '') { 284 $context->handler_object_pi-> 285 {$context->handler_method_pi}($context->htmlsax, $target, $data); 286 } 287 $context->IgnoreCharacter(); 288 $context->IgnoreCharacter(); 289 return XML_HTMLSAX_STATE_START; 290 } 291} 292?>