Subversion Repositories Applications.papyrus

Rev

Rev 1087 | Details | Compare with Previous | 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-2002 The PHP Group                                |
7
// +----------------------------------------------------------------------+
8
// | This source file is subject to version 2.02 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/2_02.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
// | Authors: Bernd Römer <berndr@bonn.edu>                               |
17
// |          Sebastian Bergmann <sb@sebastian-bergmann.de>               |
18
// |          Tomas V.V.Cox <cox@idecnet.com> (tree mapping from xml file)|
19
// +----------------------------------------------------------------------+
20
//
21
// $Id: Tree.php,v 1.1 2005-04-18 16:13:31 jpm Exp $
22
//
23
 
24
require_once 'XML/Parser.php';
25
require_once 'XML/Tree/Node.php';
26
 
27
/**
28
* PEAR::XML_Tree
29
*
30
* Purpose
31
*
32
*    Allows for the building of XML data structures
33
*    using a tree representation, without the need
34
*    for an extension like DOMXML.
35
*
36
* Example
37
*
38
*    $tree  = new XML_Tree;
39
*    $root =& $tree->addRoot('root');
40
*    $foo  =& $root->addChild('foo');
41
*
42
*    header('Content-Type: text/xml');
43
*    $tree->dump();
44
*
45
* @author  Bernd Römer <berndr@bonn.edu>
46
* @package XML
47
* @version $Version$ - 1.0
48
*/
49
class XML_Tree extends XML_Parser
50
{
51
    /**
52
    * File Handle
53
    *
54
    * @var  ressource
55
    */
56
    var $file = NULL;
57
 
58
    /**
59
    * Filename
60
    *
61
    * @var  string
62
    */
63
    var $filename = '';
64
 
65
    /**
66
    * Namespace
67
    *
68
    * @var  array
69
    */
70
    var $namespace = array();
71
 
72
    /**
73
    * Root
74
    *
75
    * @var  object XML_Tree_Node
76
    */
77
    var $root = NULL;
78
 
79
    /**
80
    * XML Version
81
    *
82
    * @var  string
83
    */
84
    var $version = '1.0';
85
 
86
    /**
87
    * Constructor
88
    *
89
    * @param  string  Filename
90
    * @param  string  XML Version
91
    */
92
    function XML_Tree($filename = '', $version = '1.0') {
93
        $this->filename = $filename;
94
        $this->version  = $version;
95
    }
96
 
97
    /**
98
    * Add root node.
99
    *
100
    * @param  string  $name     name of root element
101
    * @return object XML_Tree_Node   reference to root node
102
    *
103
    * @access public
104
    */
105
    function &addRoot($name, $content = '', $attributes = array()) {
106
        $this->root = new XML_Tree_Node($name, $content, $attributes);
107
        return $this->root;
108
    }
109
 
110
    /**
111
    * @deprecated
112
    */
113
    function &add_root($name, $content = '', $attributes = array()) {
114
        return $this->addRoot($name, $content, $attributes);
115
    }
116
 
117
    /**
118
    * inserts a child/tree (child) into tree ($path,$pos) and
119
    * maintains namespace integrity
120
    *
121
    * @param array      $path           path to parent of child to remove
122
    * @param integer    $pos            position of child to be inserted in its parents children-list
123
    * @param mixed      $child          child-node (by XML_Tree,XML_Node or Name)
124
    * @param string     $content        content (text) for new node
125
    * @param array      $attributes     attribute-hash for new node
126
    *
127
    * @return object XML_Tree_Node inserted child (node)
128
    * @access public
129
    */
130
    function &insertChild($path,$pos,$child, $content = '', $attributes = array()) {
131
        // update namespace to maintain namespace integrity
132
        $count=count($path);
133
        foreach($this->namespace as $key => $val) {
134
            if ((array_slice($val,0,$count)==$path) && ($val[$count]>=$pos))
135
                $this->namespace[$key][$count]++;
136
        }
137
 
138
        $parent=&$this->get_node_by_path($path);
139
        return($parent->insert_child($pos,$child,$content,$attributes));
140
    }
141
 
142
    /**
143
    * @deprecated
144
    */
145
    function &insert_child($path,$pos,$child, $content = '', $attributes = array()) {
146
        return $this->insertChild($path, $child, $content, $attributes);
147
    }
148
 
149
    /*
150
    * removes a child ($path,$pos) from tree ($path,$pos) and
151
    * maintains namespace integrity
152
    *
153
    * @param array      $path   path to parent of child to remove
154
    * @param integer    $pos    position of child in parents children-list
155
    *
156
    * @return object XML_Tree_Node parent whichs child was removed
157
    * @access public
158
    */
159
    function &removeChild($path,$pos) {
160
        // update namespace to maintain namespace integrity
161
        $count=count($path);
162
        foreach($this->namespace as $key => $val) {
163
            if (array_slice($val,0,$count)==$path) {
164
                if ($val[$count]==$pos) { unset($this->namespace[$key]); break; }
165
                if ($val[$count]>$pos)
166
                    $this->namespace[$key][$count]--;
167
            }
168
        }
169
 
170
        $parent=&$this->get_node_by_path($path);
171
        return($parent->remove_child($pos));
172
    }
173
 
174
    /**
175
    * @deprecated
176
    */
177
    function &remove_child($path, $pos) {
178
        return $this->removeChild($path, $pos);
179
    }
180
 
181
    /*
182
    * Maps a xml file to a objects tree
183
    *
184
    * @return mixed The objects tree (XML_tree or an Pear error)
185
    * @access public
186
    */
187
    function &getTreeFromFile ()
188
    {
189
        $this->folding = false;
190
        $this->XML_Parser(null, 'event');
191
        $err = $this->setInputFile($this->filename);
192
        if (PEAR::isError($err)) {
193
            return $err;
194
        }
195
        $this->cdata = null;
196
        $err = $this->parse();
197
        if (PEAR::isError($err)) {
198
            return $err;
199
        }
200
        return $this->root;
201
    }
202
 
203
    function getTreeFromString($str)
204
    {
205
        $this->folding = false;
206
        $this->XML_Parser(null, 'event');
207
        $this->cdata = null;
208
        $err = $this->parseString($str);
209
        if (PEAR::isError($err)) {
210
            return $err;
211
        }
212
        return $this->root;
213
    }
214
 
215
    /**
216
    * Handler for the xml-data
217
    *
218
    * @param mixed  $xp         ignored
219
    * @param string $elem       name of the element
220
    * @param array  $attribs    attributes for the generated node
221
    *
222
    * @access private
223
    */
224
    function startHandler($xp, $elem, &$attribs)
225
    {
226
        // root elem
227
        if (!isset($this->i)) {
228
            $this->obj1 =& $this->add_root($elem, null, $attribs);
229
            $this->i = 2;
230
        } else {
231
            // mixed contents
232
            if (!empty($this->cdata)) {
233
                $parent_id = 'obj' . ($this->i - 1);
234
                $parent    =& $this->$parent_id;
235
                $parent->children[] = &new XML_Tree_Node(null, $this->cdata);
236
            }
237
            $obj_id = 'obj' . $this->i++;
238
            $this->$obj_id = &new XML_Tree_Node($elem, null, $attribs);
239
        }
240
        $this->cdata = null;
241
        return null;
242
    }
243
 
244
    /**
245
    * Handler for the xml-data
246
    *
247
    * @param mixed  $xp         ignored
248
    * @param string $elem       name of the element
249
    *
250
    * @access private
251
    */
252
    function endHandler($xp, $elem)
253
    {
254
        $this->i--;
255
        if ($this->i > 1) {
256
            $obj_id = 'obj' . $this->i;
257
            // recover the node created in StartHandler
258
            $node   =& $this->$obj_id;
259
            // mixed contents
260
            if (count($node->children) > 0) {
261
                if (trim($this->cdata)) {
262
                    $node->children[] = &new XML_Tree_Node(null, $this->cdata);
263
                }
264
            } else {
265
                $node->set_content($this->cdata);
266
            }
267
            $parent_id = 'obj' . ($this->i - 1);
268
            $parent    =& $this->$parent_id;
269
            // attach the node to its parent node children array
270
            $parent->children[] = $node;
271
        }
272
        $this->cdata = null;
273
        return null;
274
    }
275
 
276
    /*
277
    * The xml character data handler
278
    *
279
    * @param mixed  $xp         ignored
280
    * @param string $data       PCDATA between tags
281
    *
282
    * @access private
283
    */
284
    function cdataHandler($xp, $data)
285
    {
286
        if (trim($data)) {
287
            $this->cdata .= $data;
288
        }
289
    }
290
 
291
    /**
292
    * Get a copy of this tree.
293
    *
294
    * @return object XML_Tree
295
    * @access public
296
    */
297
    function clone() {
298
        $clone=new XML_Tree($this->filename,$this->version);
299
        $clone->root=$this->root->clone();
300
 
301
        // clone all other vars
302
        $temp=get_object_vars($this);
303
        foreach($temp as $varname => $value)
304
            if (!in_array($varname,array('filename','version','root')))
305
                $clone->$varname=$value;
306
 
307
        return($clone);
308
    }
309
 
310
    /**
311
    * Print text representation of XML tree.
312
    *
313
    * @access public
314
    */
315
    function dump() {
316
        echo $this->get();
317
    }
318
 
319
    /**
320
    * Get text representation of XML tree.
321
    *
322
    * @return  string  XML
323
    * @access public
324
    */
325
    function &get() {
326
        $out = '<?xml version="' . $this->version . "\"?>\n";
327
        $out .= $this->root->get();
328
 
329
        return $out;
330
    }
331
 
332
    /**
333
    * Get current namespace.
334
    *
335
    * @param  string  $name namespace
336
    * @return string
337
    *
338
    * @access public
339
    */
340
    function &getName($name) {
341
        return $this->root->get_element($this->namespace[$name]);
342
    }
343
 
344
    /**
345
    * @deprecated
346
    */
347
    function &get_name($name) {
348
        return $this->getName($name);
349
    }
350
 
351
    /**
352
    * Register a namespace.
353
    *
354
    * @param  string  $name namespace
355
    * @param  string  $path path
356
    *
357
    * @access public
358
    */
359
    function registerName($name, $path) {
360
        $this->namespace[$name] = $path;
361
    }
362
 
363
    /**
364
    * @deprecated
365
    */
366
    function register_name($name, $path) {
367
        return $this->registerName($name, $path);
368
    }
369
}
370
?>