Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
341 jpm 1
<?php
2
//
3
// +----------------------------------------------------------------------+
4
// | PHP Version 4                                                        |
5
// +----------------------------------------------------------------------+
6
// | Copyright (c) 1997-2004 The PHP Group                                |
7
// +----------------------------------------------------------------------+
8
// | This source file is subject to version 3.0 of the PHP license,       |
9
// | that is bundled with this package in the file LICENSE, and is        |
10
// | available at through the world-wide-web at                           |
11
// | http://www.php.net/license/3_0.txt.                                  |
12
// | If you did not receive a copy of the PHP license and are unable to   |
13
// | obtain it through the world-wide-web, please send a note to          |
14
// | license@php.net so we can mail you a copy immediately.               |
15
// +----------------------------------------------------------------------+
16
// | Author: Stephan Schmidt <schst@php-tools.net>                        |
17
// +----------------------------------------------------------------------+
18
//
19
// $Id: Simple.php,v 1.1 2005-04-18 16:13:31 jpm Exp $
20
 
21
/**
22
 * Simple XML parser class.
23
 *
24
 * This class is a simplified version of XML_Parser.
25
 * In most XML applications the real action is executed,
26
 * when a closing tag is found.
27
 *
28
 * XML_Parser_Simple allows you to just implement one callback
29
 * for each tag that will receive the tag with its attributes
30
 * and CData
31
 *
32
 * @category XML
33
 * @package XML_Parser
34
 * @author  Stephan Schmidt <schst@php-tools.net>
35
 */
36
 
37
/**
38
 * built on XML_Parser
39
 */
40
require_once 'XML/Parser.php';
41
 
42
/**
43
 * Simple XML parser class.
44
 *
45
 * This class is a simplified version of XML_Parser.
46
 * In most XML applications the real action is executed,
47
 * when a closing tag is found.
48
 *
49
 * XML_Parser_Simple allows you to just implement one callback
50
 * for each tag that will receive the tag with its attributes
51
 * and CData.
52
 *
53
 * <code>
54
 * require_once '../Parser/Simple.php';
55
 *
56
 * class myParser extends XML_Parser_Simple
57
 * {
58
 *     function myParser()
59
 *     {
60
 *        $this->XML_Parser_Simple();
61
 *      }
62
 *
63
 *    function handleElement($name, $attribs, $data)
64
 *     {
65
 *         printf('handle %s<br>', $name);
66
 *     }
67
 * }
68
 *
69
 * $p = &new myParser();
70
 *
71
 * $result = $p->setInputFile('myDoc.xml');
72
 * $result = $p->parse();
73
 * </code>
74
 *
75
 * @category XML
76
 * @package XML_Parser
77
 * @author  Stephan Schmidt <schst@php-tools.net>
78
 */
79
class XML_Parser_Simple extends XML_Parser
80
{
81
   /**
82
    * element stack
83
    *
84
    * @access   private
85
    * @var      array
86
    */
87
    var $_elStack = array();
88
 
89
   /**
90
    * all character data
91
    *
92
    * @access   private
93
    * @var      array
94
    */
95
    var $_data = array();
96
 
97
   /**
98
    * element depth
99
    *
100
    * @access   private
101
    * @var      integer
102
    */
103
    var $_depth = 0;
104
 
105
    /**
106
     * Mapping from expat handler function to class method.
107
     *
108
     * @var  array
109
     */
110
    var $handler = array(
111
        'default_handler'                   => 'defaultHandler',
112
        'processing_instruction_handler'    => 'piHandler',
113
        'unparsed_entity_decl_handler'      => 'unparsedHandler',
114
        'notation_decl_handler'             => 'notationHandler',
115
        'external_entity_ref_handler'       => 'entityrefHandler'
116
    );
117
 
118
    /**
119
     * Creates an XML parser.
120
     *
121
     * This is needed for PHP4 compatibility, it will
122
     * call the constructor, when a new instance is created.
123
     *
124
     * @param string $srcenc source charset encoding, use NULL (default) to use
125
     *                       whatever the document specifies
126
     * @param string $mode   how this parser object should work, "event" for
127
     *                       handleElement(), "func" to have it call functions
128
     *                       named after elements (handleElement_$name())
129
     * @param string $tgenc  a valid target encoding
130
     */
131
    function XML_Parser_Simple($srcenc = null, $mode = 'event', $tgtenc = null)
132
    {
133
        $this->XML_Parser($srcenc, $mode, $tgtenc);
134
    }
135
 
136
    /**
137
     * inits the handlers
138
     *
139
     * @access  private
140
     */
141
    function _initHandlers()
142
    {
143
        if (!is_object($this->_handlerObj)) {
144
            $this->_handlerObj = &$this;
145
        }
146
 
147
        if ($this->mode != 'func' && $this->mode != 'event') {
148
            return $this->raiseError('Unsupported mode given', XML_PARSER_ERROR_UNSUPPORTED_MODE);
149
        }
150
        xml_set_object($this->parser, $this->_handlerObj);
151
 
152
        xml_set_element_handler($this->parser, array(&$this, 'startHandler'), array(&$this, 'endHandler'));
153
        xml_set_character_data_handler($this->parser, array(&$this, 'cdataHandler'));
154
 
155
        /**
156
         * set additional handlers for character data, entities, etc.
157
         */
158
        foreach ($this->handler as $xml_func => $method) {
159
            if (method_exists($this->_handlerObj, $method)) {
160
                $xml_func = 'xml_set_' . $xml_func;
161
                $xml_func($this->parser, $method);
162
            }
163
		}
164
    }
165
 
166
    /**
167
     * Reset the parser.
168
     *
169
     * This allows you to use one parser instance
170
     * to parse multiple XML documents.
171
     *
172
     * @access   public
173
     * @return   boolean|object     true on success, PEAR_Error otherwise
174
     */
175
    function reset()
176
    {
177
        $this->_elStack = array();
178
        $this->_data    = array();
179
        $this->_depth   = 0;
180
 
181
        $result = $this->_create();
182
        if ($this->isError( $result )) {
183
            return $result;
184
        }
185
        return true;
186
    }
187
 
188
   /**
189
    * start handler
190
    *
191
    * Pushes attributes and tagname onto a stack
192
    *
193
    * @access   private
194
    * @final
195
    * @param    resource    xml parser resource
196
    * @param    string      element name
197
    * @param    array       attributes
198
    */
199
    function startHandler($xp, $elem, &$attribs)
200
    {
201
        array_push($this->_elStack, array(
202
                                            'name'    => $elem,
203
                                            'attribs' => $attribs
204
                                        )
205
                  );
206
        $this->_depth++;
207
        $this->_data[$this->_depth] = '';
208
    }
209
 
210
   /**
211
    * end handler
212
    *
213
    * Pulls attributes and tagname from a stack
214
    *
215
    * @access   private
216
    * @final
217
    * @param    resource    xml parser resource
218
    * @param    string      element name
219
    */
220
    function endHandler($xp, $elem)
221
    {
222
        $el   = array_pop($this->_elStack);
223
        $data = $this->_data[$this->_depth];
224
        $this->_depth--;
225
 
226
        switch ($this->mode) {
227
            case 'event':
228
                $this->_handlerObj->handleElement($el['name'], $el['attribs'], $data);
229
                break;
230
            case 'func':
231
                $func = 'handleElement_' . $elem;
232
                if (strchr($func, '.')) {
233
                    $func = str_replace('.', '_', $func);
234
                }
235
                if (method_exists($this->_handlerObj, $func)) {
236
                    call_user_func(array(&$this->_handlerObj, $func), $el['name'], $el['attribs'], $data);
237
                }
238
                break;
239
        }
240
    }
241
 
242
   /**
243
    * handle character data
244
    *
245
    * @access   private
246
    * @final
247
    * @param    resource    xml parser resource
248
    * @param    string      data
249
    */
250
    function cdataHandler($xp, $data)
251
    {
252
        $this->_data[$this->_depth] .= $data;
253
    }
254
 
255
   /**
256
    * handle a tag
257
    *
258
    * Implement this in your parser
259
    *
260
    * @access   public
261
    * @abstract
262
    * @param    string      element name
263
    * @param    array       attributes
264
    * @param    string      character data
265
    */
266
    function handleElement($name, $attribs, $data)
267
    {
268
    }
269
 
270
   /**
271
    * get the current tag depth
272
    *
273
    * The root tag is in depth 0.
274
    *
275
    * @access   public
276
    * @return   integer
277
    */
278
    function getCurrentDepth()
279
    {
280
        return $this->_depth;
281
    }
282
 
283
   /**
284
    * add some string to the current ddata.
285
    *
286
    * This is commonly needed, when a document is parsed recursively.
287
    *
288
    * @access   public
289
    * @param    string      data to add
290
    * @return   void
291
    */
292
    function addToData( $data )
293
    {
294
        $this->_data[$this->_depth] .= $data;
295
    }
296
}
297
?>