27 require_once
'XML/Parser.php';
28 require_once
'XML/Tree/Node.php';
72 var $namespace = array();
94 var $use_cdata_sections =
false;
102 function XML_Tree($filename =
'', $version =
'1.0')
104 $this->filename = $filename;
105 $this->version = $version;
116 $this->use_cdata_sections =
true;
128 if (!is_null($this->root)) {
131 return $this->raiseError(
"No root");
142 function &
addRoot($name, $content =
'', $attributes = array(), $lineno = null)
144 $this->root =
new XML_Tree_Node($name, $content, $attributes, $lineno);
167 function &
insertChild($path, $pos, $child, $content =
'', $attributes = array())
170 if (PEAR::isError($parent)) {
174 $x =& $parent->insertChild(null, $pos, $child, $content, $attributes);
176 if (!PEAR::isError($x)) {
178 $count = count($path);
179 foreach ($this->
namespace as $key => $val) {
180 if ((array_slice($val,0,$count)==$path) && ($val[$count]>=$pos)) {
181 $this->
namespace[$key][$count]++;
204 if (PEAR::isError($parent)) {
208 $x =& $parent->removeChild($pos);
210 if (!PEAR::isError($x)) {
213 foreach($this->
namespace as $key => $val) {
214 if (array_slice($val,0,$count)==$path) {
215 if ($val[$count]==$pos) {
216 unset($this->
namespace[$key]);
break;
218 if ($val[$count]>$pos) {
219 $this->
namespace[$key][$count]--;
236 $this->folding =
false;
237 $this->XML_Parser(null,
'event');
238 $err = $this->setInputFile($this->filename);
239 if (PEAR::isError($err)) {
243 $err = $this->parse();
244 if (PEAR::isError($err)) {
259 $this->folding =
false;
260 $this->XML_Parser(null,
'event');
262 $err = $this->parseString($str);
263 if (PEAR::isError($err)) {
281 $lineno = xml_get_current_line_number($xp);
283 if (!isset($this->i)) {
284 $this->obj1 =& $this->
addRoot($elem, null, $attribs, $lineno);
288 if (!empty($this->cdata)) {
289 $parent_id =
'obj' . ($this->i - 1);
290 $parent =& $this->$parent_id;
294 if (trim($this->cdata) !=
'') {
295 $parent->children[] =
new XML_Tree_Node(null, $this->cdata, null, $lineno);
298 $obj_id =
'obj' . $this->i++;
299 $this->$obj_id =
new XML_Tree_Node($elem, null, $attribs, $lineno);
318 $obj_id =
'obj' . $this->i;
320 $node =& $this->$obj_id;
322 if (count($node->children) > 0) {
323 if (trim($this->cdata) !=
'') {
327 $node->setContent($this->cdata);
329 $parent_id =
'obj' . ($this->i - 1);
330 $parent =& $this->$parent_id;
332 $parent->children[] = $node;
334 $node =& $this->obj1;
335 if (count($node->children) > 0) {
336 if (trim($this->cdata)) {
340 $node->setContent($this->cdata);
358 $this->cdata .= $data;
369 $clone =
new XML_Tree($this->filename, $this->version);
370 if (!is_null($this->root)) {
371 $clone->root = $this->root->cloneTree();
375 $temp = get_object_vars($this);
376 foreach($temp as $varname => $value) {
377 if (!in_array($varname,array(
'filename',
'version',
'root'))) {
378 $clone->$varname=$value;
393 function dump($xmlHeader =
false)
396 header(
'Content-type: text/xml');
398 echo $this->
get($this->use_cdata_sections);
409 $out =
'<?xml version="' . $this->version .
"\"?>\n";
411 if (!is_null($this->root))
413 if(!is_object($this->root) || (strtolower(get_class($this->root)) !=
'xml_tree_node'))
414 return $this->raiseError(
"Bad XML root node");
415 $out .= $this->root->get($this->use_cdata_sections);
429 return $this->root->getElement($this->
namespace[$name]);
437 $name_parts = explode(
':',$node->name);
438 if (
sizeof($name_parts) > 1) {
439 $namespace = $name_parts[0];
444 if (isset($node->namespace[$namespace])) {
445 return $node->namespace[$namespace];
446 } elseif (isset($this->root->namespace[$namespace])) {
447 return $this->root->namespace[$namespace];
467 if (is_null($this->root)){
468 return $this->raiseError(
"XML_Tree hasn't a root node");
470 if (is_string($path))
471 $path = explode(
"/", $path);
472 if (
sizeof($path) == 0) {
473 return $this->raiseError(
"Path to node is empty");
476 $rootName = array_shift($path1);
477 if ($this->root->name != $rootName) {
478 return $this->raiseError(
"Path does not match the document root");
480 $x =& $this->root->getNodeAt($path1);
481 if (!PEAR::isError($x)) {
485 return $this->raiseError(
"Bad path to node: [".implode(
'/', $path).
"]");
500 if (empty($tagName)) {
501 return $this->raiseError(
'Empty tag name');
504 foreach ($this->root->children as $child) {
505 if ($child->name == $tagName) {
526 if (empty($tagName)) {
527 return $this->raiseError(
'Empty tag name');
530 foreach ($node->children as $child) {
531 if ($child->name == $tagName) {
548 if (trim($name) ==
'') {
553 if (!preg_match(
"/[[:alpha:]_]/", $name{0})) {
554 return new PEAR_Error( ucfirst($type) .
" ('$name') has an invalid name, an XML name may only start with a letter or underscore");
557 if (!preg_match(
"/^([a-zA-Z_]([a-zA-Z0-9_\-\.]*)?:)?[a-zA-Z_]([a-zA-Z0-9_\-\.]+)?$/", $name)) {
558 return new PEAR_Error( ucfirst($type) .
" ('$name') has an invalid name, an XML name may only contain alphanumeric chars, period, hyphen, colon and underscores");