1 2 大家都知é?“PHP4䏿²¡æœ‰SimpleXML扩展,è¦?XMLè§£æž?æˆ?数组是件麻烦的事,最近æ£å¥½ç”¨åˆ°ç›¸å…³æŠ€æœ¯ï¼ŒäºŽæ˜¯å°±è‡ªå·±å†™ä¸€ä¸ªï¼Œä»¥ä¸‹æ˜¯æº?代ç ?: 3 4 SofeeXmlParser.php 5 <?php 6 /* 7 +----------------------------------------------------------------------+ 8 | SofeeFramework for PHP 4 | 9 +----------------------------------------------------------------------+ 10 | Copyright (c) 2004-2005 Sofee Development Team.(http://www.sofee.cn) | 11 +----------------------------------------------------------------------+ 12 | This source file is subject to version 1.00 of the Sofee license, | 13 | that is bundled with this package in the file LICENSE, and is | 14 | available through the world-wide-web at the following url: | 15 | http://www.sofee.cn/license/1_00.txt. | 16 | If you did not receive a copy of the Sofee license and are unable to | 17 | obtain it through the world-wide-web, please send a note to | 18 | license@sofee.cn so we can mail you a copy immediately. | 19 +----------------------------------------------------------------------+ 20 | Author: Justin Wu <ezdevelop@gmail.com> | 21 +----------------------------------------------------------------------+ 22 */ 23 24 /* $Id: SofeeXmlParser.php,v 1.3 2005/05/30 06:30:14 wenlong Exp $ */ 25 26 /** 27 * Sofee XML Parser class - This is an XML parser based on PHP's "xml" extension. 28 * 29 * The SofeeXmlParser class provides a very simple and easily usable toolset to convert XML 30 * to an array that can be processed with array iterators. 31 * 32 * @package SofeeFramework 33 * @access public 34 * @version $Revision: 1.1 $ 35 * @author Justin Wu <wenlong@php.net> 36 * @homepage http://www.sofee.cn 37 * @copyright Copyright (c) 2004-2005 Sofee Development Team.(http://www.sofee.cn) 38 * @since 2005-05-30 39 * @see PEAR:XML_Parser | SimpleXML extension 40 */ 41 class SofeeXmlParser { 42 43 /** 44 * XML parser handle 45 * 46 * @var resource 47 * @see xml_parser_create() 48 */ 49 var $parser; 50 51 /** 52 * source encoding 53 * 54 * @var string 55 */ 56 var $srcenc; 57 58 /** 59 * target encoding 60 * 61 * @var string 62 */ 63 var $dstenc; 64 65 /** 66 * the original struct 67 * 68 * @access private 69 * @var array 70 */ 71 var $_struct = array(); 72 73 /** 74 * Constructor 75 * 76 * @access public 77 * @param mixed [$srcenc] source encoding 78 * @param mixed [$dstenc] target encoding 79 * @return void 80 * @since 81 */ 82 function SofeeXmlParser($srcenc = null, $dstenc = null) { 83 $this->srcenc = $srcenc; 84 $this->dstenc = $dstenc; 85 86 // initialize the variable. 87 $this->parser = null; 88 $this->_struct = array(); 89 } 90 91 /** 92 * Free the resources 93 * 94 * @access public 95 * @return void 96 **/ 97 function free() { 98 if (isset($this->parser) && is_resource($this->parser)) { 99 xml_parser_free($this->parser); 100 unset($this->parser); 101 } 102 } 103 104 /** 105 * Parses the XML file 106 * 107 * @access public 108 * @param string [$file] the XML file name 109 * @return void 110 * @since 111 */ 112 function parseFile($file) { 113 $data = @file_get_contents($file) or die("Can't open file $file for reading!"); 114 $this->parseString($data); 115 } 116 117 /** 118 * Parses a string. 119 * 120 * @access public 121 * @param string [$data] XML data 122 * @return void 123 */ 124 function parseString($data) { 125 if ($this->srcenc === null) { 126 $this->parser = @xml_parser_create() or die('Unable to create XML parser resource.'); 127 } else { 128 $this->parser = @xml_parser_create($this->srcenc) or die('Unable to create XML parser resource with '. $this->srcenc .' encoding.'); 129 } 130 131 if ($this->dstenc !== null) { 132 @xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->dstenc) or die('Invalid target encoding'); 133 } 134 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); // lowercase tags 135 xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 1); // skip empty tags 136 if (!xml_parse_into_struct($this->parser, $data, &$this->_struct)) { 137 printf("XML error: %s at line %d", 138 xml_error_string(xml_get_error_code($this->parser)), 139 xml_get_current_line_number($this->parser) 140 ); 141 $this->free(); 142 exit(); 143 } 144 145 $this->_count = count($this->_struct); 146 $this->free(); 147 } 148 149 /** 150 * return the data struction 151 * 152 * @access public 153 * @return array 154 */ 155 function getTree() { 156 $i = 0; 157 $tree = array(); 158 159 $tree = $this->addNode( 160 $tree, 161 $this->_struct[$i]['tag'], 162 (isset($this->_struct[$i]['value'])) ? $this->_struct[$i]['value'] : '', 163 (isset($this->_struct[$i]['attributes'])) ? $this->_struct[$i]['attributes'] : '', 164 $this->getChild($i) 165 ); 166 167 unset($this->_struct); 168 return ($tree); 169 } 170 171 /** 172 * recursion the children node data 173 * 174 * @access public 175 * @param integer [$i] the last struct index 176 * @return array 177 */ 178 function getChild(&$i) { 179 // contain node data 180 $children = array(); 181 182 // loop 183 while (++$i < $this->_count) { 184 // node tag name 185 $tagname = $this->_struct[$i]['tag']; 186 $value = isset($this->_struct[$i]['value']) ? $this->_struct[$i]['value'] : ''; 187 $attributes = isset($this->_struct[$i]['attributes']) ? $this->_struct[$i]['attributes'] : ''; 188 189 switch ($this->_struct[$i]['type']) { 190 case 'open': 191 // node has more children 192 $child = $this->getChild($i); 193 // append the children data to the current node 194 $children = $this->addNode($children, $tagname, $value, $attributes, $child); 195 break; 196 case 'complete': 197 // at end of current branch 198 $children = $this->addNode($children, $tagname, $value, $attributes); 199 break; 200 case 'cdata': 201 // node has CDATA after one of it's children 202 $children['value'] .= $value; 203 break; 204 case 'close': 205 // end of node, return collected data 206 return $children; 207 break; 208 } 209 210 } 211 //return $children; 212 } 213 214 /** 215 * Appends some values to an array 216 * 217 * @access public 218 * @param array [$target] 219 * @param string [$key] 220 * @param string [$value] 221 * @param array [$attributes] 222 * @param array [$inner] the children 223 * @return void 224 * @since 225 */ 226 function addNode($target, $key, $value = '', $attributes = '', $child = '') { 227 if (!isset($target[$key]['value']) && !isset($target[$key][0])) { 228 if ($child != '') { 229 $target[$key] = $child; 230 } 231 if ($attributes != '') { 232 foreach ($attributes as $k => $v) { 233 $target[$key][$k] = $v; 234 } 235 } 236 237 $target[$key]['value'] = $value; 238 } else { 239 if (!isset($target[$key][0])) { 240 // is string or other 241 $oldvalue = $target[$key]; 242 $target[$key] = array(); 243 $target[$key][0] = $oldvalue; 244 $index = 1; 245 } else { 246 // is array 247 $index = count($target[$key]); 248 } 249 250 if ($child != '') { 251 $target[$key][$index] = $child; 252 } 253 254 if ($attributes != '') { 255 foreach ($attributes as $k => $v) { 256 $target[$key][$index][$k] = $v; 257 } 258 } 259 $target[$key][$index]['value'] = $value; 260 } 261 return $target; 262 } 263 264 } 265 266 调用方å¼?: 267 <?php 268 $file = 'test.xml'; 269 require_once('SofeeXmlParser.php'); 270 $xml = new SofeeXmlParser(); 271 $xml->parseFile($file); 272 $tree = $xml->getTree(); 273 unset($xml); 274 print "<pre>"; 275 print_r($tree); 276 print "</pre>"; 277 ?> 278 279 test.xml文件内容: 280 <?xml version="1.0" encoding="GBK"?> 281 <nba update="2005-06-07"> 282 <team id="46">皇家马德里</team> 283 <team id="47">尤文图斯</team> 284 <team id="51">ç?«ç®</team> 285 <team id="52">æ²ƒå°”å¤«æ–¯å ¡</team> 286 <team id="53">巴塞罗那</team> 287 <team id="54">太阳</team> 288 </nba> 289 290 输出结果: 291 292 293 Array 294 ( 295 [nba] => Array 296 ( 297 [team] => Array 298 ( 299 [0] => Array 300 ( 301 [id] => 46 302 [value] => 皇家马德里 303 ) 304 305 [1] => Array 306 ( 307 [id] => 47 308 [value] => 尤文图斯 309 ) 310 311 [2] => Array 312 ( 313 [id] => 51 314 [value] => ç?«ç® 315 ) 316 317 [3] => Array 318 ( 319 [id] => 52 320 [value] => æ²ƒå°”å¤«æ–¯å ¡ 321 ) 322 323 [4] => Array 324 ( 325 [id] => 53 326 [value] => 巴塞罗那 327 ) 328 329 [5] => Array 330 ( 331 [id] => 54 332 [value] => 太阳 333 ) 334 335 ) 336 337 [update] => 2005-06-07 338 [value] => 339 ) 340 341 ) 342 343 344 Array 345 ( 346 [nba] => Array 347 ( 348 [team] => Array 349 ( 350 [0] => Array 351 ( 352 [id] => 46 353 [value] => 皇家马德里 354 ) 355 356 [1] => Array 357 ( 358 [id] => 47 359 [value] => 尤文图斯 360 ) 361 362 [2] => Array 363 ( 364 [id] => 51 365 [value] => ç?«ç® 366 ) 367 368 [3] => Array 369 ( 370 [id] => 52 371 [value] => æ²ƒå°”å¤«æ–¯å ¡ 372 ) 373 374 [4] => Array 375 ( 376 [id] => 53 377 [value] => 巴塞罗那 378 ) 379 380 [5] => Array 381 ( 382 [id] => 54 383 [value] => 太阳 384 ) 385 386 ) 387 388 [update] => 2005-06-07 389 [value] => 390 ) 391 392 ) 393 394
You need to create an account or log in to post comments to this site.