home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / PEAR / XMLParser.php < prev   
Encoding:
PHP Script  |  2005-12-02  |  7.8 KB  |  261 lines

  1. <?php
  2. /**
  3.  * PEAR_FTP
  4.  *
  5.  * PHP versions 4 and 5
  6.  *
  7.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  8.  * that is available through the world-wide-web at the following URI:
  9.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10.  * the PHP License and are unable to obtain it through the web, please
  11.  * send a note to license@php.net so we can mail you a copy immediately.
  12.  *
  13.  * @category   pear
  14.  * @package    PEAR
  15.  * @author     Greg Beaver <cellog@php.net>
  16.  * @author     Stephan Schmidt (original XML_Unserializer code)
  17.  * @copyright  1997-2005 The PHP Group
  18.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  19.  * @version    CVS: $Id: XMLParser.php,v 1.10 2005/09/25 03:49:02 cellog Exp $
  20.  * @link       http://pear.php.net/package/PEAR
  21.  * @since      File available since Release 1.4.0a1
  22.  */
  23.  
  24. /**
  25.  * Parser for any xml file
  26.  * @category   pear
  27.  * @package    PEAR
  28.  * @author     Greg Beaver <cellog@php.net>
  29.  * @author     Stephan Schmidt (original XML_Unserializer code)
  30.  * @copyright  1997-2005 The PHP Group
  31.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  32.  * @version    Release: 1.4.5
  33.  * @link       http://pear.php.net/package/PEAR
  34.  * @since      Class available since Release 1.4.0a1
  35.  */
  36. class PEAR_XMLParser
  37. {
  38.     /**
  39.      * unserilialized data
  40.      * @var string $_serializedData
  41.      */
  42.     var $_unserializedData = null;
  43.  
  44.     /**
  45.      * name of the root tag
  46.      * @var string $_root
  47.      */
  48.     var $_root = null;
  49.  
  50.     /**
  51.      * stack for all data that is found
  52.      * @var array    $_dataStack
  53.      */
  54.     var $_dataStack  =   array();
  55.  
  56.     /**
  57.      * stack for all values that are generated
  58.      * @var array    $_valStack
  59.      */
  60.     var $_valStack  =   array();
  61.  
  62.     /**
  63.      * current tag depth
  64.      * @var int    $_depth
  65.      */
  66.     var $_depth = 0;
  67.  
  68.     /**
  69.      * @return array
  70.      */
  71.     function getData()
  72.     {
  73.         return $this->_unserializedData;
  74.     }
  75.  
  76.     /**
  77.      * @param string xml content
  78.      * @return true|PEAR_Error
  79.      */
  80.     function parse($data)
  81.     {
  82.         if (!extension_loaded('xml')) {
  83.             include_once 'PEAR.php';
  84.             return PEAR::raiseError("XML Extension not found", 1);
  85.         }
  86.         $this->_valStack = array();
  87.         $this->_dataStack = array();
  88.         $this->_depth = 0;
  89.  
  90.         if (version_compare(phpversion(), '5.0.0', 'lt')) {
  91.             if (strpos($data, 'encoding="UTF-8"')) {
  92.                 $data = utf8_decode($data);
  93.             }
  94.             $xp = @xml_parser_create('ISO-8859-1');
  95.         } else {
  96.             if (strpos($data, 'encoding="UTF-8"')) {
  97.                 $xp = @xml_parser_create('UTF-8');
  98.             } else {
  99.                 $xp = @xml_parser_create('ISO-8859-1');
  100.             }
  101.         }
  102.         xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, 0);
  103.         xml_set_object($xp, $this);
  104.         xml_set_element_handler($xp, 'startHandler', 'endHandler');
  105.         xml_set_character_data_handler($xp, 'cdataHandler');
  106.         if (!xml_parse($xp, $data)) {
  107.             $msg = xml_error_string(xml_get_error_code($xp));
  108.             $line = xml_get_current_line_number($xp);
  109.             xml_parser_free($xp);
  110.             include_once 'PEAR.php';
  111.             return PEAR::raiseError("XML Error: '$msg' on line '$line'", 2);
  112.         }
  113.         xml_parser_free($xp);
  114.         return true;
  115.     }
  116.  
  117.     /**
  118.      * Start element handler for XML parser
  119.      *
  120.      * @access private
  121.      * @param  object $parser  XML parser object
  122.      * @param  string $element XML element
  123.      * @param  array  $attribs attributes of XML tag
  124.      * @return void
  125.      */
  126.     function startHandler($parser, $element, $attribs)
  127.     {
  128.         $type = 'string';
  129.  
  130.         $this->_depth++;
  131.         $this->_dataStack[$this->_depth] = null;
  132.  
  133.         $val = array(
  134.                      'name'         => $element,
  135.                      'value'        => null,
  136.                      'type'         => $type,
  137.                      'childrenKeys' => array(),
  138.                      'aggregKeys'   => array()
  139.                     );
  140.  
  141.         if (count($attribs) > 0) {
  142.             $val['children'] = array();
  143.             $val['type'] = 'array';
  144.  
  145.             $val['children']['attribs'] = $attribs;
  146.  
  147.         }
  148.  
  149.         array_push($this->_valStack, $val);
  150.     }
  151.  
  152.     /**
  153.      * post-process data
  154.      *
  155.      * @param string $data
  156.      * @param string $element element name
  157.      */
  158.     function postProcess($data, $element)
  159.     {
  160.         return trim($data);
  161.     }
  162.  
  163.     /**
  164.      * End element handler for XML parser
  165.      *
  166.      * @access private
  167.      * @param  object XML parser object
  168.      * @param  string
  169.      * @return void
  170.      */
  171.     function endHandler($parser, $element)
  172.     {
  173.         $value = array_pop($this->_valStack);
  174.         $data  = $this->postProcess($this->_dataStack[$this->_depth], $element);
  175.  
  176.         // adjust type of the value
  177.         switch(strtolower($value['type'])) {
  178.  
  179.             /*
  180.              * unserialize an array
  181.              */
  182.             case 'array':
  183.                 if ($data !== '') {
  184.                     $value['children']['_content'] = $data;
  185.                 }
  186.                 if (isset($value['children'])) {
  187.                     $value['value'] = $value['children'];
  188.                 } else {
  189.                     $value['value'] = array();
  190.                 }
  191.                 break;
  192.  
  193.             /*
  194.              * unserialize a null value
  195.              */
  196.             case 'null':
  197.                 $data = null;
  198.                 break;
  199.  
  200.             /*
  201.              * unserialize any scalar value
  202.              */
  203.             default:
  204.                 settype($data, $value['type']);
  205.                 $value['value'] = $data;
  206.                 break;
  207.         }
  208.         $parent = array_pop($this->_valStack);
  209.         if ($parent === null) {
  210.             $this->_unserializedData = &$value['value'];
  211.             $this->_root = &$value['name'];
  212.             return true;
  213.         } else {
  214.             // parent has to be an array
  215.             if (!isset($parent['children']) || !is_array($parent['children'])) {
  216.                 $parent['children'] = array();
  217.                 if ($parent['type'] != 'array') {
  218.                     $parent['type'] = 'array';
  219.                 }
  220.             }
  221.  
  222.             if (!empty($value['name'])) {
  223.                 // there already has been a tag with this name
  224.                 if (in_array($value['name'], $parent['childrenKeys'])) {
  225.                     // no aggregate has been created for this tag
  226.                     if (!in_array($value['name'], $parent['aggregKeys'])) {
  227.                         if (isset($parent['children'][$value['name']])) {
  228.                             $parent['children'][$value['name']] = array($parent['children'][$value['name']]);
  229.                         } else {
  230.                             $parent['children'][$value['name']] = array();
  231.                         }
  232.                         array_push($parent['aggregKeys'], $value['name']);
  233.                     }
  234.                     array_push($parent['children'][$value['name']], $value['value']);
  235.                 } else {
  236.                     $parent['children'][$value['name']] = &$value['value'];
  237.                     array_push($parent['childrenKeys'], $value['name']);
  238.                 }
  239.             } else {
  240.                 array_push($parent['children'],$value['value']);
  241.             }
  242.             array_push($this->_valStack, $parent);
  243.         }
  244.  
  245.         $this->_depth--;
  246.     }
  247.  
  248.     /**
  249.      * Handler for character data
  250.      *
  251.      * @access private
  252.      * @param  object XML parser object
  253.      * @param  string CDATA
  254.      * @return void
  255.      */
  256.     function cdataHandler($parser, $cdata)
  257.     {
  258.         $this->_dataStack[$this->_depth] .= $cdata;
  259.     }
  260. }
  261. ?>