1<?php 2 function var2xml($name, $data) 3 { 4 $doc = new xmltool('root','',''); 5 return $doc->import_var($name,$data,True,True); 6 } 7 8 class xmltool 9 { 10 /* for root nodes */ 11 var $xmlversion = '1.0'; 12 var $doctype = Array(); 13 /* shared */ 14 var $node_type = ''; 15 var $name = ''; 16 var $data_type; 17 var $data; 18 /* for nodes */ 19 var $attributes = Array(); 20 var $comments = Array(); 21 var $indentstring = "\t"; 22 23 /* start the class as either a root or a node */ 24 function xmltool ($node_type = 'root', $name='',$indentstring="\t") 25 { 26 $this->node_type = $node_type; 27 $this->indentstring = $indentstring; 28 if ($this->node_type == 'node') 29 { 30 if($name != '') 31 { 32 $this->name = $name; 33 } 34 else 35 { 36 echo 'You must name node type objects<br>'; 37 exit; 38 } 39 } 40 } 41 42 function set_version ($version = '1.0') 43 { 44 $this->xmlversion = $version; 45 return True; 46 } 47 48 function set_doctype ($name, $uri = '') 49 { 50 if ($this->node_type == 'root') 51 { 52 $this->doctype[$name] = $uri; 53 return True; 54 } 55 else 56 { 57 return False; 58 } 59 } 60 61 function add_node ($node_object, $name = '') 62 { 63 switch ($this->node_type) 64 { 65 case 'root': 66 if (is_object($node_object)) 67 { 68 $this->data = $node_object; 69 } 70 else 71 { 72 $this->data = $this->import_var($name, $node_object); 73 } 74 break; 75 case 'node': 76 if(!is_array($this->data)) 77 { 78 $this->data = Array(); 79 $this->data_type = 'node'; 80 } 81 if (is_object($node_object)) 82 { 83 if ($name != '') 84 { 85 $this->data[$name] = $node_object; 86 } 87 else 88 { 89 $this->data[] = $node_object; 90 } 91 } 92 else 93 { 94 $this->data[$name] = $this->import_var($name, $node_object); 95 } 96 return True; 97 break; 98 } 99 } 100 101 function get_node ($name = '') // what is that function doing: NOTHING !!! 102 { 103 switch ($this->data_type) 104 { 105 case 'root': 106 break; 107 case 'node': 108 break; 109 case 'object': 110 break; 111 } 112 113 } 114 115 function set_value ($string) 116 { 117 $this->data = $string; 118 $this->data_type = 'value'; 119 return True; 120 } 121 122 function get_value () 123 { 124 if($this->data_type == 'value') 125 { 126 return $this->data; 127 } 128 else 129 { 130 return False; 131 } 132 } 133 134 function set_attribute ($name, $value = '') 135 { 136 $this->attributes[$name] = $value; 137 return True; 138 } 139 140 function get_attribute ($name) 141 { 142 return $this->attributes[$name]; 143 } 144 145 function get_attributes () 146 { 147 return $this->attributes; 148 } 149 150 function add_comment ($comment) 151 { 152 $this->comments[] = $comment; 153 return True; 154 } 155 156 function import_var($name, $value,$is_root=False,$export_xml=False) 157 { 158 echo "<p>import_var: this->indentstring='$this->indentstring'</p>\n"; 159 $node = new xmltool('node',$name,$this->indentstring); 160 switch (gettype($value)) 161 { 162 case 'string': 163 case 'integer': 164 case 'double': 165 case 'NULL': 166 $node->set_value($value); 167 break; 168 case 'boolean': 169 if($value == True) 170 { 171 $node->set_value('1'); 172 } 173 else 174 { 175 $node->set_value('0'); 176 } 177 break; 178 case 'array': 179 $new_index = False; 180 while (list ($idxkey, $idxval) = each ($value)) 181 { 182 if(is_array($idxval)) 183 { 184 while (list ($k, $i) = each ($idxval)) 185 { 186 if (is_int($k)) 187 { 188 $new_index = True; 189 } 190 } 191 } 192 } 193 reset($value); 194 while (list ($key, $val) = each ($value)) 195 { 196 if($new_index) 197 { 198 $keyname = $name; 199 $nextkey = $key; 200 } 201 else 202 { 203 $keyname = $key; 204 $nextkey = $key; 205 } 206 switch (gettype($val)) 207 { 208 case 'string': 209 case 'integer': 210 case 'double': 211 case 'NULL': 212 $subnode = new xmltool('node', $nextkey,$this->indentstring); 213 $subnode->set_value($val); 214 $node->add_node($subnode); 215 break; 216 case 'boolean': 217 $subnode = new xmltool('node', $nextkey,$this->indentstring); 218 if($val == True) 219 { 220 $subnode->set_value('1'); 221 } 222 else 223 { 224 $subnode->set_value('0'); 225 } 226 $node->add_node($subnode); 227 break; 228 case 'array': 229 if($new_index) 230 { 231 while (list ($subkey, $subval) = each ($val)) 232 { 233 $node->add_node($this->import_var($nextkey, $subval)); 234 } 235 } 236 else 237 { 238 $subnode = $this->import_var($nextkey, $val); 239 $node->add_node($subnode); 240 } 241 break; 242 case 'object': 243 $subnode = new xmltool('node', $nextkey,$this->indentstring); 244 $subnode->set_value('PHP_SERIALIZED_OBJECT&:'.serialize($val)); 245 $node->add_node($subnode); 246 break; 247 case 'resource': 248 echo 'Halt: Cannot package PHP resource pointers into XML<br>'; 249 exit; 250 default: 251 echo 'Halt: Invalid or unknown data type<br>'; 252 exit; 253 } 254 } 255 break; 256 case 'object': 257 $node->set_value('PHP_SERIALIZED_OBJECT&:'.serialize($value)); 258 break; 259 case 'resource': 260 echo 'Halt: Cannot package PHP resource pointers into XML<br>'; 261 exit; 262 default: 263 echo 'Halt: Invalid or unknown data type<br>'; 264 exit; 265 } 266 267 if($is_root) 268 { 269 $this->add_node($node); 270 if($export_xml) 271 { 272 $xml = $this->export_xml(); 273 return $xml; 274 } 275 else 276 { 277 return True; 278 } 279 } 280 else 281 { 282 $this->add_node($node); 283 return $node; 284 } 285 } 286 287 function export_var() 288 { 289 if($this->node_type == 'root') 290 { 291 return $this->data->export_var(); 292 } 293 294 if($this->data_type != 'node') 295 { 296 $found_at = strstr($this->data,'PHP_SERIALIZED_OBJECT&:'); 297 if($found_at != False) 298 { 299 return unserialize(str_replace ('PHP_SERIALIZED_OBJECT&:', '', $this->data)); 300 } 301 return $this->data; 302 } 303 else 304 { 305 $new_index = False; 306 reset($this->data); 307 while(list($key,$val) = each($this->data)) 308 { 309 if(!isset($found_keys[$val->name])) 310 { 311 $found_keys[$val->name] = True; 312 } 313 else 314 { 315 $new_index = True; 316 } 317 } 318 319 if($new_index) 320 { 321 reset($this->data); 322 while(list($key,$val) = each($this->data)) 323 { 324 325 $return_array[$val->name][] = $val->export_var(); 326 } 327 } 328 else 329 { 330 reset($this->data); 331 while(list($key,$val) = each($this->data)) 332 { 333 $return_array[$val->name] = $val->export_var(); 334 } 335 } 336 return $return_array; 337 } 338 } 339 340 function export_struct() 341 { 342 if($this->node_type == 'root') 343 { 344 return $this->data->export_struct(); 345 } 346 347 $retval['tag'] = $this->name; 348 $retval['attributes'] = $this->attributes; 349 if($this->data_type != 'node') 350 { 351 $found_at = strstr($this->data,'PHP_SERIALIZED_OBJECT&:'); 352 if($found_at != False) 353 { 354 $retval['value'] = unserialize(str_replace ('PHP_SERIALIZED_OBJECT&:', '', $this->data)); 355 } 356 else 357 { 358 $retval['value'] = $this->data; 359 } 360 return $retval; 361 } 362 else 363 { 364 reset($this->data); 365 while(list($key,$val) = each($this->data)) 366 { 367 $retval['children'][] = $val->export_struct(); 368 } 369 return $retval; 370 } 371 } 372 373 374 function import_xml_children($data, &$i, $parent_node) 375 { 376 while (++$i < count($data)) 377 { 378 switch ($data[$i]['type']) 379 { 380 case 'cdata': 381 case 'complete': 382 $node = new xmltool('node',$data[$i]['tag'],$this->indentstring); 383 if(is_array($data[$i]['attributes']) && count($data[$i]['attributes']) > 0) 384 { 385 while(list($k,$v)=each($data[$i]['attributes'])) 386 { 387 $node->set_attribute($k,$v); 388 } 389 } 390 $node->set_value($data[$i]['value']); 391 $parent_node->add_node($node); 392 break; 393 case 'open': 394 $node = new xmltool('node',$data[$i]['tag'],$this->indentstring); 395 if(is_array($data[$i]['attributes']) && count($data[$i]['attributes']) > 0) 396 { 397 while(list($k,$v)=each($data[$i]['attributes'])) 398 { 399 $node->set_attribute($k,$v); 400 } 401 } 402 403 $node = $this->import_xml_children($data, $i, $node); 404 $parent_node->add_node($node); 405 break; 406 case 'close': 407 return $parent_node; 408 } 409 } 410 } 411 412 function import_xml($xmldata) 413 { 414 $parser = xml_parser_create(); 415 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 416 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 417 xml_parse_into_struct($parser, $xmldata, $vals, $index); 418 xml_parser_free($parser); 419 unset($index); 420 $node = new xmltool('node',$vals[0]['tag'],$this->indentstring); 421 if(isset($vals[0]['attributes'])) 422 { 423 while(list($key,$value) = each($vals[0]['attributes'])) 424 { 425 $node->set_attribute($key, $value); 426 } 427 } 428 switch ($vals[0]['type']) 429 { 430 case 'complete': 431 $node->set_value($vals[0]['value']); 432 break; 433 case 'cdata': 434 $node->set_value($vals[0]['value']); 435 break; 436 case 'open': 437 $node = $this->import_xml_children($vals, $i = 0, $node); 438 break; 439 case 'closed': 440 exit; 441 } 442 $this->add_node($node); 443 } 444 445 function export_xml($indent = 1) 446 { 447 if ($this->node_type == 'root') 448 { 449 $result = '<?xml version="'.$this->xmlversion.'"?>'."\n"; 450 if(count($this->doctype) == 1) 451 { 452 list($doctype_name,$doctype_uri) = each($this->doctype); 453 $result .= '<!DOCTYPE '.$doctype_name.' SYSTEM "'.$doctype_uri.'">'."\n"; 454 } 455 if(count($this->comments) > 0 ) 456 { 457 //reset($this->comments); 458 while(list($key,$val) = each ($this->comments)) 459 { 460 $result .= "<!-- $val -->\n"; 461 } 462 } 463 if(is_object($this->data)) 464 { 465 $indent = 0; 466 $result .= $this->data->export_xml($indent); 467 } 468 return $result; 469 } 470 else /* For node objects */ 471 { 472 for ($i = 0; $i < $indent; $i++) 473 { 474 $indentstring .= $this->indentstring; 475 } 476 477 $result = $indentstring.'<'.$this->name; 478 if(count($this->attributes) > 0 ) 479 { 480 reset($this->attributes); 481 while(list($key,$val) = each ($this->attributes)) 482 { 483 $result .= ' '.$key.'="'.htmlspecialchars($val).'"'; 484 } 485 } 486 487 $endtag_indent = $indentstring; 488 if (empty($this->data_type)) 489 { 490 $result .= '/>'."\n"; 491 } 492 else 493 { 494 $result .= '>'; 495 496 switch ($this->data_type) 497 { 498 case 'value': 499 if(is_array($this->data)) 500 { 501 $type_error = True; 502 break; 503 } 504 505 /*if(preg_match("(&|<)", $this->data)) // this is unnecessary with htmlspecialchars($this->data) 506 { 507 $result .= '<![CDATA['.$this->data.']]>'; 508 $endtag_indent = ''; 509 } 510 else*/if(strlen($this->data) > 30 && !empty($this->indentstring)) 511 { 512 $result .= "\n".$indentstring.$this->indentstring.htmlspecialchars($this->data)."\n"; 513 $endtag_indent = $indentstring; 514 } 515 else 516 { 517 $result .= htmlspecialchars($this->data); 518 $endtag_indent = ''; 519 } 520 break; 521 case 'node': 522 $result .= "\n"; 523 if(!is_array($this->data)) 524 { 525 $type_error = True; 526 break; 527 } 528 529 $subindent = $indent+1; 530 reset($this->data); 531 while(list($key,$val) = each ($this->data)) 532 { 533 if(is_object($val)) 534 { 535 $result .= $val->export_xml($subindent); 536 } 537 } 538 break; 539 default: 540 if($this->data != '') 541 { 542 echo 'Invalid or unset data type ('.$this->data_type.'). This should not be possible if using the class as intended<br>'; 543 } 544 } 545 546 if ($type_error) 547 { 548 echo 'Invalid data type. Tagged as '.$this->data_type.' but data is '.gettype($this->data).'<br>'; 549 } 550 551 $result .= $endtag_indent.'</'.$this->name.'>'; 552 if($indent != 0) 553 { 554 $result .= "\n"; 555 } 556 } 557 if(count($this->comments) > 0 ) 558 { 559 reset($this->comments); 560 while(list($key,$val) = each ($this->comments)) 561 { 562 $result .= $endtag_indent."<!-- $val -->\n"; 563 } 564 } 565 return $result; 566 } 567 } 568 } 569 570 class xmlnode extends xmltool 571 { 572 function xmlnode($name) 573 { 574 $this->xmltool('node',$name); 575 } 576 } 577 578 class xmldoc extends xmltool 579 { 580 function xmldoc($version = '1.0') 581 { 582 $this->xmltool('root'); 583 $this->set_version($version); 584 } 585 586 function add_root($root_node) 587 { 588 return $this->add_node($root_node); 589 } 590 } 591?> 592