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