Source code for file /joomla/utilities/simplexml.php
Documentation is available at simplexml.php
* @version $Id: simplexml.php 6673 2007-02-19 05:12:48Z louis $
* @package Joomla.Framework
* @copyright Copyright (C) 2005 - 2007 Open Source Matters. All rights reserved.
* @license GNU/GPL, see LICENSE.php
* Joomla! is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
// Check to ensure this file is within the rest of the framework
* SimpleXML implementation.
* The XML Parser extension (expat) is required to use JSimpleXML.
* The class provides a pure PHP4 implementation of the PHP5
* interface SimpleXML. As with PHP5's SimpleXML it is what it says:
* simple. Nevertheless, it is an easy way to deal with XML data,
* especially for read only access.
* Because it's not possible to use the PHP5 ArrayIterator interface
* with PHP4 there are some differences between this implementation
* <li>The access to the root node has to be explicit in
* JSimpleXML, not implicit as with PHP5. Write
* $xml->document->node instead of $xml->node</li>
* <li>You cannot acces CDATA using array syntax. Use the method data() instead</li>
* <li>You cannot access attributes directly with array syntax. use attributes()
* <li>Comments are ignored.</li>
* <li>Last and least, this is not as fast as PHP5 SimpleXML--it is pure PHP4.</li>
* <?xml version="1.0" encoding="utf-8" standalon="yes"?>
* <child gender="m">Tom Foo</child>
* <child gender="f">Tamara Bar</child>
* // read and write a document
* $xml->loadFile('simple.xml');
* // access a given node's CDATA
* print $xml->root->node->child[0]->data(); // Tom Foo
* $attr = $xml->root->node->child[1]->attributes();
* print $attr['gender']; // f
* foreach( $xml->root->node->children() as $child ) {
* Note: JSimpleXML cannot be used to access sophisticated XML doctypes
* using datatype ANY (e.g. XHTML). With a DOM implementation you can
* @package Joomla.Framework
return false; //TODO throw warning
//Create the parser resource and make sure both versions of PHP autodetect the format.
foreach( $options as $option =>
$value ) {
* Interprets a string of XML into an object
* This function will take the well-formed xml string data and return an object of class
* JSimpleXMLElement with properties containing the data held within the xml document.
* If any errors occur, it returns FALSE.
* @param string Well-formed xml string data
* @param string currently ignored
* @return object JSimpleXMLElement
* Interprets an XML file into an object
* This function will convert the well-formed XML document in the file specified by filename
* to an object of class JSimpleXMLElement. If any errors occur during file access or
* interpretation, the function returns FALSE.
* @param string Path to xml file containing a well-formed XML document
* @param string currently ignored
* @return boolean True if successful, false if file empty
function loadFile($path, $classname =
null)
//Get the XML document loaded into a variable
* Get a JSimpleXMLElement object from a DOM node.
* This function takes a node of a DOM document and makes it into a JSimpleXML node.
* This new object can then be used as a native JSimpleXML element. If any errors occur,
* @param string DOM document
* @param string currently ignored
* @return object JSimpleXMLElement
function importDom($node, $classname =
null) {
* @return resource XML parser resource handle
* @param resource XML parser resource handle
* Start parsing an XML document
* Parses an XML document. The handlers for the configured events are called as many times as necessary.
* @param $xml string data to parse
* Handles an XML parsing error
* @param int $code XML Error Code
* @param int $line Line on which the error happened
* @param int $col Column on which the error happened
* Gets the reference to the current direct parent
foreach($this->_stack as $stack) {
return rtrim($return, '->');
* Handler function for the start of a tag
* @param resource $parser
//Make the name of the tag lower case
//Check to see if tag is root-level
//If so, set the document as the current tag
//And start out the stack with the document tag
$this->_stack =
array('document');
//If it isn't root level, use the stack to find the parent
//Get the name which points to the current direct parent, relative to $this
eval
('$this->'.
$parent.
'->addChild($name, $attrs, '.
count($this->_stack).
');');
eval
('$this->_stack[] = $name.\'[\'.(count($this->'.
$parent.
'->'.
$name.
') - 1).\']\';');
* Handler function for the end of a tag
* @param resource $parser
//Update stack by removing the end value from it as the parent
* Handler function for the character data within a tag
* @param resource $parser
//Get the reference to the current parent object
eval
('$this->'.
$tag.
'->_data .= trim($data);');
* This object stores all of the direct children of itself in the $children array.
* They are also stored by type as arrays. So, if, for example, this tag had 2 <font>
* tags as children, there would be a class member called $font created as an array.
* $font[0] would be the first font tag, and $font[1] would be the second.
* To loop through all of the direct children of this object, the $children member
* To loop through all of the direct children of a specific tag for this object, it
* is probably easier to use the arrays of the specific tag names, as explained above.
* @package Joomla.Framework
* Array with the attributes of this XML element
* The name of the element
* The data the element contains
* Array of references to the objects of all direct children of this XML object
* The level of this XML element
* Constructor, sets up all the default values
* @return JSimpleXMLElement
function __construct($name, $attrs =
array(), $level =
0)
//Make the keys of the attr array lower case, and store the value
//Make the name lower case and store the value
* Get the name of the element
* Get the an attribute of the element
* @param string $attribute The name of the attribute
* @return mixed If an attribute is given will return the attribute if it exist.
* If no attribute is given will return the complete attributes array
* Get the data of the element
* Set the data of the element
* Get the children of the element
* Get the level of the element
* Adds an attribute to the element
//add the attribute to the element, override if it already exists
* Removes an attribute from the element
* Adds a direct child to the element
function addChild($name, $attrs, $level)
//If there is no array already set for the tag name being added,
//create an empty array for it
//Create the child object itself
//Add the reference of it to the end of an array member named for the elements name
$this->{$name}[] =
& $child;
//Add the reference to the children array member
for ($i=
0,$n=
count($this->{$name});$i<
$n;$i++
)
if ($this->{$name}[$i] ==
$child) {
unset
($this->{$name}[$i]);
* Get an element in the document by / separated path
* @param string $path The / separated path to the element
* @return object JSimpleXMLElement
foreach ($parts as $node)
if ($child->_name ==
$node)
function map($callback, $args=
array())
* Return a well-formed XML string based on SimpleXML element
function asXML($whitespace=
true)
//Start a new line, indent by the number indicated in $this->level, add a <, and add the name of the tag
//For each attribute, add attr="value"
$out .=
' '.
$attr.
'="'.
$value.
'"';
//If there are no children and it contains no data, end it off with a />
//Close off the start tag
//For each child, call the asXML function (this will ensure that all children are added recursively)
$out .=
$child->asXML($whitespace);
//Add the newline and indentation to go along with the close tag
//If there is data, close off the start tag and add the data
elseif(!empty($this->_data))
$out .=
'>'.
$this->_data;
$out .=
'</'.
$this->_name.
'>';
//Return the final output