[ Index ]
 

Code source de LifeType 1.2.4

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/class/xml/tree/ -> Node.php (source)

   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('&#252;', '&#220;', '&#246;',
 546                                   '&#214;', '&#228;', '&#196;',
 547                                    '&#223;', '&lt;', '&gt;',
 548                                    '&quot;', '&apos;'
 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                                    "&amp;",
 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  ?>


Généré le : Mon Nov 26 21:04:15 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics