PageRenderTime 38ms CodeModel.GetById 7ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/minixml/element.inc.php

http://wowroster.googlecode.com/
PHP | 1771 lines | 856 code | 391 blank | 524 comment | 165 complexity | 08a872fcdef22cff32f17e17b4305514 MD5 | raw file
   1<?php
   2/**
   3 * WoWRoster.net WoWRoster
   4 *
   5 * MiniXML Library
   6 *
   7 *
   8 * @copyright  2002-2011 WoWRoster.net
   9 * @license    http://www.gnu.org/licenses/gpl.html   Licensed under the GNU General Public License v3.
  10 * @version    SVN: $Id: element.inc.php 2222 2010-12-05 10:05:37Z c.treyce@gmail.com $
  11 * @link       http://www.wowroster.net
  12 * @since      File available since Release 1.8.0
  13 * @package    WoWRoster
  14 * @subpackage MiniXML
  15*/
  16
  17/***************************************************************************************************
  18****************************************************************************************************
  19*****
  20*****      MiniXML - PHP class library for generating and parsing XML.
  21*****
  22*****      Copyright (C) 2002-2005 Patrick Deegan, Psychogenic.com
  23*****      All rights reserved.
  24*****
  25*****      http://minixml.psychogenic.com
  26*****
  27*****   This program is free software; you can redistribute
  28*****   it and/or modify it under the terms of the GNU
  29*****   General Public License as published by the Free
  30*****   Software Foundation; either version 2 of the
  31*****   License, or (at your option) any later version.
  32*****
  33*****   This program is distributed in the hope that it will
  34*****   be useful, but WITHOUT ANY WARRANTY; without even
  35*****   the implied warranty of MERCHANTABILITY or FITNESS
  36*****   FOR A PARTICULAR PURPOSE.  See the GNU General
  37*****   Public License for more details.
  38*****
  39*****   You should have received a copy of the GNU General
  40*****   Public License along with this program; if not,
  41*****   write to the Free Software Foundation, Inc., 675
  42*****   Mass Ave, Cambridge, MA 02139, USA.
  43*****
  44*****
  45*****   You may contact the author, Pat Deegan, through the
  46*****   contact section at http://www.psychogenic.com
  47*****
  48*****   Much more information on using this API can be found on the
  49*****   official MiniXML website - http://minixml.psychogenic.com
  50*****	or within the Perl version (XML::Mini) available through CPAN
  51*****
  52****************************************************************************************************
  53***************************************************************************************************/
  54
  55
  56
  57require_once(MINIXML_CLASSDIR . "/treecomp.inc.php");
  58require_once(MINIXML_CLASSDIR . "/node.inc.php");
  59
  60/***************************************************************************************************
  61****************************************************************************************************
  62*****
  63*****					  MiniXMLElement
  64*****
  65****************************************************************************************************
  66***************************************************************************************************/
  67
  68
  69/* class MiniXMLElement (MiniXMLTreeComponent)
  70**
  71** Although the main handle to the xml document is the MiniXMLDoc object,
  72** much of the functionality and manipulation involves interaction with
  73** MiniXMLElement objects.
  74**
  75** A MiniXMLElement
  76** has:
  77** - a name
  78** - a list of 0 or more attributes (which have a name and a value)
  79** - a list of 0 or more children (MiniXMLElement or MiniXMLNode objects)
  80** - a parent (optional, only if MINIXML_AUTOSETPARENT > 0)
  81**/
  82
  83class MiniXMLElement extends MiniXMLTreeComponent {
  84
  85
  86	var $xname;
  87	var $xattributes;
  88	var $xchildren;
  89	var $xnumChildren;
  90	var $xnumElementChildren;
  91
  92	var $xavoidLoops = MINIXML_AVOIDLOOPS;
  93
  94
  95	/* MiniXMLElement NAME
  96	** Creates and inits a new MiniXMLElement
  97	*/
  98	function MiniXMLElement ($name=NULL)
  99	{
 100		$this->MiniXMLTreeComponent();
 101		$this->xname = NULL;
 102		$this->xattributes = array();
 103		$this->xchildren = array();
 104		$this->xnumChildren = 0;
 105		$this->xnumElementChildren = 0;
 106		if ($name)
 107		{
 108			$this->name($name);
 109		} else {
 110			return _MiniXMLError("MiniXMLElement Constructor: must pass a name to constructor");
 111		}
 112	} /* end method MiniXMLElement */
 113
 114
 115	/**************** Get/set methods for MiniXMLElement data *****************/
 116
 117
 118	/* name [NEWNAME]
 119	**
 120	** If a NEWNAME string is passed, the MiniXMLElement's name is set
 121	** to NEWNAME.
 122	**
 123	** Returns the element's name.
 124	*/
 125	function name ($setTo=NULL)
 126	{
 127		if (! is_null($setTo))
 128		{
 129			if (! is_string($setTo))
 130			{
 131				return _MiniXMLError("MiniXMLElement::name() Must pass a STRING to method to set name");
 132			}
 133
 134			$this->xname = $setTo;
 135		}
 136
 137		return $this->xname;
 138
 139	} /* end method name */
 140
 141
 142
 143	/* attribute NAME [SETTO [SETTOALT]]
 144	**
 145	** The attribute() method is used to get and set the
 146	** MiniXMLElement's attributes (ie the name/value pairs contained
 147	** within the tag, <tagname attrib1="value1" attrib2="value2">)
 148	**
 149	** If SETTO is passed, the attribute's value is set to SETTO.
 150	**
 151	** If the optional SETTOALT is passed and SETTO is false, the
 152	** attribute's value is set to SETTOALT.  This is usefull in cases
 153	** when you wish to set the attribute to a default value if no SETTO is
 154	** present, eg $myelement->attribute('href', $theHref, 'http://psychogenic.com')
 155	** will default to 'http://psychogenic.com'.
 156	**
 157	** Note: if the MINIXML_LOWERCASEATTRIBUTES define is > 0, all attribute names
 158	** will be lowercased (while setting and during retrieval)
 159	**
 160	** Returns the value associated with attribute NAME.
 161	**
 162	*/
 163	function attribute ($name, $primValue=NULL, $altValue=NULL)
 164	{
 165		$value = (is_null($primValue) ? $altValue : $primValue );
 166
 167
 168		if (MINIXML_UPPERCASEATTRIBUTES > 0)
 169		{
 170			$name = strtoupper($name);
 171		} elseif (MINIXML_LOWERCASEATTRIBUTES > 0)
 172		{
 173			$name = strtolower($name);
 174		}
 175
 176		if (! is_null($value))
 177		{
 178
 179			$this->xattributes[$name] = $value;
 180		}
 181
 182		if (! is_null($this->xattributes[$name]))
 183		{
 184			return $this->xattributes[$name];
 185		} else {
 186			return NULL;
 187		}
 188
 189	} /* end method attribute */
 190
 191
 192	/* text [SETTO [SETTOALT]]
 193	**
 194	** The text() method is used to get or append text data to this
 195	** element (it is appended to the child list as a new MiniXMLNode object).
 196	**
 197	** If SETTO is passed, a new node is created, filled with SETTO
 198	** and appended to the list of this element's children.
 199	**
 200	** If the optional SETTOALT is passed and SETTO is false, the
 201	** new node's value is set to SETTOALT.  See the attribute() method
 202	** for an example use.
 203	**
 204	** Returns a string composed of all child MiniXMLNodes' contents.
 205	**
 206	** Note: all the children MiniXMLNodes' contents - including numeric
 207	** nodes are included in the return string.
 208	*/
 209	function text ($setToPrimary = NULL, $setToAlternate=NULL)
 210	{
 211		$setTo = ($setToPrimary ? $setToPrimary : $setToAlternate);
 212
 213		if (! is_null($setTo))
 214		{
 215			$this->createNode($setTo);
 216		}
 217
 218		$retString = '';
 219
 220		/* Extract text from all child nodes */
 221		for($i=0; $i< $this->xnumChildren; $i++)
 222		{
 223			if ($this->isNode($this->xchildren[$i]))
 224			{
 225				$nodeTxt = $this->xchildren[$i]->getValue();
 226				if (! is_null($nodeTxt))
 227				{
 228					$retString .= "$nodeTxt ";
 229
 230				} /* end if text returned */
 231
 232			} /* end if this is a MiniXMLNode */
 233
 234		} /* end loop over all children */
 235
 236		return $retString;
 237
 238	}  /* end method text */
 239
 240
 241
 242	/* numeric [SETTO [SETTOALT]]
 243	**
 244	** The numeric() method is used to get or append numeric data to
 245	** this element (it is appended to the child list as a MiniXMLNode object).
 246	**
 247	** If SETTO is passed, a new node is created, filled with SETTO
 248	** and appended to the list of this element's children.
 249	**
 250	** If the optional SETTOALT is passed and SETTO is false, the
 251	** new node's value is set to SETTOALT.  See the attribute() method
 252	** for an example use.
 253	**
 254	** Returns a space seperated string composed all child MiniXMLNodes'
 255	** numeric contents.
 256	**
 257	** Note: ONLY numerical contents are included from the list of child MiniXMLNodes.
 258	**
 259	*/
 260	function numeric ($setToPrimary = NULL, $setToAlternate=NULL)
 261	{
 262		$setTo = (is_null($setToPrimary) ? $setToAlternate : $setToPrimary);
 263
 264		if (! is_null($setTo))
 265		{
 266			$this->createNode($setTo);
 267		}
 268
 269	} /* end method numeric */
 270
 271
 272	/* comment CONTENTS
 273	**
 274	** The comment() method allows you to add a new MiniXMLElementComment to this
 275	** element's list of children.
 276	**
 277	** Comments will return a <!-- CONTENTS --> string when the element's toString()
 278	** method is called.
 279	**
 280	** Returns a reference to the newly appended MiniXMLElementComment
 281	**
 282	*/
 283	function & comment ($contents)
 284	{
 285		$newEl = new MiniXMLElementComment();
 286
 287		$appendedComment =& $this->appendChild($newEl);
 288		$appendedComment->text($contents);
 289
 290		return $appendedComment;
 291
 292	} /* end method comment */
 293
 294
 295
 296
 297
 298
 299
 300	/*
 301	** docType DEFINITION
 302	**
 303	** Append a new <!DOCTYPE DEFINITION [ ...]> element as a child of this
 304	** element.
 305	**
 306	** Returns the appended DOCTYPE element. You will normally use the returned
 307	** element to add ENTITY elements, like
 308
 309	** $newDocType =& $xmlRoot->docType('spec SYSTEM "spec.dtd"');
 310	** $newDocType->entity('doc.audience', 'public review and discussion');
 311	*/
 312
 313	function & docType ($definition)
 314	{
 315
 316		$newElement = new MiniXMLElementDocType($definition);
 317		$appendedElement =& $this->appendChild($newElement);
 318
 319		return $appendedElement;
 320	}
 321	/*
 322	** entity NAME VALUE
 323	**
 324	** Append a new <!ENTITY NAME "VALUE"> element as a child of this
 325	** element.
 326
 327	** Returns the appended ENTITY element.
 328	*/
 329	function & entity ($name,$value)
 330	{
 331
 332		$newElement = new MiniXMLElementEntity($name, $value);
 333		$appendedEl =& $this->appendChild($newElement);
 334
 335		return $appendedEl;
 336	}
 337
 338
 339	/*
 340	** cdata CONTENTS
 341	**
 342	** Append a new <![CDATA[ CONTENTS ]]> element as a child of this element.
 343	** Returns the appended CDATA element.
 344	**
 345	*/
 346
 347	function & cdata ($contents)
 348	{
 349		$newElement = new MiniXMLElementCData($contents);
 350		$appendedChild =& $this->appendChild($newElement);
 351
 352		return $appendedChild;
 353	}
 354
 355
 356	/* getValue
 357	**
 358	** Returns a string containing the value of all the element's
 359	** child MiniXMLNodes (and all the MiniXMLNodes contained within
 360	** it's child MiniXMLElements, recursively).
 361	**
 362	** Note: the seperator parameter remains officially undocumented
 363	** since I'm not sure it will remain part of the API
 364	*/
 365	function getValue ($seperator=' ')
 366	{
 367		$retStr = '';
 368		$valArray = array();
 369		for($i=0; $i < $this->xnumChildren; $i++)
 370		{
 371			$value = $this->xchildren[$i]->getValue();
 372			if (! is_null($value))
 373			{
 374				array_push($valArray, $value);
 375			}
 376		}
 377		if (count($valArray))
 378		{
 379			$retStr = implode($seperator, $valArray);
 380		}
 381		return $retStr;
 382
 383	} /* end method getValue */
 384
 385
 386
 387	/* getElement NAME
 388	** Searches the element and it's children for an element with name NAME.
 389	**
 390	** Returns a reference to the first MiniXMLElement with name NAME,
 391	** if found, NULL otherwise.
 392	**
 393	** NOTE: The search is performed like this, returning the first
 394	** 	 element that matches:
 395	**
 396	** - Check this element for a match
 397	** - Check this element's immediate children (in order) for a match.
 398	** - Ask each immediate child (in order) to MiniXMLElement::getElement()
 399	**  (each child will then proceed similarly, checking all it's immediate
 400	**   children in order and then asking them to getElement())
 401	*/
 402	function &getElement ($name)
 403	{
 404
 405		if (MINIXML_DEBUG > 0)
 406		{
 407			$elname = $this->name();
 408			_MiniXMLLog("MiniXMLElement::getElement() called for $name on $elname.");
 409		}
 410		if (is_null($name))
 411		{
 412			return _MiniXMLError("MiniXMLElement::getElement() Must Pass Element name.");
 413		}
 414
 415
 416		/** Must only check children as checking $this results in an inability to
 417		*** fetch nested objects with the same name
 418		*** <tag>
 419		***  <nested>
 420		***   <nested>
 421		***     Can't get here from tag or from the first 'nested'
 422		***   </nested>
 423		***  </nested>
 424		*** </tag>
 425		if (MINIXML_CASESENSITIVE > 0)
 426		{
 427			if (strcmp($this->xname, $name) == 0)
 428			{
 429				/* This element is it * /
 430				return $this;
 431			}
 432		} else {
 433
 434			if (strcasecmp($this->xname,$name) == 0)
 435			{
 436				return $this;
 437			}
 438		}
 439
 440		***** end commented out section ****
 441		*/
 442
 443		if (! $this->xnumChildren )
 444		{
 445			/* Not match here and and no kids - not found... */
 446			return NULL;
 447		}
 448
 449		/* Try each child (immediate children take priority) */
 450		for ($i = 0; $i < $this->xnumChildren; $i++)
 451		{
 452			$childname = $this->xchildren[$i]->name();
 453			if ($childname)
 454			{
 455				if (MINIXML_CASESENSITIVE > 0)
 456				{
 457					/* case sensitive matches only */
 458					if (strcmp($name, $childname) == 0)
 459					{
 460						return $this->xchildren[$i];
 461					}
 462				} else {
 463					/* case INsensitive matching */
 464					if (strcasecmp($name, $childname) == 0)
 465					{
 466						return $this->xchildren[$i];
 467					}
 468				} /* end if case sensitive */
 469			} /* end if child has a name */
 470
 471		} /* end loop over all my children */
 472
 473		/* Use beautiful recursion, daniel san */
 474		for ($i = 0; $i < $this->xnumChildren; $i++)
 475		{
 476			$theelement =& $this->xchildren[$i]->getElement($name);
 477			if ($theelement)
 478			{
 479				if (MINIXML_DEBUG > 0)
 480				{
 481					_MiniXMLLog("MiniXMLElement::getElement() returning element $theelement");
 482				}
 483				return $theelement;
 484			}
 485		}
 486
 487		/* Not found */
 488		return NULL;
 489
 490
 491	}  /* end method getElement */
 492
 493
 494	/* getElementByPath PATH
 495	** Attempts to return a reference to the (first) element at PATH
 496	** where PATH is the path in the structure (relative to this element) to
 497	** the requested element.
 498	**
 499	** For example, in the document represented by:
 500	**
 501	**	 <partRateRequest>
 502	**	  <vendor>
 503	**	   <accessid user="myusername" password="mypassword" />
 504	**	  </vendor>
 505	**	  <partList>
 506	**	   <partNum>
 507	**	    DA42
 508	**	   </partNum>
 509	**	   <partNum>
 510	**	    D99983FFF
 511	**	   </partNum>
 512	**	   <partNum>
 513	**	    ss-839uent
 514	**	   </partNum>
 515	**	  </partList>
 516	**	 </partRateRequest>
 517	**
 518	**	$partRate =& $xmlDocument->getElement('partRateRequest');
 519	**
 520	** 	$accessid =& $partRate->getElementByPath('vendor/accessid');
 521	**
 522	** Will return what you expect (the accessid element with attributes user = "myusername"
 523	** and password = "mypassword").
 524	**
 525	** BUT be careful:
 526	**	$accessid =& $partRate->getElementByPath('partList/partNum');
 527	**
 528	** will return the partNum element with the value "DA42".  Other partNums are
 529	** inaccessible by getElementByPath() - Use MiniXMLElement::getAllChildren() instead.
 530	**
 531	** Returns the MiniXMLElement reference if found, NULL otherwise.
 532	*/
 533	function &getElementByPath($path)
 534	{
 535		$names = split ("/", $path);
 536
 537		$element = $this;
 538		foreach ($names as $elementName)
 539		{
 540			if ($element && $elementName) /* Make sure we didn't hit a dead end and that we have a name*/
 541			{
 542				/* Ask this element to get the next child in path */
 543				$element =& $element->getElement($elementName);
 544			}
 545		}
 546
 547		return $element;
 548
 549	} /* end method getElementByPath */
 550
 551
 552
 553	/* numChildren [NAMED]
 554	**
 555	** Returns the number of immediate children for this element
 556	**
 557	** If the optional NAMED parameter is passed, returns only the
 558	** number of immediate children named NAMED.
 559	*/
 560	function numChildren ($named=NULL)
 561	{
 562		if (is_null($named))
 563		{
 564			return $this->xnumElementChildren;
 565		}
 566
 567		/* We require only children named '$named' */
 568		$allkids =& $this->getAllChildren($named);
 569
 570		return count($allkids);
 571
 572
 573	}
 574
 575
 576	/* getAllChildren [NAME]
 577	**
 578	** Returns a reference to an array of all this element's MiniXMLElement children
 579	**
 580	** Note: although the MiniXMLElement may contain MiniXMLNodes as children, these are
 581	** not part of the returned list.
 582	**/
 583	function &getAllChildren ($name=NULL)
 584	{
 585		$retArray = array();
 586		$count = 0;
 587
 588		if (is_null($name))
 589		{
 590			/* Return all element children */
 591			for($i=0; $i < $this->xnumChildren; $i++)
 592			{
 593				if (method_exists($this->xchildren[$i], 'MiniXMLElement'))
 594				{
 595					$retArray[$count++] =& $this->xchildren[$i];
 596				}
 597			}
 598		} else {
 599			/* Return only element children with name $name */
 600
 601			for($i=0; $i < $this->xnumChildren; $i++)
 602			{
 603				if (method_exists($this->xchildren[$i], 'MiniXMLElement'))
 604				{
 605					if (MINIXML_CASESENSITIVE > 0)
 606					{
 607						if ($this->xchildren[$i]->name() == $name)
 608						{
 609							$retArray[$count++] =& $this->xchildren[$i];
 610						}
 611					} else {
 612						if (strcasecmp($this->xchildren[$i]->name(), $name) == 0)
 613						{
 614							$retArray[$count++] =& $this->xchildren[$i];
 615						}
 616					} /* end if case sensitive */
 617
 618				} /* end if child is a MiniXMLElement object */
 619
 620			} /* end loop over all children */
 621
 622		} /* end if specific name was requested */
 623
 624		return $retArray;
 625
 626	} /* end method getAllChildren */
 627
 628
 629
 630	function &insertChild (&$child, $idx=0)
 631	{
 632
 633
 634
 635		if (! $this->_validateChild($child))
 636		{
 637			return;
 638		}
 639
 640		/* Set the parent for the child element to this element if
 641		** avoidLoops or MINIXML_AUTOSETPARENT is set
 642		*/
 643		if ($this->xavoidLoops || (MINIXML_AUTOSETPARENT > 0) )
 644		{
 645			if ($this->xparent == $child)
 646			{
 647
 648				$cname = $child->name();
 649				return _MiniXMLError("MiniXMLElement::insertChild() Tryng to append parent $cname as child of "
 650							. $this->xname );
 651			}
 652			$child->parent($this);
 653		}
 654
 655
 656		$nextIdx = $this->xnumChildren;
 657		$lastIdx = $nextIdx - 1;
 658		if ($idx > $lastIdx)
 659		{
 660
 661			if ($idx > $nextIdx)
 662			{
 663				$idx = $lastIdx + 1;
 664			}
 665			$this->xchildren[$idx] = $child;
 666			$this->xnumChildren++;
 667			if ($this->isElement($child))
 668			{
 669				$this->xnumElementChildren++;
 670			}
 671
 672		} elseif ($idx >= 0)
 673		{
 674
 675			$removed = array_splice($this->xchildren, $idx);
 676			array_push($this->xchildren, $child);
 677			$numRemoved = count($removed);
 678
 679			for($i=0; $i<$numRemoved; $i++)
 680			{
 681
 682				array_push($this->xchildren, $removed[$i]);
 683			}
 684			$this->xnumChildren++;
 685			if ($this->isElement($child))
 686			{
 687				$this->xnumElementChildren++;
 688			}
 689
 690
 691		} else {
 692			$revIdx = (-1 * $idx) % $this->xnumChildren;
 693			$newIdx = $this->xnumChildren - $revIdx;
 694
 695			if ($newIdx < 0)
 696			{
 697				return _MiniXMLError("Element::insertChild() Ended up with a negative index? ($newIdx)");
 698			}
 699
 700			return $this->insertChild($child, $newIdx);
 701		}
 702
 703		return $child;
 704	}
 705
 706
 707	/* appendChild CHILDELEMENT
 708	**
 709	** appendChild is used to append an existing MiniXMLElement object to
 710	** this element's list.
 711	**
 712	** Returns a reference to the appended child element.
 713	**
 714	** NOTE: Be careful not to create loops in the hierarchy, eg
 715	** $parent->appendChild($child);
 716	** $child->appendChild($subChild);
 717	** $subChild->appendChild($parent);
 718	**
 719	** If you want to be sure to avoid loops, set the MINIXML_AVOIDLOOPS define
 720	** to 1 or use the avoidLoops() method (will apply to all children added with createChild())
 721	*/
 722	function &appendChild (&$child)
 723	{
 724
 725		if (! $this->_validateChild($child))
 726		{
 727			_MiniXMLLog("MiniXMLElement::appendChild() Could not validate child, aborting append");
 728			return NULL;
 729		}
 730
 731		/* Set the parent for the child element to this element if
 732		** avoidLoops or MINIXML_AUTOSETPARENT is set
 733		*/
 734		if ($this->xavoidLoops || (MINIXML_AUTOSETPARENT > 0) )
 735		{
 736			if ($this->xparent == $child)
 737			{
 738
 739				$cname = $child->name();
 740				return _MiniXMLError("MiniXMLElement::appendChild() Tryng to append parent $cname as child of "
 741							. $this->xname );
 742			}
 743			$child->parent($this);
 744		}
 745
 746
 747		$this->xnumElementChildren++; /* Note that we're addind a MiniXMLElement child */
 748
 749		/* Add the child to the list */
 750		$idx = $this->xnumChildren++;
 751		$this->xchildren[$idx] =& $child;
 752
 753		return $this->xchildren[$idx];
 754
 755	} /* end method appendChild */
 756
 757
 758	/* prependChild CHILDELEMENT
 759	**
 760	** prependChild is used to prepend an existing MiniXMLElement object to
 761	** this element's list.  The child will be positioned at the begining of
 762	** the elements child list, thus it will be output first in the resulting XML.
 763	**
 764	** Returns a reference to the prepended child element.
 765	*/
 766	function &prependChild ($child)
 767	{
 768
 769
 770		if (! $this->_validateChild($child))
 771		{
 772			_MiniXMLLog("MiniXMLElement::prependChild - Could not validate child, aborting.");
 773			return NULL;
 774		}
 775
 776		/* Set the parent for the child element to this element if
 777		** avoidLoops or MINIXML_AUTOSETPARENT is set
 778		*/
 779		if ($this->xavoidLoops || (MINIXML_AUTOSETPARENT > 0) )
 780		{
 781			if ($this->xparent == $child)
 782			{
 783
 784				$cname = $child->name();
 785				return _MiniXMLError("MiniXMLElement::prependChild() Tryng to append parent $cname as child of "
 786							. $this->xname );
 787			}
 788			$child->parent($this);
 789		}
 790
 791
 792		$this->xnumElementChildren++; /* Note that we're adding a MiniXMLElement child */
 793
 794		/* Add the child to the list */
 795		$idx = $this->xnumChildren++;
 796		array_unshift($this->xchildren, $child);
 797		return $this->xchildren[0];
 798
 799	} /* end method prependChild */
 800
 801	function _validateChild (&$child)
 802	{
 803
 804		if (is_null($child))
 805		{
 806			return  _MiniXMLError("MiniXMLElement::_validateChild() need to pass a non-NULL MiniXMLElement child.");
 807		}
 808
 809		if (! method_exists($child, 'MiniXMLElement'))
 810		{
 811			return _MiniXMLError("MiniXMLElement::_validateChild() must pass a MiniXMLElement object to _validateChild.");
 812		}
 813
 814		/* Make sure element is named */
 815		$cname = $child->name();
 816		if (is_null($cname))
 817		{
 818			_MiniXMLLog("MiniXMLElement::_validateChild() children must be named");
 819			return 0;
 820		}
 821
 822
 823		/* Check for loops */
 824		if ($child == $this)
 825		{
 826			_MiniXMLLog("MiniXMLElement::_validateChild() Trying to append self as own child!");
 827			return 0;
 828		} elseif ( $this->xavoidLoops && $child->parent())
 829		{
 830			_MiniXMLLog("MiniXMLElement::_validateChild() Trying to append a child ($cname) that already has a parent set "
 831						. "while avoidLoops is on - aborting");
 832			return 0;
 833		}
 834
 835		return 1;
 836	}
 837	/* createChild ELEMENTNAME [VALUE]
 838	**
 839	** Creates a new MiniXMLElement instance and appends it to the list
 840	** of this element's children.
 841	** The new child element's name is set to ELEMENTNAME.
 842	**
 843	** If the optional VALUE (string or numeric) parameter is passed,
 844	** the new element's text/numeric content will be set using VALUE.
 845	**
 846	** Returns a reference to the new child element
 847	**
 848	** Note: don't forget to use the =& (reference assignment) operator
 849	** when calling createChild:
 850	**
 851	**	$newChild =& $myElement->createChild('newChildName');
 852	**
 853	*/
 854	function & createChild ($name, $value=NULL)
 855	{
 856		if (! $name)
 857		{
 858			return _MiniXMLError("MiniXMLElement::createChild() Must pass a NAME to createChild.");
 859		}
 860
 861		if (! is_string($name))
 862		{
 863			return _MiniXMLError("MiniXMLElement::createChild() Name of child must be a STRING");
 864		}
 865
 866		$child = new MiniXMLElement($name);
 867
 868		$appendedChild =& $this->appendChild($child);
 869
 870		if (! $appendedChild )
 871		{
 872			_MiniXMLLog("MiniXMLElement::createChild() '$name' child NOT appended.");
 873			return NULL;
 874		}
 875
 876		if (! is_null($value))
 877		{
 878			if (is_numeric($value))
 879			{
 880				$appendedChild->numeric($value);
 881			} elseif (is_string($value))
 882			{
 883				$appendedChild->text($value);
 884			}
 885		}
 886
 887		$appendedChild->avoidLoops($this->xavoidLoops);
 888
 889		return $appendedChild;
 890
 891	} /* end method createChild */
 892
 893
 894
 895	/* removeChild CHILD
 896	** Removes CHILD from this element's list of children.
 897	**
 898	** Returns the removed child, if found, NULL otherwise.
 899	*/
 900
 901	function &removeChild (&$child)
 902	{
 903		if (! $this->xnumChildren)
 904		{
 905			if (MINIXML_DEBUG > 0)
 906			{
 907				_MiniXMLLog("Element::removeChild() called for element without any children.") ;
 908			}
 909			return NULL;
 910		}
 911
 912		$foundChild = NULL;
 913		$idx = 0;
 914		while ($idx < $this->xnumChildren && ! $foundChild)
 915		{
 916			if ($this->xchildren[$idx] == $child)
 917			{
 918				$foundChild =& $this->xchildren[$idx];
 919			} else {
 920				$idx++;
 921			}
 922		}
 923
 924		if (! $foundChild)
 925		{
 926			if (MINIXML_DEBUG > 0)
 927			{
 928				_MiniXMLLog("Element::removeChild() No matching child found.") ;
 929			}
 930			return NULL;
 931		}
 932
 933		array_splice($this->xchildren, $idx, 1);
 934
 935		$this->xnumChildren--;
 936		if ($this->isElement($foundChild))
 937		{
 938			$this->xnumElementChildren--;
 939		}
 940
 941		unset ($foundChild->xparent) ;
 942		return $foundChild;
 943	}
 944
 945
 946	/* removeAllChildren
 947	** Removes all children of this element.
 948	**
 949	** Returns an array of the removed children (which may be empty)
 950	*/
 951	function &removeAllChildren ()
 952	{
 953		$emptyArray = array();
 954
 955		if (! $this->xnumChildren)
 956		{
 957			return $emptyArray;
 958		}
 959
 960		$retList =& $this->xchildren;
 961
 962		$idx = 0;
 963		while ($idx < $this->xnumChildren)
 964		{
 965			unset ($retList[$idx++]->xparent);
 966		}
 967
 968		$this->xchildren = array();
 969		$this->xnumElementChildren = 0;
 970		$this->xnumChildren = 0;
 971
 972
 973		return $retList;
 974	}
 975
 976
 977	function & remove ()
 978	{
 979		$parent =& $this->parent();
 980
 981		if (!$parent)
 982		{
 983			_MiniXMLLog("XML::Mini::Element::remove() called for element with no parent set.  Aborting.");
 984			return NULL;
 985		}
 986
 987		$removed =& $parent->removeChild($this);
 988
 989		return $removed;
 990	}
 991
 992
 993
 994	/* parent NEWPARENT
 995	**
 996	** The parent() method is used to get/set the element's parent.
 997	**
 998	** If the NEWPARENT parameter is passed, sets the parent to NEWPARENT
 999	** (NEWPARENT must be an instance of MiniXMLElement)
1000	**
1001	** Returns a reference to the parent MiniXMLElement if set, NULL otherwise.
1002	**
1003	** Note: This method is mainly used internally and you wouldn't normally need
1004	** to use it.
1005	** It get's called on element appends when MINIXML_AUTOSETPARENT or
1006	** MINIXML_AVOIDLOOPS or avoidLoops() > 1
1007	**
1008	*/
1009	function &parent (&$setParent)
1010	{
1011		if (! is_null($setParent))
1012		{
1013			/* Parents can only be MiniXMLElement objects */
1014			if (! $this->isElement($setParent))
1015			{
1016				return _MiniXMLError("MiniXMLElement::parent(): Must pass an instance of MiniXMLElement to set.");
1017			}
1018			$this->xparent = $setParent;
1019		}
1020
1021		return $this->xparent;
1022
1023	} /* end method parent */
1024
1025
1026	/* avoidLoops SETTO
1027	**
1028	** The avoidLoops() method is used to get or set the avoidLoops flag for this element.
1029	**
1030	** When avoidLoops is true, children with parents already set can NOT be appended to any
1031	** other elements.  This is overkill but it is a quick and easy way to avoid infinite loops
1032	** in the heirarchy.
1033	**
1034	** The avoidLoops default behavior is configured with the MINIXML_AVOIDLOOPS define but can be
1035	** set on individual elements (and automagically all the element's children) with the
1036	** avoidLoops() method.
1037	**
1038	** Returns the current value of the avoidLoops flag for the element.
1039	**
1040	*/
1041	function avoidLoops ($setTo = NULL)
1042	{
1043		if (! is_null($setTo))
1044		{
1045			$this->xavoidLoops = $setTo;
1046		}
1047
1048		return $this->xavoidLoops;
1049	}
1050
1051
1052	/* toString [SPACEOFFSET]
1053	**
1054	** toString returns an XML string based on the element's attributes,
1055	** and content (recursively doing the same for all children)
1056	**
1057	** The optional SPACEOFFSET parameter sets the number of spaces to use
1058	** after newlines for elements at this level (adding 1 space per level in
1059	** depth).  SPACEOFFSET defaults to 0.
1060	**
1061	** If SPACEOFFSET is passed as MINIXML_NOWHITESPACES.
1062	** no \n or whitespaces will be inserted in the xml string
1063	** (ie it will all be on a single line with no spaces between the tags.
1064	**
1065	** Returns the XML string.
1066	**
1067	**
1068	** Note: Since the toString() method recurses into child elements and because
1069	** of the MINIXML_NOWHITESPACES and our desire to avoid testing for this value
1070	** on every element (as it does not change), here we split up the toString method
1071	** into 2 subs: toStringWithWhiteSpaces(DEPTH) and toStringNoWhiteSpaces().
1072	**
1073	** Each of these methods, which are to be considered private (?), in turn recurses
1074	** calling the appropriate With/No WhiteSpaces toString on it's children - thereby
1075	** avoiding the test on SPACEOFFSET
1076	*/
1077
1078	function toString ($depth=0)
1079	{
1080		if ($depth == MINIXML_NOWHITESPACES)
1081		{
1082			return $this->toStringNoWhiteSpaces();
1083		} else {
1084			return $this->toStringWithWhiteSpaces($depth);
1085		}
1086	}
1087
1088	function toStringWithWhiteSpaces ($depth=0)
1089	{
1090		$attribString = '';
1091		$elementName = $this->xname;
1092		$spaces = $this->_spaceStr($depth) ;
1093
1094		$retString = "$spaces<$elementName";
1095
1096
1097		foreach ($this->xattributes as $attrname => $attrvalue)
1098		{
1099			$attribString .= "$attrname=\"$attrvalue\" ";
1100		}
1101
1102
1103		if ($attribString)
1104		{
1105			$attribString = rtrim($attribString);
1106			$retString .= " $attribString";
1107		}
1108
1109		if (! $this->xnumChildren)
1110		{
1111			/* No kids -> no sub-elements, no text, nothing - consider a <unary/> element */
1112			$retString .= " />\n";
1113
1114			return $retString;
1115		}
1116
1117
1118
1119		/* If we've gotten this far, the element has
1120		** kids or text - consider a <binary>otherstuff</binary> element
1121		*/
1122
1123		$onlyTxtChild = 0;
1124		if ($this->xnumChildren == 1 && ! $this->xnumElementChildren)
1125		{
1126			$onlyTxtChild = 1;
1127		}
1128
1129
1130
1131		if ($onlyTxtChild)
1132		{
1133			$nextDepth = 0;
1134			$retString .= "> ";
1135		} else {
1136			$nextDepth = $depth+1;
1137			$retString .= ">\n";
1138		}
1139
1140
1141
1142		for ($i=0; $i < $this->xnumChildren ; $i++)
1143		{
1144			if (method_exists($this->xchildren[$i], 'toStringWithWhiteSpaces') )
1145			{
1146
1147				$newStr = $this->xchildren[$i]->toStringWithWhiteSpaces($nextDepth);
1148
1149
1150				if (! is_null($newStr))
1151				{
1152					if (! ( preg_match("/\n\$/", $newStr) || $onlyTxtChild) )
1153					{
1154						$newStr .= "\n";
1155					}
1156
1157					$retString .= $newStr;
1158				}
1159
1160			} else {
1161				_MiniXMLLog("Invalid child found in $elementName ". $this->xchildren[$i]->name() );
1162
1163			} /* end if has a toString method */
1164
1165		} /* end loop over all children */
1166
1167		/* add the indented closing tag */
1168		if ($onlyTxtChild)
1169		{
1170			$retString .= " </$elementName>\n";
1171		} else {
1172			$retString .= "$spaces</$elementName>\n";
1173		}
1174		return $retString;
1175
1176	} /* end method toString */
1177
1178
1179
1180
1181	function toStringNoWhiteSpaces ()
1182	{
1183		$retString = '';
1184		$attribString = '';
1185		$elementName = $this->xname;
1186
1187		foreach ($this->xattributes as $attrname => $attrvalue)
1188		{
1189			$attribString .= "$attrname=\"$attrvalue\" ";
1190		}
1191
1192		$retString = "<$elementName";
1193
1194
1195		if ($attribString)
1196		{
1197			$attribString = rtrim($attribString);
1198			$retString .= " $attribString";
1199		}
1200
1201		if (! $this->xnumChildren)
1202		{
1203			/* No kids -> no sub-elements, no text, nothing - consider a <unary/> element */
1204
1205			$retString .= " />";
1206			return $retString;
1207		}
1208
1209
1210		/* If we've gotten this far, the element has
1211		** kids or text - consider a <binary>otherstuff</binary> element
1212		*/
1213		$retString .= ">";
1214
1215		/* Loop over all kids, getting associated strings */
1216		for ($i=0; $i < $this->xnumChildren ; $i++)
1217		{
1218			if (method_exists($this->xchildren[$i], 'toStringNoWhiteSpaces') )
1219			{
1220				$newStr = $this->xchildren[$i]->toStringNoWhiteSpaces();
1221
1222				if (! is_null($newStr))
1223				{
1224					$retString .= $newStr;
1225				}
1226
1227			} else {
1228				_MiniXMLLog("Invalid child found in $elementName");
1229
1230			} /* end if has a toString method */
1231
1232		} /* end loop over all children */
1233
1234		/* add the indented closing tag */
1235		$retString .= "</$elementName>";
1236
1237		return $retString;
1238
1239	} /* end method toStringNoWhiteSpaces */
1240
1241
1242	/* toStructure
1243	**
1244	** Converts an element to a structure - either an array or a simple string.
1245	**
1246	** This method is used by MiniXML documents to perform their toArray() magic.
1247	*/
1248	function & toStructure ()
1249	{
1250
1251		$retHash = array();
1252		$contents = "";
1253		$numAdded = 0;
1254
1255
1256
1257		for($i=0; $i< $this->xnumChildren; $i++)
1258		{
1259			if ($this->isElement($this->xchildren[$i]))
1260			{
1261				$name = $this->xchildren[$i]->name();
1262
1263				if (array_key_exists($name, $retHash))
1264
1265				{
1266					if (! (is_array($retHash[$name]) && array_key_exists('_num', $retHash[$name])) )
1267					{
1268						$retHash[$name] = array($retHash[$name],
1269									 $this->xchildren[$i]->toStructure());
1270
1271						$retHash[$name]['_num'] = 2;
1272					} else {
1273						array_push($retHash[$name], $this->xchildren[$i]->toStructure() );
1274
1275						$retHash[$name]['_num']++;
1276					}
1277				} else {
1278					$retHash[$name] = $this->xchildren[$i]->toStructure();
1279				}
1280
1281				$numAdded++;
1282			} else {
1283				$contents .= $this->xchildren[$i]->getValue();
1284			}
1285
1286
1287		}
1288
1289
1290		foreach ($this->xattributes as $attrname => $attrvalue)
1291		{
1292			#array_push($retHash, array($attrname => $attrvalue));
1293			$retHash["_attributes"][$attrname] = $attrvalue;
1294			$numAdded++;
1295		}
1296
1297
1298		if ($numAdded)
1299		{
1300			if (! empty($contents))
1301			{
1302				$retHash['_content'] = $contents;
1303			}
1304
1305			return $retHash;
1306		} else {
1307			return $contents;
1308		}
1309
1310	} // end toStructure() method
1311
1312
1313
1314
1315
1316	/* isElement ELEMENT
1317	** Returns a true value if ELEMENT is an instance of MiniXMLElement,
1318	** false otherwise.
1319	**
1320	** Note: Used internally.
1321	*/
1322	function isElement (&$testme)
1323	{
1324		if (is_null($testme))
1325		{
1326			return 0;
1327		}
1328
1329		return method_exists($testme, 'MiniXMLElement');
1330	}
1331
1332
1333	/* isNode NODE
1334	** Returns a true value if NODE is an instance of MiniXMLNode,
1335	** false otherwise.
1336	**
1337	** Note: used internally.
1338	*/
1339	function isNode (&$testme)
1340	{
1341		if (is_null($testme))
1342		{
1343			return 0;
1344		}
1345
1346		return method_exists($testme, 'MiniXMLNode');
1347	}
1348
1349
1350	/* createNode NODEVALUE [ESCAPEENTITIES]
1351	**
1352	** Private (?)
1353	**
1354	** Creates a new MiniXMLNode instance and appends it to the list
1355	** of this element's children.
1356	** The new child node's value is set to NODEVALUE.
1357	**
1358	** Returns a reference to the new child node.
1359	**
1360	** Note: You don't need to use this method normally - it is used
1361	** internally when appending text() and such data.
1362	**
1363	*/
1364	function & createNode (&$value, $escapeEntities=NULL)
1365	{
1366
1367		$newNode = new MiniXMLNode($value, $escapeEntities);
1368
1369		$appendedNode =& $this->appendNode($newNode);
1370
1371		return $appendedNode;
1372	}
1373
1374
1375	/* appendNode CHILDNODE
1376	**
1377	** appendNode is used to append an existing MiniXMLNode object to
1378	** this element's list.
1379	**
1380	** Returns a reference to the appended child node.
1381	**
1382	**
1383	** Note: You don't need to use this method normally - it is used
1384	** internally when appending text() and such data.
1385	*/
1386	function &appendNode (&$node)
1387	{
1388		if (is_null($node))
1389		{
1390			return  _MiniXMLError("MiniXMLElement::appendNode() need to pass a non-NULL MiniXMLNode.");
1391		}
1392
1393
1394		if (! method_exists($node, 'MiniXMLNode'))
1395		{
1396			return _MiniXMLError("MiniXMLElement::appendNode() must pass a MiniXMLNode object to appendNode.");
1397		}
1398
1399		if (MINIXML_AUTOSETPARENT)
1400		{
1401			if ($this->xparent == $node)
1402			{
1403				return _MiniXMLError("MiniXMLElement::appendnode() Tryng to append parent $cname as node of "
1404							. $this->xname );
1405			}
1406			$node->parent($this);
1407		}
1408
1409
1410		$idx = $this->xnumChildren++;
1411		$this->xchildren[$idx] = $node;
1412
1413		return $this->xchildren[$idx];
1414
1415
1416	}
1417
1418	/* Destructor to keep things clean -- patch by Ilya */
1419	function __destruct()
1420	{
1421		for ($i = 0; $i < count($this->xchildren); ++$i)
1422			$this->xchildren[$i]->xparent = null;
1423	}
1424
1425
1426} /* end MiniXMLElement class definition */
1427
1428
1429
1430
1431
1432
1433/***************************************************************************************************
1434****************************************************************************************************
1435*****
1436*****					  MiniXMLElementComment
1437*****
1438****************************************************************************************************
1439***************************************************************************************************/
1440
1441/* The MiniXMLElementComment class is a specific extension of the MiniXMLElement class.
1442**
1443** It is used to create the special <!-- comment --> tags and an instance in created when calling
1444** $elementObject->comment('this is a comment');
1445**
1446** It's methods are the same as for MiniXMLElement - see those for documentation.
1447**/
1448
1449class MiniXMLElementComment extends MiniXMLElement {
1450
1451	function MiniXMLElementComment ($name=NULL)
1452	{
1453		$this->MiniXMLElement('!--');
1454	}
1455
1456
1457	function toString ($depth=0)
1458	{
1459		if ($depth == MINIXML_NOWHITESPACES)
1460		{
1461			return $this->toStringNoWhiteSpaces();
1462		} else {
1463			return $this->toStringWithWhiteSpaces($depth);
1464		}
1465	}
1466
1467
1468	function toStringWithWhiteSpaces ($depth=0)
1469	{
1470
1471		$spaces = $this->_spaceStr($depth) ;
1472
1473		$retString = "$spaces<!-- \n";
1474
1475		if (! $this->xnumChildren)
1476		{
1477			/* No kids, no text - consider a <unary/> element */
1478			$retString .= " -->\n";
1479
1480			return $retString;
1481		}
1482
1483		/* If we get here, the element does have children... get their contents */
1484
1485		$nextDepth = $depth+1;
1486
1487		for ($i=0; $i < $this->xnumChildren ; $i++)
1488		{
1489			$retString .= $this->xchildren[$i]->toStringWithWhiteSpaces($nextDepth);
1490		}
1491
1492		$retString .= "\n$spaces -->\n";
1493
1494
1495		return $retString;
1496	}
1497
1498
1499	function toStringNoWhiteSpaces ()
1500	{
1501		$retString = '';
1502
1503		$retString = "<!-- ";
1504
1505		if (! $this->xnumChildren)
1506		{
1507			/* No kids, no text - consider a <unary/> element */
1508			$retString .= " -->";
1509			return $retString;
1510		}
1511
1512
1513		/* If we get here, the element does have children... get their contents */
1514		for ($i=0; $i < $this->xnumChildren ; $i++)
1515		{
1516			$retString .= $this->xchildren[$i]->toStringNoWhiteSpaces();
1517		}
1518
1519		$retString .= " -->";
1520
1521
1522		return $retString;
1523	}
1524
1525
1526}
1527
1528
1529
1530
1531/***************************************************************************************************
1532****************************************************************************************************
1533*****
1534*****					  MiniXMLElementCData
1535*****
1536****************************************************************************************************
1537***************************************************************************************************/
1538
1539/* The MiniXMLElementCData class is a specific extension of the MiniXMLElement class.
1540**
1541** It is used to create the special <![CDATA [ data ]]> tags and an instance in created when calling
1542** $elementObject->cdata('data');
1543**
1544** It's methods are the same as for MiniXMLElement - see those for documentation.
1545**/
1546
1547class MiniXMLElementCData extends MiniXMLElement {
1548
1549
1550
1551
1552	function MiniXMLElementCData ($contents)
1553	{
1554
1555		$this->MiniXMLElement('CDATA');
1556		if (! is_null($contents))
1557		{
1558			$this->createNode($contents, 0) ;
1559		}
1560	}
1561
1562
1563	function toStringNoWhiteSpaces ()
1564	{
1565		return $this->toString(MINIXML_NOWHITESPACES);
1566	}
1567
1568	function toStringWithWhiteSpaces ($depth=0)
1569	{
1570		return $this->toString($depth);
1571	}
1572
1573	function toString ($depth=0)
1574	{
1575		$spaces = '';
1576		if ($depth != MINIXML_NOWHITESPACES)
1577		{
1578			$spaces = $this->_spaceStr($depth);
1579		}
1580
1581		$retString = "$spaces<![CDATA[ ";
1582
1583		if (! $this->xnumChildren)
1584		{
1585			$retString .= "]]>\n";
1586			return $retString;
1587		}
1588
1589		for ( $i=0; $i < $this->xnumChildren; $i++)
1590		{
1591			$retString .= $this->xchildren[$i]->getValue();
1592
1593		}
1594
1595		$retString .= " ]]>\n";
1596
1597		return $retString;
1598	}
1599
1600
1601
1602}
1603
1604/***************************************************************************************************
1605****************************************************************************************************
1606*****
1607*****					  MiniXMLElementDocType
1608*****
1609****************************************************************************************************
1610***************************************************************************************************/
1611
1612/* The MiniXMLElementDocType class is a specific extension of the MiniXMLElement class.
1613**
1614** It is used to create the special <!DOCTYPE def [...]> tags and an instance in created when calling
1615** $elementObject->comment('');
1616**
1617** It's methods are the same as for MiniXMLElement - see those for documentation.
1618**/
1619
1620class MiniXMLElementDocType extends MiniXMLElement {
1621
1622	var $dtattr;
1623
1624	function MiniXMLElementDocType ($attr)
1625	{
1626		$this->MiniXMLElement('DOCTYPE');
1627		$this->dtattr = $attr;
1628	}
1629	function toString ($depth)
1630	{
1631		if ($depth == MINIXML_NOWHITESPACES)
1632		{
1633			return $this->toStringNoWhiteSpaces();
1634		} else {
1635			return $this->toStringWithWhiteSpaces($depth);
1636		}
1637	}
1638
1639
1640	function toStringWithWhiteSpaces ($depth=0)
1641	{
1642
1643		$spaces = $this->_spaceStr($depth);
1644
1645		$retString = "$spaces<!DOCTYPE " . $this->dtattr . " [\n";
1646
1647		if (! $this->xnumChildren)
1648		{
1649			$retString .= "]>\n";
1650			return $retString;
1651		}
1652
1653		$nextDepth = $depth + 1;
1654
1655		for ( $i=0; $i < $this->xnumChildren; $i++)
1656		{
1657
1658			$retString .= $this->xchildren[$i]->toStringWithWhiteSpaces($nextDepth);
1659
1660		}
1661
1662		$retString .= "\n$spaces]>\n";
1663
1664		return $retString;
1665	}
1666
1667
1668	function toStringNoWhiteSpaces ()
1669	{
1670
1671		$retString = "<!DOCTYPE " . $this->dtattr . " [ ";
1672
1673		if (! $this->xnumChildren)
1674		{
1675			$retString .= "]>\n";
1676			return $retString;
1677		}
1678
1679		for ( $i=0; $i < $this->xnumChildren; $i++)
1680		{
1681
1682			$retString .= $this->xchildren[$i]->toStringNoWhiteSpaces();
1683
1684		}
1685
1686		$retString .= " ]>\n";
1687
1688		return $retString;
1689	}
1690
1691
1692}
1693
1694
1695/***************************************************************************************************
1696****************************************************************************************************
1697*****
1698*****					  MiniXMLElementEntity
1699*****
1700****************************************************************************************************
1701***************************************************************************************************/
1702
1703/* The MiniXMLElementEntity class is a specific extension of the MiniXMLElement class.
1704**
1705** It is used to create the special <!ENTITY name "val">  tags and an instance in created when calling
1706** $elementObject->comment('');
1707**
1708** It's methods are the same as for MiniXMLElement - see those for documentation.
1709**/
1710
1711class MiniXMLElementEntity extends MiniXMLElement {
1712
1713
1714
1715	function MiniXMLElementEntity  ($name, $value=NULL)
1716	{
1717
1718		$this->MiniXMLElement($name);
1719
1720		if (! is_null ($value))
1721		{
1722			$this->createNode($value, 0);
1723		}
1724
1725	}
1726
1727	function toString ($depth = 0)
1728	{
1729
1730		$spaces = '';
1731		if ($depth != MINIXML_NOWHITESPACES)
1732		{
1733			$spaces = $this->_spaceStr($depth);
1734		}
1735
1736		$retString = "$spaces<!ENTITY " . $this->name();
1737
1738		if (! $this->xnumChildren)
1739		{
1740			$retString .= ">\n";
1741			return $retString;
1742		}
1743
1744		 $nextDepth = ($depth == MINIXML_NOWHITESPACES) ? MINIXML_NOWHITESPACES
1745										: $depth + 1;
1746		$retString .= '"';
1747		for ( $i=0; $i < $this->xnumChildren; $i++)
1748		{
1749
1750			$retString .= $this->xchildren[$i]->toString(MINIXML_NOWHITESPACES);
1751
1752		}
1753		$retString .= '"';
1754		$retString .= " >\n";
1755
1756		return $retString;
1757	}
1758
1759
1760	function toStringNoWhiteSpaces ()
1761	{
1762		return $this->toString(MINIXML_NOWHITESPACES);
1763	}
1764
1765	function toStringWithWhiteSpaces ($depth=0)
1766	{
1767		return $this->toString($depth);
1768	}
1769
1770
1771}