PHP Classes

File: extendeddom.php

Recommend this page to a friend!
  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: 12 years ago
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, $classname, DOMNode $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);
    }
  }