Login   Register  
PHP Classes
elePHPant
Icontem

File: XMLElement

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of mathieu lachance  >  XMLElement  >  XMLElement  >  Download  
File: XMLElement
Role: Class source
Content type: text/plain
Description: The XMLElement class file
Class: XMLElement
Compose and generate XML documents
Author: By
Last change: revised these methods :
addChild, export, import.
Date: 7 years ago
Size: 9,056 bytes
 

Contents

Class file image Download
<?php
/**
 * XMLElement class file
 * @author Mathieu Lachance <lachance.mathieu@poincomm.com>
 * @link http://www.mathieulachance.com/
 * @copyright Copyright (c) 2007 Mathieu Lachance
 * @license http://creativecommons.org/licenses/by/2.5/ca/
 * @version 2.0 2007-03-10 15h45
 */

/**
 * Class XMLElement
 * The XMLElement class is used to generate an xml tree architecture.
 * This xml tree architecture is similar to the SimpleXMLElement class embeded by default within PHP5.
 * Each XMLElement contains :
 * - all the properties inherited from the Node class, $name, $parent, $children, $count
 * - an entity, the $entity protected property
 * - a mapped array containing all the attributes of the xml element, the $attributes protected property
 * - a possible prefix of the xml element entity, the $prefix protected property
 * - the possible text content of the xml element, the $text protected property
 *   note : only empty xml element (without child elements) can define this property
 * 
 * For more information please refer to the Node class documentation.
 */
class XMLElement extends Node
{
  const 
XML_DECLARATION "<?xml version=\"1.0\"?>\n";
  
  
/**
   * @var string $entity the entity of the xml element
   */
  
protected $entity null;
  
/**
   * @var array $attributes a mapped array containing all the attributes of the xml element
   */
  
protected $attributes null;
  
/**
   * @var string $prefix the possible prefix of the xml element entity
   */
  
protected $prefix null;
  
/**
   * @var string $text the possible text content of the xml element
   */
  
protected $text null;
  
  
/**
   * Constructor
   * @param string $entity the xml element entity
   * @param array $attributes a possible mapped array containing all the xml element attributes
   * @param string $prefix a possible prefix for the xml element entity
   * @todo : add a param for the possible text content ?
   */
  
public function __construct($entity null$attributes null$prefix null){
    
parent::__construct((string)$entity);
    
$this->prefix = (string)$prefix;
    
$this->attributes = (array)$attributes;
  }
  
  
/**
   * Assign to the mapped array $attributes the value $value at the index $name
   * @param string $name the name of the attribute
   * @param string $value the value of the attribute
   */
  
public function addAttribute($name$value){
    
$this->attributes[(string)$name] = (string)$value;
  }
  
/**
   * Assign all the attributes contained in the $map parameter
   * @param array $map an array containing all the attributes to assign to the xml element
   */
  
public function addAttributes($map){
    if (!(
is_array($map))) { throw new Exception("must pass a mapped array"); }
    foreach (
$map as $name => $value){
      
$this->addAttribute($name$value);
    }
  }
  
  
/**
   * Overload the node addChild method to ensure that no child can be assigned
   * if the $text property is not null
   * @param string $entity the xml element entity
   * @param array $attributes a possible mapped array containing all the xml element attributes
   * @param string $prefix a possible prefix for the xml element entity
   * @throws Exception if the $text property is not null
   */
  
public function addChild($entity$attributes null$prefix null){
    if (
$this->text != null){ throw new Exception("Can only add element to non text element"); }
    return 
parent::addChild(new XMLElement($entity$attributes$prefix));
  }
  
  
/**
   * @return string $prefix the possible prefix of the xml element entity
   */
  
public function getPrefix(){
    return 
$this->prefix;
  }
  
  
/**
   * @return string / null the $text property
   */
  
public function getText(){
    return 
$this->text;
  }
  
  
/**
   * @param string $text the string to be assign to the $text property
   * @throws Exception if the xml element is not empty
   */
  
public function setText($text){
    if (!(
$this->isEmpty())){ throw new Exception("Can only add text element to empty node"); }
    
$this->text = (string)$text;
  }
  
  
/**
   * Overload the node export method to integrate :
   * - the possible prefix of the entity
   * - the attributes of the xml element
   * @param int $level the xml element indentation
   * @return string $x the xml output
   */
  
public function export($level null){
    
$level = (int)$level;
    
$ws str_repeat("  "$level);               // calculate the whitespace indentation
    
((string)$this->prefix != "") ? $pr "$this->prefix:" $pr ""// generate the prefix string
    
$at "";                                     // generate the attributes string
    
foreach ($this->attributes as $n => $v){
      
$at .= $n=\"$v\"";
    }
    if (
$this->isEmpty()){                        // if the current node is empty
      
if ($this->text == null){                   // return a closing tag of the current node name as the xml output
        
return "$ws<$pr$this->name$at/>\n";
      }
      return 
"$ws<$pr$this->name$at>$this->text</$pr$this->name>\n";
    }
    
$x "$ws<$pr$this->name$at>\n";              // open an tag of the current node name
    
foreach($this->children as $child){           // for each child of the current node
      
$x .= $child->export($level+1);             // export the child node
    
}
    
$x .= "$ws</$pr$this->name>\n";               // close the opened tag of the current node name
    
return $x;                                    // return the xml output of the current node
  
}
  
  public function 
__toString(){
    return 
self::XML_DECLARATION $this->export();
  }
  
  
/**
   * Overload the import method to integrate :
   * - the possible prefix of the entity
   * - the attributes of the xml element
   * @param DomNode $d the xml fragment of the last import method iteration
   * @param XMLElement $p the parent node reference of the last import method iteration
   */
  
public function import(DomNode $dXMLElement $p null){
    
$this->name $d->nodeName;                   // assign the node name with the root element of the DomNode
    
$this->parent $p;                           // assign the parent node
    
$this->entity $this->name;                  // assign the node entity as same as node name
    
$this->prefix $d->prefix;                   // assign the node prefix
    
if ($d->hasAttributes()){                     // if the node contains any attributes
      
foreach($d->attributes as $a){              // for each attributes
        
$this->addAttribute($a->name$a->value); // append attribute
      
}
    }
    if (
$d->hasChildNodes()){                     // if the xml node is not empty
      
foreach($d->childNodes as $child){          // for each children
        
switch($child->nodeType){                 // switch the node type
        
case XML_ELEMENT_NODE :                   // if it is an XML ELEMENT NODE
          
$n = new XMLElement();                  // create the new XMLElement
          
$n->import($child$this);              // import all nodes contained in the child node
          
break;
        case 
XML_TEXT_NODE :                      // if it is a XML TEXT NODE
          
if (trim($child->textContent)){         // if the content is not empty
            
$this->text trim($child->textContent); // trim whitespaces and assign the content
          
}
          break;
        case 
XML_CDATA_SECTION_NODE :             // if the child is an XML CDATA SECTION NODE
          
if (trim($child->textContent)){         // if the content is not empty
            
$this->text "<![CDATA[" trim($child->textContent) . "]]>"// trim whitespaces and assign the content
          
}
          break;
        }
      }
    }
  }
  
}

// exemple :
$n = new XMLElement("people");
$n->addAttribute("xmlns:p""http://example.org/ns");
$n->addAttribute("xmlns:t""http://example.org/test");
$n->addChild("person", array("t:id"=>"1"), "p");
$n->person->setText("John Doe");
$n->addChild("person", array("t:id"=>"2","a:addr"=>"123 Street" ,"xmlns:a"=>"http://example.org/addr"), "p");
$n->person[1]->setText("<![CDATA[Susie Q. Public]]>");
echo 
$n;

/* output :
<?xml version="1.0"?>
<people xmlns:p="http://example.org/ns" xmlns:t="http://example.org/test">
  <p:person t:id="1">John Doe</p:person>
  <p:person t:id="2" a:addr="123 Street" xmlns:a="http://example.org/addr"><![CDATA[Susie Q. Public]]></p:person>
</people>
*/

$d = new DomDocument();
$d->loadXML($n->export());
echo 
$d->saveXML();
/* output :
<?xml version="1.0"?>
<people xmlns:p="http://example.org/ns" xmlns:t="http://example.org/test">
  <p:person t:id="1">John Doe</p:person>
  <p:person xmlns:a="http://example.org/addr" t:id="2" a:addr="123 Street"><![CDATA[Susie Q. Public]]></p:person>
</people>
<?xml version="1.0"?>
*/

$n->import($d->documentElement);
echo 
$n;
/* output :
<people xmlns:p="http://example.org/ns" xmlns:t="http://example.org/test">
  <p:person t:id="1">John Doe</p:person>
  <p:person t:id="2" a:addr="123 Street" xmlns:a="http://example.org/addr"><![CDATA[Susie Q. Public]]></p:person>
</people>
*/

?>