Subversion Repositories Applications.gtt

Rev

Rev 94 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
94 jpm 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-2006 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.12 2006/03/27 04:39:03 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-2006 The PHP Group
31
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
32
 * @version    Release: 1.5.1
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
?>