Login   Register  
PHP Classes
elePHPant
Icontem

File: extendeddom.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Richard Keizer  >  True DOM abstraction  >  extendeddom.php  >  Download  
File: extendeddom.php
Role: Class source
Content type: text/plain
Description: Main class
Class: True DOM abstraction
Create XML documents using extensible DOM elements
Author: By
Last change: Made accessible without user login
Date: 2011-09-12 00:53
Size: 5,368 bytes
 

Contents

Class file image Download
<?php
  
/**------------------------------------------------------------------------------
   * File:         extendeddom.phplibrary
   * Description:  True DOMDocument and DOMElement abstraction
   * Version:      1.0
   * Author:       Richard Keizer
   * Email:        ra dot keizer at gmail dot com
   *------------------------------------------------------------------------------
   * COPYRIGHT (c) 2011 Richard Keizer
   *
   * The source code included in this package is free software; you can
   * redistribute it and/or modify it under the terms of the GNU General Public
   * License as published by the Free Software Foundation. This license can be
   * read at:
   *
   * http://www.opensource.org/licenses/gpl-license.php
   *
   * This program 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 General Public License for more details. 
   *------------------------------------------------------------------------------
   *
   *
   */

  
class extDOMDocument extends DOMDocument {
    
    public function 
__construct($version='1.0'$encoding=null) {
      
parent::__construct($version$encoding);
      
$this->formatOutput true;
    }
    
    public function 
createElement($classname$name=null$owner=null$value=null) {
      if (
is_null($owner)) $owner $this;
      
      return (!
is_null($name) && $this->getElementByName($name$owner)) ? $this->getElementByName($name$owner) : new $classname($owner$name$value);
    }
    
    public function 
createElementNS($namespaceURI$classnameDOMNode $owner$value=null) {
      if (
is_null($owner)) $owner $this;
      return 
$this->getElementByName($name$owner) ? $this->getElementByName($name$owner) : new $classname($owner$name$value$namespaceURI);      
    }
    
    public function 
getElementByName($name$node=null) {
      if (
is_null($node)) $node $this;
      foreach(
$node->childNodes as $child) if ($child->hasAttribute('name') && $child->getAttribute('name') == $name) return $child;
    }
    
    
    public function 
marshal() {
      return 
$this->saveXML();
    }
    
    public function 
unmarshal($xml) {
      return 
$this->loadXML($xml);
    }
    
    public function 
loadXML($xml) {
      
$tmpdom = new DOMDocument('1.0');
      
$tmpdom->preserveWhiteSpace false;
      
$tmpdom->loadXML($xml);
      
      
$stack = array($tmpdom$this);                 //push source (=tmpdom's root) and target (=insertionpoint)
      
while (!empty($stack)) {
        
        
$source array_shift($stack);
        
$target array_shift($stack);
        
        foreach(
$source->childNodes as $child) {
          
          switch (
$child->nodeType) {
            case 
XML_ELEMENT_NODE: {
              
              
$new $child->namespaceURI == '' $this->createElement($child->nodeName$child->getAttribute('name'), $target) : $this->createElementNS($uri$child->nodeName$child->getAttribute('name'), $target);
              
              foreach (
$child->attributes as $attr$new->setAttribute($attr->nodeName$attr->nodeValue);        //$new->appendChild($this->importNode($attr, true));
              
              
array_push($stack$child);
              
array_push($stack$new);
              break;
            }
              
            case 
XML_TEXT_NODE: {
              
$target->appendChild($this->createTextNode($child->nodeValue));   //$target->nodeValue = $child->nodeValue;
              
break;
            }
              
            case 
XML_PI_NODE: {
              
$target->appendChild($this->createProcessingInstruction($child->nodeName$child->nodeValue));
              break;
            }
              
            case 
XML_COMMENT_NODE: {
              
//$target->appendChild($this->createComment($child->nodeValue));
              
break;              
            }
              
            default: {
              throw new 
Exception("nodeType '{$child->nodeType}' not implemented!");
            }
          }
        }
      }
    }          
  }

  
  
  
//id is global unique
  //name is local unique


  
class extDOMElement extends DOMElement {
    private 
$this;
    
    public function 
__construct($owner$name=null$value=null$namespaceURI=null) {
      
parent::__construct(get_called_class(), $value$namespaceURI);
      
$owner->appendChild($this);                    //append to owner
      
$this->setAttribute('id'uniqid('u'));        //assign unique identifier
      
$this->setIdAttribute('id'true);
      if (
$name$this->setAttribute('name'$name);
      
$this->this $this;                          //IMPORTANT: if we don't store this extra reference the element would degrade to a DOMElement for some reason...
    
}
    
    public function 
createElement($classname$name=null$value=null) {
      return 
$this->ownerDocument->createElement($classname$name$this$value);
    }
    
    public function 
getId() {
      return 
$this->getAttribute('id');
    }
    
    public function 
getElementByName($name) {
      return 
$this->ownerDocument->getElementByName($name$this);
    }
  }