Location: PHPKode > scripts > myXML > myxml/myDOM/Node.php
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4                                                        |
// +----------------------------------------------------------------------+
// | Copyright (c) 2002-2003 Tereshchenko Andrey. All rights reserved.    |
// +----------------------------------------------------------------------+
// | This source file is free software; you can redistribute it and/or    |
// | modify it under the terms of the GNU Lesser General Public           |
// | License as published by the Free Software Foundation; either         |
// | version 2.1 of the License, or (at your option) any later version.   |
// |                                                                      |
// | This source file is distributed in the hope that it will be useful,  |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
// | Lesser General Public License for more details.                      |
// +----------------------------------------------------------------------+
// | Authors:                                                             |
// |     Tereshchenko Andrey <hide@address.com>                  |
// +----------------------------------------------------------------------+
//
// $Id: Node.php,v 0.3 2004/02/06 10:50:20 anter Exp $

/**
* @package      myXML
* @subpackage   myDOM
*/
/**
* Error handling.
*/
require_once('Error.php');

/**
* NodeList class.
*/
require_once('NodeList.php');

/**
* NamedNodeMap class.
*/
require_once('NamedNodeMap.php');

/**
* Node class.
* 
* See DOM for details.
* 
* @author       Tereshchenko Andrey <hide@address.com>
* @copyright    Tereshchenko Andrey 2002-2003
* @version      0.3 2004/02/06
* @access       public
* @package      myXML
* @subpackage   myDOM
* @link         http://phpmyxml.sourceforge.net/
*/
class Node extends PEAR
{
    /**
    * The name of this node, depending on its type.
    * 
    * @var      string
    * @access   public
    */
    var $nodeName;
    
    /**
    * The value of this node, depending on its type.
    * 
    * @var      string
    * @access   public
    */
    var $nodeValue = null;
    
    /**
    * A code representing the type of the underlying object, as defined above.
    * 
    * @var      integer
    * @access   public
    */
    var $nodeType;
    
    /**
    * The parent of this node.
    * 
    * @var      object Element
    * @access   public
    */
    var $parentNode = null;
    
    /**
    * A NodeList that contains all children of this node.
    * 
    * @var      object NodeList
    * @access   public
    */
    var $childNodes = null;
    
    /**
    * The first child of this node.
    * 
    * @var      object Element
    * @access   public
    */
    var $firstChild = null;
    
    /**
    * The last child of this node.
    * 
    * @var      object Element
    * @access   public
    */
    var $lastChild = null;
    
    /**
    * The node immediately preceding this node.
    * 
    * @var      object Element
    * @access   public
    */
    var $previousSibling = null;
    
    /**
    * The node immediately following this node.
    * 
    * @var      object Element
    * @access   public
    */
    var $nextSibling = null;
    
    /**
    * A NamedNodeMap containing the attributes of this node.
    * 
    * @var      object NamedNodeMap
    * @access   public
    */
    var $attributes = null;
    
    /**
    * The Document object associated with this node.
    * 
    * @var      object Document
    * @access   public
    */
    var $ownerDocument;
    
    // Introduced in DOM Level 2:
    /**
    * The namespace URI of this node, or null if it is unspecified.
    * 
    * @var      string
    * @access   public
    */
    var $namespaceURI = null;
    
    /**
    * The namespace prefix of this node, or null if it is unspecified.
    * 
    * @var      string
    * @access   public
    */
    var $prefix = null;
    
    /**
    * Returns the local part of the qualified name of this node.
    * 
    * @var      string
    * @access   public
    */
    var $localName = null;
    
    // Introduced in this DOM Implementation:
    /**
    * Node ID
    * 
    * @var      integer
    * @access   private
    */
    var $_ID = null;
    
    /**
     * Constructor.
     * 
     * @param   string
     * @param   object Document
     * @return  object Node
     * @access  private
     */
    function Node($nodeName, &$ownerDocument)
    {
        $this->PEAR('DOM_Error');
        if (!$this->_checkName($nodeName)) {
            return $this->raiseError(INVALID_CHARACTER_ERR);
        }
        $this->nodeName = $nodeName;
        $this->_ID = mt_rand(1, 9999999999);
        $this->ownerDocument =& $ownerDocument;
        $this->childNodes =& new NodeList;
        $this->NodeList =& $this->childNodes;
    }
    
    /**
     * Inserts the node newChild before the existing child node refChild.
     * 
     * @param   object Element
     * @param   object Element
     * @access  public
     */
    function &insertBefore(&$newChild, &$refChild)
    {
        return $this->raiseError(HIERARCHY_REQUEST_ERR);
    }
    
    /**
     * Replaces the child node oldChild with newChild in the list of children,
     * and returns the oldChild node.
     * 
     * @param   object Element  $newChild
     * @param   object Element  $oldChild
     * @access  public
     */
    function replaceChild(&$newChild, &$oldChild)
    {
        return $this->raiseError(HIERARCHY_REQUEST_ERR);
    }
    
    /**
     * Removes the child node indicated by oldChild from the list of children,
     * and returns it.
     * 
     * @param   object Element
     * @access  public
     */
    function &removeChild(&$oldChild)
    {
        return $this->raiseError(HIERARCHY_REQUEST_ERR);
    }
    
    /**
     * Adds the node newChild to the end of the list of children of this node.
     * 
     * @param   object Node
     * @return  object Node
     * @access  public
     */
    function &appendChild(&$newChild)
    {
        return $this->raiseError(HIERARCHY_REQUEST_ERR);
    }
    
    /**
     * Returns whether this node has any children. 
     * 
     * @return  boolean
     * @access  public
     */
    function hasChildNodes()
    {
        return (bool) $this->childNodes->length;
    }
    
    /**
     * Returns a duplicate of this node.
     * 
     * @param   boolean
     */
    function &cloneNode($deep = false)
    {
      //Abstract method
    }
    
    // Introduced in DOM Level 2:
    /**
     * Tests whether the DOM implementation implements a specific feature and
     * that feature is supported by this node. 
     * 
     * Not implemented in this version.
     * 
     * @param   string
     * @param   string
     * @access  public
     */
    function isSupported($feature, $version)
    {
        return $this->raiseError('the function "isSupported" is not implemented in this version');
    }
    
    /**
     * Returns whether this node (if it is an element) has any attributes.
     * 
     * @return  boolean
     * @access  public
     */
    function hasAttributes()
    {
        return (bool) $this->attributes;
    }
    
    // Introduced in this DOM Implementation:
    
    /**
     * Node::isInherited()
     * 
     * @param   object  inherited from Node
     * @return  boolean
     * @access  public
     * @static  method
     */
    function isInherited(&$node)
    {
        return (is_object($node) && is_a($node, 'Node'));
    }
    
    /**
     * Node::toString()
     * 
     * @return  string
     * @access  private
     */
    function toString()
    {
        // abstract
    }
    
    /**
     * Node::_insertBefore()
     * 
     * @access  private
     */
    function &_insertBefore(&$newChild, &$refChild)
    {
        if (!Node::isInherited($newChild)) {
            return $this->raiseError('the first argument must be inherit of object Node');
        }
        if ($this->ownerDocument->_ID != $newChild->ownerDocument->_ID) {
            return $this->raiseError(WRONG_DOCUMENT_ERR);
        }
        if ($newChild->nodeType < 1 || $newChild->nodeType > 12) {
            return $this->raiseError(NOT_SUPPORTED_ERR);
        }
        if (false === ($index = $this->childNodes->isExists(&$refChild))) {
            return $this->raiseError(NOT_FOUND_ERR);
        }
        if ($newChild->parentNode !== null) {
            $newChild->parentNode->removeChild(&$newChild);
        }
        $newChild->parentNode =& $this;
        $newChild->previousSibling =& $refChild->previousSibling;
        $newChild->nextSibling =& $refChild;
        $refChild->previousSibling->nextSibling =& $newChild;
        $refChild->previousSibling =& $newChild;
        if ($this->firstChild->_ID = $refChild->_ID) {
            $this->firstChild =& $newChild;
        }
        $this->childNodes->addItem(&$newChild, $index);
        return $newChild;
        
    }
    
    /**
     * Node::_replaceChild()
     * 
     * @access  private
     */
    function _replaceChild($newChild, $oldChild)
    {
        if (!Node::isInherited($newChild)) {
            return $this->raiseError('the first argument must be inherit of object Node');
        }
        if ($this->ownerDocument->_ID != $newChild->ownerDocument->_ID) {
            return $this->raiseError(WRONG_DOCUMENT_ERR);
        }
        if ($newChild->nodeType < 1 || $newChild->nodeType > 12) {
            return $this->raiseError(NOT_SUPPORTED_ERR);
        }
        if (false === ($index = $this->childNodes->isExists(&$oldChild))) {
            return $this->raiseError(NOT_FOUND_ERR);
        }
        if ($newChild->parentNode !== null) {
            $newChild->parentNode->removeChild(&$newChild);
        }
        $newChild->parentNode =& $this;
        $newChild->previousSibling =& $oldChild->previousSibling;
        $newChild->nextSibling =& $oldChild->nextSibling;
        if ($this->firstChild->_ID = $oldChild->_ID) {
            $this->firstChild =& $newChild;
        }
        if ($this->lastChild->_ID = $oldChild->_ID) {
            $this->lastChild =& $newChild;
        }
        $this->childNodes->addItem(&$newChild, $index, $replace = 1);
        return $oldChild;
    }
    
    /**
     * Node::_removeChild()
     * 
     * @access  private
     */
    function &_removeChild(&$oldChild)
    {
        if (!Node::isInherited($oldChild)) {
            return $this->raiseError('the first argument must be inherited from Node');
        }
        if (false === ($index = $this->childNodes->isExists(&$oldChild))) {
            return $this->raiseError(NOT_FOUND_ERR);
        }
        if ($nextSibling =& $oldChild->nextSibling) {
            if ($previousSibling =& $oldChild->previousSibling) {
                $nextSibling->previousSibling =& $previousSibling;
            } else {
                unset($nextSibling->previousSibling);
            }
        }
        if ($previousSibling =& $oldChild->previousSibling) {
            if ($nextSibling =& $oldChild->nextSibling) {
                $previousSibling->nextSibling =& $nextSibling;
            } else {
                unset($previousSibling->nextSibling);
            }
        }
        if ($this->firstChild->_ID == $oldChild->_ID) {
            if ($oldChild->nextSibling) {
                $this->firstChild =& $oldChild->nextSibling;
            } else {
                unset($this->firstChild);
            }
        }
        if ($this->lastChild->_ID == $oldChild->_ID) {
            if ($oldChild->previousSibling) {
                $this->lastChild =& $previousSibling;
            } else {
                unset($this->lastChild);
            }
        }
        unset($oldChild->parentNode);
        unset($oldChild->previousSibling);
        unset($oldChild->nextSibling);
        return $this->childNodes->removeItem($index);
    }
    
    /**
     * Node::_appendChild()
     * 
     * @access  private
     */
    function &_appendChild(&$newChild)
    {
        if (!Node::isInherited($newChild)) {
            return $this->raiseError('the first argument must be inherited from Node');
        }
        if ($this->ownerDocument->_ID != $newChild->ownerDocument->_ID) {
            return $this->raiseError(WRONG_DOCUMENT_ERR);
        }
        if ($newChild->nodeType < 1 || $newChild->nodeType > 12) {
            return $this->raiseError(NOT_SUPPORTED_ERR);
        }
        if ($newChild->parentNode !== null) {
            $newChild->parentNode->removeChild(&$newChild);
        }
        if (!$this->firstChild) {
            $this->firstChild =& $newChild;
        }
        $newChild->parentNode =& $this;
        $newChild->previousSibling =& $this->lastChild;
        $newChild->nextSibling = null;
        if ($this->lastChild) {
            $this->lastChild->nextSibling =& $newChild;
        }
        $this->lastChild =& $newChild;
        $this->childNodes->addItem(&$newChild);
        return $newChild;
    }
    
    /**
     * Checks name of node.
     * 
     * @param   string
     * @return  bool
     * @access  private
     */
    function _checkName($nodeName)
    {
        $pattern = '/^(([^\d\W]|_|#)([^\d\W]|\d|\.|-|_)*:)?([^\d\W]|_|#)([^\d\W]|\d|\.|-|_)*$/';
        return preg_match($pattern, $nodeName);
    }
}

/**
* DOM_Error class.
* 
* @access   private
*/
class DOM_Error extends Error
{
    var $error_message_prefix = 'myDOM error: ';
    var $skipClass = 'node';
    
    function DOM_Error($message = 'unknown error', $code = null,
                       $mode = null, $options = null, $userinfo = null)
    {
        global $DOM_Error;
        if (is_integer($message)) {
            $message = $DOM_Error[$message];
        }
        $this->Error($message, $code, $mode, $options, $userinfo);
    }
}

?>
Return current item: myXML