[ Index ] |
|
Code source de LifeType 1.2.4 |
1 <?php 2 // +----------------------------------------------------------------------+ 3 // | PEAR :: XML_Tree | 4 // +----------------------------------------------------------------------+ 5 // | Copyright (c) 1997-2003 The PHP Group | 6 // +----------------------------------------------------------------------+ 7 // | This source file is subject to version 2.02 of the PHP license, | 8 // | that is bundled with this package in the file LICENSE, and is | 9 // | available at through the world-wide-web at | 10 // | http://www.php.net/license/2_02.txt. | 11 // | If you did not receive a copy of the PHP license and are unable to | 12 // | obtain it through the world-wide-web, please send a note to | 13 // | license@php.net so we can mail you a copy immediately. | 14 // +----------------------------------------------------------------------+ 15 // | Authors: Bernd Römer <berndr@bonn.edu> | 16 // | Sebastian Bergmann <sb@sebastian-bergmann.de> | 17 // | Christian Kühn <ck@chkuehn.de> (escape xml entities) | 18 // | Michele Manzato <michele.manzato@verona.miz.it> | 19 // +----------------------------------------------------------------------+ 20 // 21 // $Id: Node.php,v 1.22 2004/05/26 15:03:25 davey Exp $ 22 // 23 24 /** 25 * \ingroup XML 26 * 27 * PEAR::XML_Tree_Node 28 * 29 * @author Bernd Römer <berndr@bonn.edu> 30 * @package XML_Tree 31 * @version 1.0 16-Aug-2001 32 */ 33 class XML_Tree_Node { 34 /** 35 * Attributes of this node 36 * 37 * @var array 38 */ 39 40 var $attributes; 41 42 /** 43 * Children of this node 44 * 45 * @var array 46 */ 47 48 var $children; 49 50 /** 51 * Content (text) of this node 52 * 53 * @var string 54 */ 55 56 var $content; 57 58 /** 59 * Name of the node 60 * 61 * @var string 62 */ 63 64 var $name; 65 66 /** 67 * Namespaces for the node 68 * 69 * @var array 70 */ 71 72 73 var $namespaces = array(); 74 75 /** 76 * Stores PEAR_Error upon error 77 * 78 * @var object PEAR_Error 79 */ 80 81 var $error = null; 82 83 /** 84 * Whether to encapsulate the CDATA in a <![CDATA[]]> section 85 * 86 * @var boolean 87 */ 88 89 var $use_cdata_section = null; 90 91 92 /** 93 * Constructor 94 * 95 * @param string name Node name 96 * @param string content Node content (text) 97 * @param array attributes Attribute-hash for the node 98 */ 99 100 function XML_Tree_Node($name, $content = '', $attributes = array(), $lineno = null, $use_cdata_section = null) 101 { 102 $check_name = XML_Tree::isValidName($name, 'element'); 103 if (!$check_name) { 104 $this->error =& $check_name; 105 return; 106 } 107 108 if (!is_array($attributes)) { 109 $attributes = array(); 110 } 111 112 foreach ($attributes as $attribute_name => $value) { 113 $error = XML_Tree::isValidName($attribute_name, 'Attribute'); 114 if (!$error) { 115 $this->error =& $error; 116 return; 117 } 118 } 119 $this->name = $name; 120 $this->setContent($content, $use_cdata_section); 121 $this->attributes = $attributes; 122 $this->children = array(); 123 $this->lineno = $lineno; 124 } 125 126 /** 127 * Append a child node to this node, after all other nodes 128 * 129 * @param mixed child Child to insert (XML_Tree or XML_Tree_Node), 130 * or name of child node 131 * @param string content Content (text) for the new node (only if 132 * $child is the node name) 133 * @param array attributes Attribute-hash for new node 134 * 135 * @return object reference to new child node 136 * @access public 137 */ 138 139 function &addChild($child, $content = '', $attributes = array(), $lineno = null, $use_cdata_section = null) 140 { 141 $index = sizeof($this->children); 142 143 if (is_object($child)) { 144 if (strtolower(get_class($child)) == 'xml_tree_node' || is_subclass_of($child,"xml_tree_node")) { 145 $this->children[$index] = $child; 146 } 147 148 if (strtolower(get_class($child)) == 'xml_tree' && isset($child->root)) { 149 $this->children[$index] = $child->root->getElement(); 150 } 151 } else { 152 $node = new XML_Tree_Node($child, $content, $attributes, $lineno, $use_cdata_section); 153 /*if (PEAR::isError($node->error)) { 154 return $node->error; 155 }*/ 156 157 $this->children[$index] = $node; 158 } 159 160 return $this->children[$index]; 161 } 162 163 /** 164 * Get a copy of this node by clone this node and all of its children, 165 * recursively. 166 * 167 * @return object Reference to the cloned copy. 168 * @access public 169 */ 170 171 function &cloneNode() 172 { 173 $clone = new XML_Tree_Node($this->name,$this->content,$this->attributes); 174 175 $max_child=count($this->children); 176 for($i=0;$i<$max_child;$i++) { 177 $clone->children[]=$this->children[$i]->cloneNode(); 178 } 179 180 /* for future use.... 181 // clone all other vars 182 $temp=get_object_vars($this); 183 foreach($temp as $varname => $value) 184 if (!in_array($varname,array('name','content','attributes','children'))) 185 $clone->$varname=$value; 186 */ 187 188 return $clone; 189 } 190 191 /** 192 * Inserts child ($child) to a specified child-position ($pos) 193 * 194 * @param mixed path Path to parent node to add child (see getNodeAt() 195 * for format). If null child is inserted in the 196 * current node. 197 * @param integer pos Position where to insert the new child. 198 * 0 < means |$pos| elements before the end, 199 * e.g. -1 appends as last child. 200 * @param mixed child Child to insert (XML_Tree or XML_Tree_Node), 201 * or name of child node 202 * @param string content Content (text) for the new node (only if 203 * $child is the node name) 204 * @param array attributes Attribute-hash for new node 205 * 206 * @return Reference to the newly inserted node, or PEAR_Error upon insertion error. 207 * @access public 208 */ 209 210 function &insertChild($path,$pos,&$child, $content = '', $attributes = array()) 211 { 212 $parent =& $this->getNodeAt($path); 213 if (!$parent) { 214 // $path was not found 215 return $parent; 216 } elseif ($parent != $this) { 217 // Insert at the node found 218 return $parent->insertChild(null, $pos, $child, $content, $attributes); 219 } 220 221 // if we don't care where, let's do it in the end 222 if( $pos == -1 ) 223 $pos = count($this->children); 224 225 if (($pos < -count($this->children)) || ($pos > count($this->children))) { 226 //_debug("Invalid insert position."); 227 return false; 228 } 229 230 if (is_object($child)) { // child is an object 231 // insert a single node 232 // 233 // OSCAR 20041012 234 // added "is_subclass_of()" to the condition so that we can subclass the XML_Tree_Class and still 235 // use its methods! 236 // 237 if (strtolower(get_class($child)) == 'xml_tree_node' || is_subclass_of($child,"xml_tree_node")) { 238 array_splice($this->children, $pos, 0, 'dummy'); 239 if ($pos < 0) { 240 $pos = count($this->children) + $pos - 1; 241 } 242 $this->children[$pos] = &$child; 243 // insert a tree i.e insert root-element of tree 244 } elseif (strtolower(get_class($child)) == 'xml_tree' && isset($child->root)) { 245 array_splice($this->children, $pos, 0, 'dummy'); 246 if ($pos < 0) { 247 $pos = count($this->children) + $pos - 1; 248 } 249 $this->children[$pos] = $child->root; 250 } else { 251 //_debug("Bad node (must be a XML_Tree or an XML_Tree_Node)"); 252 return false; 253 } 254 } else { // child offered is a string 255 array_splice($this->children, $pos, 0, 'dummy'); 256 if ($pos < 0) { 257 $pos = count($this->children) + $pos - 1; 258 } 259 $this->children[$pos] = new XML_Tree_Node($child, $content, $attributes); 260 } 261 return $this; 262 } 263 264 /** 265 * Removes child at a given position 266 * 267 * @param integer pos position of child to remove in children-list. 268 * 0 < means |$pos| elements before the end, 269 * e.g. -1 removes the last child. 270 * 271 * @return mixed The removed node, or PEAR_Error upon removal error. 272 * @access public 273 */ 274 275 function &removeChild($pos) 276 { 277 if (($pos < -count($this->children)) || ($pos >= count($this->children))) { 278 //return new PEAR_Error("Invalid remove position."); 279 return false; 280 } 281 282 // Using array_splice() instead of a simple unset() to maintain index-integrity 283 return array_splice($this->children, $pos, 1); 284 } 285 286 /** 287 * Register a namespace. 288 * 289 * @param string $name namespace 290 * @param string $path path 291 * 292 * @access public 293 */ 294 295 function registerName($name, $path) { 296 $this->namespace[$name] = $path; 297 } 298 299 /** 300 * Returns text representation of this node. 301 * 302 * @return string text (xml) representation of this node. Each tag is 303 * indented according to its level. 304 * @access public 305 */ 306 307 function &get($use_cdata_section = false) 308 { 309 static $deep = -1; 310 static $do_ident = true; 311 $deep++; 312 $empty = false; 313 $ident = str_repeat(' ', $deep); 314 if ($this->name !== null) { 315 if ($do_ident) { 316 $out = $ident . '<' . $this->name; 317 } else { 318 $out = '<' . $this->name; 319 } 320 foreach ($this->attributes as $name => $value) { 321 $out .= ' ' . $name . '="' . $value . '"'; 322 } 323 324 if (isset($this->namespace) && (is_array($this->namespace))) { 325 foreach ($this->namespace as $qualifier => $uri) { 326 if ($qualifier == '') { 327 $out .= " xmlns='$uri'"; 328 } else { 329 $out .= " xmlns:$qualifier='$uri'"; 330 } 331 } 332 } 333 334 if ($this->content == '' && sizeof($this->children) === 0 && $deep != 0) { 335 $out .= ' />'; 336 $empty = true; 337 } else { 338 $out .= '>'; 339 if ($this->use_cdata_section == true || ($use_cdata_section == true && $this->use_cdata_section !== false)) { 340 if (trim($this->content) != '') { 341 $out .= '<![CDATA[' .$this->content. ']]>'; 342 } 343 } else { 344 if (trim($this->content) != '') { 345 $out .= $this->content; 346 } 347 } 348 } 349 350 if (sizeof($this->children) > 0) { 351 $out .= "\n"; 352 foreach ($this->children as $child) { 353 $out .= $child->get($use_cdata_section); 354 } 355 } else { 356 $ident = ''; 357 } 358 359 if ($do_ident && $empty != true) { 360 $out .= $ident . '</' . $this->name . ">\n"; 361 } elseif ($empty != true) { 362 $out .= '</' . $this->name . '>'; 363 } 364 $do_ident = true; 365 } else { 366 if ($this->use_cdata_section == true || ($use_cdata_section == true && $this->use_cdata_section !== false)) { 367 if (trim($this->content) != '') { 368 $out = $ident . '<![CDATA[' .$this->content. ']]>' . "\n"; 369 } 370 } else { 371 if (trim($this->content) != '') { 372 $out = $ident . $this->content . "\n"; 373 } 374 } 375 } 376 $deep--; 377 return $out; 378 } 379 380 /** 381 * Get an attribute by its name. 382 * 383 * @param string $name Name of attribute to retrieve 384 * 385 * @return string attribute, or null if attribute is unset. 386 * @access public 387 */ 388 389 function getAttribute($name) 390 { 391 if (isset($this->attributes[$name])) { 392 return $this->attributes[$name]; 393 } 394 return null; 395 } 396 397 /** 398 * Sets an attribute for this node. 399 * 400 * @param string name Name of attribute to set 401 * @param string value Value of attribute 402 * 403 * @access public 404 */ 405 406 function setAttribute($name, $value = '') 407 { 408 $this->attributes[$name] = $value; 409 } 410 411 /** 412 * Unsets an attribute of this node. 413 * 414 * @param string $name Name of attribute to unset 415 * 416 * @access public 417 */ 418 419 function unsetAttribute($name) 420 { 421 if (isset($this->attributes[$name])) { 422 unset($this->attributes[$name]); 423 } 424 } 425 426 /** 427 * Sets the content for this node. 428 * 429 * @param string content Node content to assign 430 * 431 * @access public 432 */ 433 434 function setContent($content, $use_cdata_section = null) 435 { 436 $this->use_cdata_section = $use_cdata_section; 437 438 if ($use_cdata_section == true) { 439 $this->content = $content; 440 } else { 441 $this->content = $this->encodeXmlEntities($content); 442 } 443 } 444 445 /** 446 * Gets an element by its 'path'. 447 * 448 * @param array path path to element: sequence of indexes to the 449 * children. E.g. array(1, 2, 3) means "third 450 * child of second child of first child" of the node. 451 * 452 * @return object reference to element found, or PEAR_Error if node can't 453 * be found. 454 * @access public 455 */ 456 457 function &getElement($path) 458 { 459 if (!is_array($path)) { 460 $path = array($path); 461 } 462 if (sizeof($path) == 0) { 463 return $this; 464 } 465 466 $path1 = $path; 467 $next = array_shift($path1); 468 if (isset($this->children[$next])) { 469 $x =& $this->children[$next]->getElement($path1); 470 if (!$x) { 471 return $x; 472 } 473 } 474 475 //return new PEAR_Error("Bad path to node: [".implode('-', $path)."]"); 476 return false; 477 } 478 479 /** 480 * Get a reference to a node by its 'path'. 481 * 482 * @param mixed path Path to node. Can be either a string (slash-separated 483 * children names) or an array (sequence of children names) both 484 * starting from this node. The first name in sequence 485 * is a child name, not the name of this node. 486 * 487 * @return object Reference to the XML_Tree_Node found, or PEAR_Error if 488 * the path does not match any node. Note that if more than 489 * one element matches then only the first matching node is 490 * returned. 491 * @access public 492 */ 493 494 function &getNodeAt($path) 495 { 496 if (is_string($path)) 497 $path = explode("/", $path); 498 499 if (sizeof($path) == 0) { 500 return $this; 501 } 502 503 $path1 = $path; 504 $next = array_shift($path1); 505 506 // Get the first children of this node whose name is '$next' 507 $child = null; 508 for ($i = 0; $i < count($this->children); $i++) { 509 if ($this->children[$i]->name == $next) { 510 $child =& $this->children[$i]; 511 break; 512 } 513 } 514 if (!is_null($child)) { 515 $x =& $child->getNodeAt($path1); 516 if ($x) { 517 return $x; 518 } 519 } 520 521 // No node with that name found 522 //_debug("Bad path to node: [".implode('/', $path)."]"); 523 524 // the line below is here to avoid a warning message... 525 $x = false; 526 return $x; 527 } 528 529 /** 530 * Escape XML entities. 531 * 532 * @param string xml Text string to escape. 533 * 534 * @return string xml 535 * @access public 536 */ 537 538 function encodeXmlEntities($xml) 539 { 540 $xml = str_replace(array('ü', 'Ü', 'ö', 541 'Ö', 'ä', 'Ä', 542 'ß', '<', '>', 543 '"', '\'' 544 ), 545 array('ü', 'Ü', 'ö', 546 'Ö', 'ä', 'Ä', 547 'ß', '<', '>', 548 '"', ''' 549 ), 550 $xml 551 ); 552 553 $xml = preg_replace(array("/\&([a-z\d\#]+)\;/i", 554 "/\&/", 555 "/\#\|\|([a-z\d\#]+)\|\|\#/i", 556 "/([^a-zA-Z\d\s\<\>\&\;\.\:\=\"\-\/\%\?\!\'\(\)\[\]\{\}\$\#\+\,\@_])/e" 557 ), 558 array("#||\\1||#", 559 "&", 560 "&\\1;", 561 "'&#'.ord('\\1').';'" 562 ), 563 $xml 564 ); 565 566 return $xml; 567 } 568 569 /** 570 * Decode XML entities in a text string. 571 * 572 * @param string xml Text to decode 573 * 574 * @return string Decoded text 575 * @access public 576 */ 577 578 function decodeXmlEntities($xml) 579 { 580 static $trans_tbl = null; 581 if (!$trans_tbl) { 582 $trans_tbl = get_html_translation_table(HTML_ENTITIES); 583 $trans_tbl = array_flip($trans_tbl); 584 } 585 for ($i = 1; $i <= 255; $i++) { 586 $ent = sprintf("&#%03d;", $i); 587 $ch = chr($i); 588 $xml = str_replace($ent, $ch, $xml); 589 } 590 591 return strtr($xml, $trans_tbl); 592 } 593 594 595 /** 596 * Print text representation of XML_Tree_Node. 597 * 598 * @access public 599 */ 600 601 function dump() { 602 echo $this->get(); 603 } 604 } 605 ?>
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 |
![]() |