Location: PHPKode > scripts > XML Dropper > xml-dropper/XMLDropper.php
<?PHP

/*
Version 1.0, last update 11/12/2004
All code copyright Corey Tisdale (hide@address.com)
unless otherwise noted. This is freely distributable.
Use it. Tell me how to make it better.

Usage:
$x = new XMLDropper('myenvelopetag');

echo $x->StartDocument();

echo $x->OpenContainer('Somecontainertag', array('attrib1' => 'val1');

echo $x->DropTag('sometag', 'some data here', array('moreattribs' => 'more vals', 'yetmoreattribs' => 'yet more vals'));
echo $x->DropTag('empty_tag_with_attribs', '', array('moreattribs' => 'more vals', 'yetmoreattribs' => 'yet more vals'));

echo $x->OpenContainer('Somenewcontainertag');

echo $x->DropTag('myemptytag');
echo $x->DropTag('my_tag_WITH_NO_ATTRIBS', 'content');

echo $x->EndDocument(); //note that EndDocument closes all open containers!!!!

Limitations:
Does not support namespaces
Does not enforce validation rules against DTDs or schemas
Probably does not take spaces out of tag names
Does not print the DOCTYPE tag
*/

class XMLDropper {
	protected $containerStack;
	protected $envelope;
	protected $version;
	protected $tabCount;
	protected $charset;
	
/**
 * @return void
 * @param string $envelope
 * @param string $charSet
 * @desc Creates an XMLDropper object with an envelope
 *		named $envelope. It specifies charset $charSet
 *		in the resultant document.
*/
	function __construct($envelope="XML", $charSet = 'UTF-8') {
		
		$this->version = '1.0';
		$this->charset = $charSet;
		$this->envelope = ($envelope == "") ? "XML" : $envelope;
		$this->containerStack = array();
		$this->tabCount = 0;
		$this->tab = "\t";
	}
	
	
/**
 * @return string
 * @desc Returns the XML header, currently version 1.0
*/
	function DropHeader() {
		return "<?xml version=\"{$this->version}\" encoding=\"{$this->charset}\"?>";
	}
	
/**
 * @return string
 * @desc Returns the XML header and opens the XML envelope
*/
	function StartDocument() {
		return $this->DropHeader() . "\n" . $this->OpenEnvelope();
	}
	
/**
 * @return string
 * @desc Returns the closing tags for any open containers
 *		and the close envelope tag
*/
	function EndDocument() {
		$temp = "";
		
		for($x = count($this->containerStack); $x>0; $x--) {
			$temp .= $this->CloseContainer();
		}
		
		return $temp;
	}
	
/**
 * @return string
 * @desc Returns the open envelope tag
*/
	function OpenEnvelope() {
		return $this->OpenContainer($this->envelope);
	}
	
/**
 * @return string
 * @desc Returns the close envelope tag
*/
	function CloseEnvelope() {
		return $this->EndDocument();
	}
	
/**
 * @return string
 * @param string $tag
 * @param string $attribs
 * @desc Returns the opening tag for tag $tag with 
 *		the escaped attributes contained in $attribs.
 *		$attribs should be associative; the index
 *		should be the attribute name and the value
 *		should be the value. This object keeps track
 *		of all open container tags.  Output is XML
 *		safe in theory.
*/
	function OpenContainer($tag, $attribs=array()) {
		$tag = $this->MakeSafe($tag); //make sure!
		
		//indent
		$this->tabCount++;
		
		//add to stack
		array_push($this->containerStack, $tag);
		
		//start tage
		$result = "<$tag";
		
		//attributes
		$result .= $this->DropAttribs($attribs);
		
		//Close tag
		$result .= ">";
		
		$result = str_repeat($this->tab, $this->tabCount) . $result . "\n";
		
		return $result;
	}
	
/**
 * @return string
 * @desc Returns the closing tag the for 
 *		the next container to close.
*/
	function CloseContainer() {
		//get last tag
		$tag = array_pop($this->containerStack);
		
		//start tage
		$result = "</$tag>";
		
		$result = str_repeat($this->tab, $this->tabCount) . $result . "\n";
		
		//unindent
		$this->tabCount--;
		
		return $result;
	}
	
/**
 * @return string
 * @param string $string
 * @desc Returns a string escaped for xml. Omits any control characters
 *		May not translate some chars; just add them to the array here as
 *		'whatever value ord() returns' => 'whatever the unicode value is'
*/
	public static function MakeSafe($str)
	{
		//Code by Billy Kimble and Corey Tisdale
		$tr = array(
		'34' => '34', //'"'
		'36' => '36', //'$'
		'37' => '37', //'%'
		'38' => '38', //'&'
		'39' => '39', //'''
		'60' => '60', //'<'
		'62' => '62', //'>'
		'63' => '63', //'?'
		'64' => '64', //'@'
		'94' => '94', //'^'
		'96' => '96', //'`'
		'124' => '124', //'|'
		'126' => '126', //'~'
		'147' => '8220', //'ì'
		'148' => '8221', //'î'
		'153' => '8482', //'TM'
		'160' => '160', //non-breaking space
		'162' => '162', //'¢'
		'163' => '163', //'£'
		'165' => '165', //'•'
		'167' => '167', //'ß'
		'169' => '169', //'©'
		'174' => '174', //'Æ'
		'176' => '176', //'&#8734;'
		'177' => '177', //'±'
		'183' => '183', //'&#8721;'
		'188' => '188', //'º'
		'189' => '189', //'&#937;'
		'190' => '190', //'æ'
		'198' => '198', //'&#8710;'
		'215' => '215', //'&#9674;'
		'230' => '230', //'Ê'
		'247' => '247' //'˜'
		);

		$str = str_split($str);
		foreach ($str as $key=>$char)
		{
			$nextChar = (isset($str[$key+1])) ? $str[$key+1] : '';
			if (ord($char) <= 31) { //remove control characters
				$str[$key] = '';
			} else if (array_key_exists(ord($char),$tr)) {
				if ($nextChar != '#') {
					$str[$key] = '&#' . $tr[ord($char)] . ';';
				}
			}
		}
		return join('',$str);
	}

/**
 * @return string
 * @param string $tag
 * @param string $content
 * @param string $attribs
 * @desc Returns the opening tag for tag $tag with 
 *		the escaped attributes contained in $attribs,
 *		the escaped $content, and then the closing tag
 *		for $tag. $attribs should be associative; the index
 *		should be the attribute name and the value
 *		should be the value. This object keeps track
 *		of all open container tags. Output is XML
 *		safe in theory.
*/
	function DropTag($tag, $content='', $attribs=array(), $toCDATA=false) {
		$tag = $this->MakeSafe($tag); //make sure!
		$content = $this->MakeSafe($content); //safe this bitch
		
		//start tage
		$result = "<$tag";
		
		//attributes
		$result .= $this->DropAttribs($attribs);
		
		//end here
		if($content == "") {
			$result .= "/>";
		} else {
			$result .= ">";
			if ($toCDATA) {
				$result .= "<![CDATA[{$content}]]>";
			} else {
				$result .= $content;
			}
			$result .= "</$tag>";
		}
		
		$result = str_repeat($this->tab, ($this->tabCount+1)) . $result . "\n";
		
		return $result;
	}
	
/**
 * @return string
 * @param string $attribs
 * @desc Returns the escaped attributes contained in
 *		$attribs. $attribs should be associative; the index
 *		should be the attribute name and the value
 *		should be the value. This object keeps track
 *		of all open container tags.
*/
	function DropAttribs($attribs) {
		$result = "";
		
		foreach($attribs as $attrib => $val) {
			$result .= ' ' . $this->MakeSafe($attrib) . '="' . $this->MakeSafe($val) . '"';
		}
		
		return $result;
	}
}

?>
Return current item: XML Dropper