9  * @author     Greg Beaver <cellog@php.net>
 
  10  * @author     Stephan Schmidt (original XML_Unserializer code)
 
  11  * @copyright  1997-2009 The Authors
 
  12  * @license   http://opensource.org/licenses/bsd-license New BSD License
 
  13  * @version    CVS: $Id: XMLParser.php 313023 2011-07-06 19:17:11Z dufuz $
 
  14  * @link       http://pear.php.net/package/PEAR
 
  15  * @since      File available since Release 1.4.0a1
 
  19  * Parser for any xml file
 
  22  * @author    Greg Beaver <cellog@php.net>
 
  23  * @author    Stephan Schmidt (original XML_Unserializer code)
 
  24  * @copyright 1997-2009 The Authors
 
  25  * @license   http://opensource.org/licenses/bsd-license New BSD License
 
  26  * @version   Release: 1.9.4
 
  27  * @link      http://pear.php.net/package/PEAR
 
  28  * @since     Class available since Release 1.4.0a1
 
  34      * @var string $_serializedData
 
  36     var $_unserializedData = null;
 
  39      * name of the root tag
 
  45      * stack for all data that is found
 
  46      * @var array    $_dataStack
 
  48     var $_dataStack = array();
 
  51      * stack for all values that are generated
 
  52      * @var array    $_valStack
 
  54     var $_valStack = array();
 
  63      * The XML encoding to use
 
  64      * @var string $encoding
 
  66     var $encoding = 'ISO-8859-1';
 
  73         return $this->_unserializedData;
 
  77      * @param string xml content
 
  78      * @return true|PEAR_Error
 
  82         if (!extension_loaded('xml')) {
 
  83             include_once 'PEAR.php';
 
  84             return PEAR::raiseError("XML Extension not found", 1);
 
  86         $this->_dataStack =  $this->_valStack = array();
 
  90             strpos($data, 'encoding="UTF-8"')
 
  91             || strpos($data, 'encoding="utf-8"')
 
  92             || strpos($data, "encoding='UTF-8'")
 
  93             || strpos($data, "encoding='utf-8'")
 
  95             $this->encoding = 'UTF-8';
 
  98         if (version_compare(phpversion(), '5.0.0', 'lt') && $this->encoding == 'UTF-8') {
 
  99             $data = utf8_decode($data);
 
 100             $this->encoding = 'ISO-8859-1';
 
 103         $xp = xml_parser_create($this->encoding);
 
 104         xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, 0);
 
 105         xml_set_object($xp, $this);
 
 106         xml_set_element_handler($xp, 'startHandler', 'endHandler');
 
 107         xml_set_character_data_handler($xp, 'cdataHandler');
 
 108         if (!xml_parse($xp, $data)) {
 
 109             $msg = xml_error_string(xml_get_error_code($xp));
 
 110             $line = xml_get_current_line_number($xp);
 
 111             xml_parser_free($xp);
 
 112             include_once 'PEAR.php';
 
 113             return PEAR::raiseError("XML Error: '$msg' on line '$line'", 2);
 
 115         xml_parser_free($xp);
 
 120      * Start element handler for XML parser
 
 123      * @param  object $parser  XML parser object
 
 124      * @param  string $element XML element
 
 125      * @param  array  $attribs attributes of XML tag
 
 128     function startHandler($parser, $element, $attribs)
 
 131         $this->_dataStack[$this->_depth] = null;
 
 137             'childrenKeys' => array(),
 
 138             'aggregKeys'   => array()
 
 141         if (count($attribs) > 0) {
 
 142             $val['children'] = array();
 
 143             $val['type'] = 'array';
 
 144             $val['children']['attribs'] = $attribs;
 
 147         array_push($this->_valStack, $val);
 
 153      * @param string $data
 
 154      * @param string $element element name
 
 156     function postProcess($data, $element)
 
 162      * End element handler for XML parser
 
 165      * @param  object XML parser object
 
 169     function endHandler($parser, $element)
 
 171         $value = array_pop($this->_valStack);
 
 172         $data  = $this->postProcess($this->_dataStack[$this->_depth], $element);
 
 174         // adjust type of the value
 
 175         switch (strtolower($value['type'])) {
 
 176             // unserialize an array
 
 179                     $value['children']['_content'] = $data;
 
 182                 $value['value'] = isset($value['children']) ? $value['children'] : array();
 
 186              * unserialize a null value
 
 193              * unserialize any scalar value
 
 196                 settype($data, $value['type']);
 
 197                 $value['value'] = $data;
 
 201         $parent = array_pop($this->_valStack);
 
 202         if ($parent === null) {
 
 203             $this->_unserializedData = &$value['value'];
 
 204             $this->_root = &$value['name'];
 
 208         // parent has to be an array
 
 209         if (!isset($parent['children']) || !is_array($parent['children'])) {
 
 210             $parent['children'] = array();
 
 211             if ($parent['type'] != 'array') {
 
 212                 $parent['type'] = 'array';
 
 216         if (!empty($value['name'])) {
 
 217             // there already has been a tag with this name
 
 218             if (in_array($value['name'], $parent['childrenKeys'])) {
 
 219                 // no aggregate has been created for this tag
 
 220                 if (!in_array($value['name'], $parent['aggregKeys'])) {
 
 221                     if (isset($parent['children'][$value['name']])) {
 
 222                         $parent['children'][$value['name']] = array($parent['children'][$value['name']]);
 
 224                         $parent['children'][$value['name']] = array();
 
 226                     array_push($parent['aggregKeys'], $value['name']);
 
 228                 array_push($parent['children'][$value['name']], $value['value']);
 
 230                 $parent['children'][$value['name']] = &$value['value'];
 
 231                 array_push($parent['childrenKeys'], $value['name']);
 
 234             array_push($parent['children'],$value['value']);
 
 236         array_push($this->_valStack, $parent);
 
 242      * Handler for character data
 
 245      * @param  object XML parser object
 
 246      * @param  string CDATA
 
 249     function cdataHandler($parser, $cdata)
 
 251         $this->_dataStack[$this->_depth] .= $cdata;