| 
 | 1 | +<?php  | 
 | 2 | + | 
 | 3 | +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */  | 
 | 4 | + | 
 | 5 | +/**  | 
 | 6 | + * XML_Parser  | 
 | 7 | + *  | 
 | 8 | + * XML Parser's Simple parser class   | 
 | 9 | + *  | 
 | 10 | + * PHP versions 4 and 5  | 
 | 11 | + *  | 
 | 12 | + * LICENSE:  | 
 | 13 | + *  | 
 | 14 | + * Copyright (c) 2002-2008 The PHP Group  | 
 | 15 | + * All rights reserved.  | 
 | 16 | + *  | 
 | 17 | + * Redistribution and use in source and binary forms, with or without  | 
 | 18 | + * modification, are permitted provided that the following conditions  | 
 | 19 | + * are met:  | 
 | 20 | + *  | 
 | 21 | + *    * Redistributions of source code must retain the above copyright  | 
 | 22 | + *      notice, this list of conditions and the following disclaimer.  | 
 | 23 | + *    * Redistributions in binary form must reproduce the above copyright  | 
 | 24 | + *      notice, this list of conditions and the following disclaimer in the  | 
 | 25 | + *      documentation and/or other materials provided with the distribution.  | 
 | 26 | + *    * The name of the author may not be used to endorse or promote products  | 
 | 27 | + *      derived from this software without specific prior written permission.  | 
 | 28 | + *  | 
 | 29 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS  | 
 | 30 | + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  | 
 | 31 | + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  | 
 | 32 | + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR  | 
 | 33 | + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  | 
 | 34 | + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  | 
 | 35 | + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR  | 
 | 36 | + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY  | 
 | 37 | + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  | 
 | 38 | + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS  | 
 | 39 | + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  | 
 | 40 | + *  | 
 | 41 | + * @category  XML  | 
 | 42 | + * @package   XML_Parser  | 
 | 43 | + * @author    Stephan Schmidt <[email protected]>  | 
 | 44 | + * @copyright 2004-2008 Stephan Schmidt <[email protected]>  | 
 | 45 | + * @license   http://opensource.org/licenses/bsd-license New BSD License  | 
 | 46 | + * @version   CVS: $Id$  | 
 | 47 | + * @link      http://pear.php.net/package/XML_Parser  | 
 | 48 | + */  | 
 | 49 | + | 
 | 50 | +/**  | 
 | 51 | + * built on XML_Parser  | 
 | 52 | + */  | 
 | 53 | +require_once 'XML/Parser.php';  | 
 | 54 | + | 
 | 55 | +/**  | 
 | 56 | + * Simple XML parser class.  | 
 | 57 | + *  | 
 | 58 | + * This class is a simplified version of XML_Parser.  | 
 | 59 | + * In most XML applications the real action is executed,  | 
 | 60 | + * when a closing tag is found.  | 
 | 61 | + *  | 
 | 62 | + * XML_Parser_Simple allows you to just implement one callback  | 
 | 63 | + * for each tag that will receive the tag with its attributes  | 
 | 64 | + * and CData.  | 
 | 65 | + *  | 
 | 66 | + * <code>  | 
 | 67 | + * require_once '../Parser/Simple.php';  | 
 | 68 | + *  | 
 | 69 | + * class myParser extends XML_Parser_Simple  | 
 | 70 | + * {  | 
 | 71 | + *     function myParser()  | 
 | 72 | + *     {  | 
 | 73 | + *        $this->XML_Parser_Simple();  | 
 | 74 | + *      }  | 
 | 75 | + *   | 
 | 76 | + *    function handleElement($name, $attribs, $data)  | 
 | 77 | + *     {  | 
 | 78 | + *         printf('handle %s<br>', $name);  | 
 | 79 | + *     }  | 
 | 80 | + * }  | 
 | 81 | + *   | 
 | 82 | + * $p = &new myParser();  | 
 | 83 | + *   | 
 | 84 | + * $result = $p->setInputFile('myDoc.xml');  | 
 | 85 | + * $result = $p->parse();  | 
 | 86 | + * </code>  | 
 | 87 | + *  | 
 | 88 | + * @category  XML  | 
 | 89 | + * @package   XML_Parser  | 
 | 90 | + * @author    Stephan Schmidt <[email protected]>  | 
 | 91 | + * @copyright 2004-2008 The PHP Group  | 
 | 92 | + * @license   http://opensource.org/licenses/bsd-license New BSD License  | 
 | 93 | + * @version   Release: @package_version@  | 
 | 94 | + * @link      http://pear.php.net/package/XML_Parser  | 
 | 95 | + */  | 
 | 96 | +class XML_Parser_Simple extends XML_Parser  | 
 | 97 | +{  | 
 | 98 | +    /**  | 
 | 99 | +     * element stack  | 
 | 100 | +     *  | 
 | 101 | +     * @access   private  | 
 | 102 | +     * @var      array  | 
 | 103 | +     */  | 
 | 104 | +    var $_elStack = array();  | 
 | 105 | + | 
 | 106 | +    /**  | 
 | 107 | +     * all character data  | 
 | 108 | +     *  | 
 | 109 | +     * @access   private  | 
 | 110 | +     * @var      array  | 
 | 111 | +     */  | 
 | 112 | +    var $_data = array();  | 
 | 113 | + | 
 | 114 | +    /**  | 
 | 115 | +     * element depth  | 
 | 116 | +     *  | 
 | 117 | +     * @access   private  | 
 | 118 | +     * @var      integer  | 
 | 119 | +     */  | 
 | 120 | +    var $_depth = 0;  | 
 | 121 | + | 
 | 122 | +    /**  | 
 | 123 | +     * Mapping from expat handler function to class method.  | 
 | 124 | +     *  | 
 | 125 | +     * @var  array  | 
 | 126 | +     */  | 
 | 127 | +    var $handler = array(  | 
 | 128 | +        'default_handler'                   => 'defaultHandler',  | 
 | 129 | +        'processing_instruction_handler'    => 'piHandler',  | 
 | 130 | +        'unparsed_entity_decl_handler'      => 'unparsedHandler',  | 
 | 131 | +        'notation_decl_handler'             => 'notationHandler',  | 
 | 132 | +        'external_entity_ref_handler'       => 'entityrefHandler'  | 
 | 133 | +    );  | 
 | 134 | +      | 
 | 135 | +    /**  | 
 | 136 | +     * Creates an XML parser.  | 
 | 137 | +     *  | 
 | 138 | +     * This is needed for PHP4 compatibility, it will  | 
 | 139 | +     * call the constructor, when a new instance is created.  | 
 | 140 | +     *  | 
 | 141 | +     * @param string $srcenc source charset encoding, use NULL (default) to use  | 
 | 142 | +     *                       whatever the document specifies  | 
 | 143 | +     * @param string $mode   how this parser object should work, "event" for  | 
 | 144 | +     *                       handleElement(), "func" to have it call functions  | 
 | 145 | +     *                       named after elements (handleElement_$name())  | 
 | 146 | +     * @param string $tgtenc a valid target encoding  | 
 | 147 | +     */  | 
 | 148 | +    function XML_Parser_Simple($srcenc = null, $mode = 'event', $tgtenc = null)  | 
 | 149 | +    {  | 
 | 150 | +        $this->XML_Parser($srcenc, $mode, $tgtenc);  | 
 | 151 | +    }  | 
 | 152 | + | 
 | 153 | +    /**  | 
 | 154 | +     * inits the handlers  | 
 | 155 | +     *  | 
 | 156 | +     * @return mixed  | 
 | 157 | +     * @access private  | 
 | 158 | +     */  | 
 | 159 | +    function _initHandlers()  | 
 | 160 | +    {  | 
 | 161 | +        if (!is_object($this->_handlerObj)) {  | 
 | 162 | +            $this->_handlerObj = &$this;  | 
 | 163 | +        }  | 
 | 164 | + | 
 | 165 | +        if ($this->mode != 'func' && $this->mode != 'event') {  | 
 | 166 | +            return $this->raiseError('Unsupported mode given',   | 
 | 167 | +                XML_PARSER_ERROR_UNSUPPORTED_MODE);  | 
 | 168 | +        }  | 
 | 169 | +        xml_set_object($this->parser, $this->_handlerObj);  | 
 | 170 | + | 
 | 171 | +        xml_set_element_handler($this->parser, array(&$this, 'startHandler'),   | 
 | 172 | +            array(&$this, 'endHandler'));  | 
 | 173 | +        xml_set_character_data_handler($this->parser, array(&$this, 'cdataHandler'));  | 
 | 174 | +          | 
 | 175 | +        /**  | 
 | 176 | +         * set additional handlers for character data, entities, etc.  | 
 | 177 | +         */  | 
 | 178 | +        foreach ($this->handler as $xml_func => $method) {  | 
 | 179 | +            if (method_exists($this->_handlerObj, $method)) {  | 
 | 180 | +                $xml_func = 'xml_set_' . $xml_func;  | 
 | 181 | +                $xml_func($this->parser, $method);  | 
 | 182 | +            }  | 
 | 183 | +        }  | 
 | 184 | +    }  | 
 | 185 | + | 
 | 186 | +    /**  | 
 | 187 | +     * Reset the parser.  | 
 | 188 | +     *  | 
 | 189 | +     * This allows you to use one parser instance  | 
 | 190 | +     * to parse multiple XML documents.  | 
 | 191 | +     *  | 
 | 192 | +     * @access   public  | 
 | 193 | +     * @return   boolean|object     true on success, PEAR_Error otherwise  | 
 | 194 | +     */  | 
 | 195 | +    function reset()  | 
 | 196 | +    {  | 
 | 197 | +        $this->_elStack = array();  | 
 | 198 | +        $this->_data    = array();  | 
 | 199 | +        $this->_depth   = 0;  | 
 | 200 | +          | 
 | 201 | +        $result = $this->_create();  | 
 | 202 | +        if ($this->isError($result)) {  | 
 | 203 | +            return $result;  | 
 | 204 | +        }  | 
 | 205 | +        return true;  | 
 | 206 | +    }  | 
 | 207 | + | 
 | 208 | +    /**  | 
 | 209 | +     * start handler  | 
 | 210 | +     *  | 
 | 211 | +     * Pushes attributes and tagname onto a stack  | 
 | 212 | +     *  | 
 | 213 | +     * @param resource $xp       xml parser resource  | 
 | 214 | +     * @param string   $elem     element name  | 
 | 215 | +     * @param array    &$attribs attributes  | 
 | 216 | +     *  | 
 | 217 | +     * @return mixed  | 
 | 218 | +     * @access private  | 
 | 219 | +     * @final  | 
 | 220 | +     */  | 
 | 221 | +    function startHandler($xp, $elem, &$attribs)  | 
 | 222 | +    {  | 
 | 223 | +        array_push($this->_elStack, array(  | 
 | 224 | +            'name'    => $elem,  | 
 | 225 | +            'attribs' => $attribs  | 
 | 226 | +        ));  | 
 | 227 | +        $this->_depth++;  | 
 | 228 | +        $this->_data[$this->_depth] = '';  | 
 | 229 | +    }  | 
 | 230 | + | 
 | 231 | +    /**  | 
 | 232 | +     * end handler  | 
 | 233 | +     *  | 
 | 234 | +     * Pulls attributes and tagname from a stack  | 
 | 235 | +     *  | 
 | 236 | +     * @param resource $xp   xml parser resource  | 
 | 237 | +     * @param string   $elem element name  | 
 | 238 | +     *  | 
 | 239 | +     * @return mixed  | 
 | 240 | +     * @access private  | 
 | 241 | +     * @final  | 
 | 242 | +     */  | 
 | 243 | +    function endHandler($xp, $elem)  | 
 | 244 | +    {  | 
 | 245 | +        $el   = array_pop($this->_elStack);  | 
 | 246 | +        $data = $this->_data[$this->_depth];  | 
 | 247 | +        $this->_depth--;  | 
 | 248 | + | 
 | 249 | +        switch ($this->mode) {  | 
 | 250 | +        case 'event':  | 
 | 251 | +            $this->_handlerObj->handleElement($el['name'], $el['attribs'], $data);  | 
 | 252 | +            break;  | 
 | 253 | +        case 'func':  | 
 | 254 | +            $func = 'handleElement_' . $elem;  | 
 | 255 | +            if (strchr($func, '.')) {  | 
 | 256 | +                $func = str_replace('.', '_', $func);  | 
 | 257 | +            }  | 
 | 258 | +            if (method_exists($this->_handlerObj, $func)) {  | 
 | 259 | +                call_user_func(array(&$this->_handlerObj, $func),   | 
 | 260 | +                    $el['name'], $el['attribs'], $data);  | 
 | 261 | +            }  | 
 | 262 | +            break;  | 
 | 263 | +        }  | 
 | 264 | +    }  | 
 | 265 | + | 
 | 266 | +    /**  | 
 | 267 | +     * handle character data  | 
 | 268 | +     *  | 
 | 269 | +     * @param resource $xp   xml parser resource  | 
 | 270 | +     * @param string   $data data  | 
 | 271 | +     *  | 
 | 272 | +     * @return void  | 
 | 273 | +     * @access private  | 
 | 274 | +     * @final  | 
 | 275 | +     */  | 
 | 276 | +    function cdataHandler($xp, $data)  | 
 | 277 | +    {  | 
 | 278 | +        $this->_data[$this->_depth] .= $data;  | 
 | 279 | +    }  | 
 | 280 | + | 
 | 281 | +    /**  | 
 | 282 | +     * handle a tag  | 
 | 283 | +     *  | 
 | 284 | +     * Implement this in your parser   | 
 | 285 | +     *  | 
 | 286 | +     * @param string $name    element name  | 
 | 287 | +     * @param array  $attribs attributes  | 
 | 288 | +     * @param string $data    character data  | 
 | 289 | +     *  | 
 | 290 | +     * @return void  | 
 | 291 | +     * @access public  | 
 | 292 | +     * @abstract  | 
 | 293 | +     */  | 
 | 294 | +    function handleElement($name, $attribs, $data)  | 
 | 295 | +    {  | 
 | 296 | +    }  | 
 | 297 | + | 
 | 298 | +    /**  | 
 | 299 | +     * get the current tag depth  | 
 | 300 | +     *  | 
 | 301 | +     * The root tag is in depth 0.  | 
 | 302 | +     *  | 
 | 303 | +     * @access   public  | 
 | 304 | +     * @return   integer  | 
 | 305 | +     */  | 
 | 306 | +    function getCurrentDepth()  | 
 | 307 | +    {  | 
 | 308 | +        return $this->_depth;  | 
 | 309 | +    }  | 
 | 310 | + | 
 | 311 | +    /**  | 
 | 312 | +     * add some string to the current ddata.  | 
 | 313 | +     *  | 
 | 314 | +     * This is commonly needed, when a document is parsed recursively.  | 
 | 315 | +     *  | 
 | 316 | +     * @param string $data data to add  | 
 | 317 | +     *  | 
 | 318 | +     * @return void  | 
 | 319 | +     * @access public  | 
 | 320 | +     */  | 
 | 321 | +    function addToData($data)  | 
 | 322 | +    {  | 
 | 323 | +        $this->_data[$this->_depth] .= $data;  | 
 | 324 | +    }  | 
 | 325 | +}  | 
 | 326 | +?>  | 
0 commit comments