ILIAS  Release_3_10_x_branch Revision 61812
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilDOMXML.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
24 
35 class ilDOMXML
36 {
43  var $doc;
44 
51  var $tree;
52 
60  var $error;
61 
78  function ilDOMXML ()
79  {
80  $num = func_num_args();
81  $args = func_get_args();
82 
83  if (($num == 1) && is_object($args[0]))
84  {
85  $this->doc = $args[0];
86  }
87  else
88  {
89  $this->initNewDocument($args[0],$args[1],$args[2]);
90  }
91  }
92 
93  function _ilDOMXML ()
94  {
95  if (DEBUG)
96  {
97  printf("domxml destructor called, class=%s\n", get_class($this)."<br/>");
98  }
99  }
100 
101 
102 
112  function initNewDocument ($a_version = "", $a_encoding = "", $a_charset = "")
113  {
114  if (!$a_version) {
115  $a_version = "1.0";
116  }
117 
118  if (!$a_encoding) {
119  $a_encoding = "UTF-8";
120  }
121 
122  if (!$a_charset) {
123  $a_charset = "UTF-8";
124  }
125 
126  // create the xml string (workaround for domxml_new_doc) ***
127  $xmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>". // *** ISO-8859-1
128  "<root />"; // dummy node
129 
130  // create a domxml document object
131  $this->doc = domxml_open_mem($xmlHeader); // *** Fehlerabfrage
132 
133  // delete dummy node
134  $root = $this->doc->document_element();
135  $root->unlink_node();
136 
137  //$this->doc = new_xmldoc($a_version);
138  $this->setEncoding($a_encoding);
139  $this->setCharset($a_charset);
140  }
141 
151  function createRootElement ($a_element)
152  {
153  // check if rootNode already exists
154  if ($root = $this->getRoot()) {
155  return false;
156  }
157 
158  return $this->appendChild($this->createElement($a_element));
159  }
160 
172  function loadDocument ($a_filename, $a_filepath, $a_validate = false)
173  {
174  if ($a_validate) {
175  $mode = DOMXML_LOAD_VALIDATING;
176  } else {
177  $mode = DOMXML_LOAD_PARSING;
178  }
179 
180  $this->doc = domxml_open_file($a_filepath . "/" . $a_filename, $mode, $this->error);
181 
182  // stop parsing if an error occured
183  if ($this->error) {
184  $error_msg = "Error(s) while parsing the document!<br><br>";
185 
186  foreach ($this->error as $error) {
187  $error_msg .= $error["errormessage"]." in line: ".$error["line"]."<br>";
188  }
189 
190  // error handling with ilias object?
191  echo $error_msg;
192  exit();
193  }
194 
195  // set encoding to UTF-8 if empty
196  $this->setEncoding("iso-8859-1",true);
197  // set charset to UTF-8
198  $this->setCharset("iso-8859-1");
199 
200  return $this->doc;
201  }
202 
210  function trim ($a_node)
211  {
212  if ($a_node->has_child_nodes()) {
213  $childs = $a_node->child_nodes();
214 
215  foreach ($childs as $child) {
216  $content = trim($child->get_content());
217 
218  if (empty($content)) {
219  $child->unlink_node();
220  } else {
221  $this->trim($child);
222  }
223  }
224  }
225  }
226 
235  function trimDocument ($a_node = '')
236  {
237  if (empty($a_node)) {
238  $a_node = $this->doc;
239  }
240 
241  $this->trim($a_node);
242  return $a_node;
243  }
244 
266  function transform ($node, $left2 = -1, $lvl = 0)
267  {
268  static $left;
269 
270  // set depth
271  $lvl++;
272 
273  // start value given from outside?
274  if ($left2 > 0) {
275  $left = $left2;
276  }
277  // set default value 1 if no value given
278  if (!$left) {
279  $left = 1;
280  }
281 
282  $node2 = (array)$node;
283 
284  // init structure data
285  // provides additional information about document structure
286  // bitwise:
287  // 1: has attributes
288  // 2: has text element
289  $this->tree[$node2[0]]["struct"] = 0;
290 
291  if ($parent = $node->parent_node()) {
292  $parent = (array)$parent;
293  }
294 
295  if ($first = $node->first_child())
296  {
297  $first = (array)$first;
298  }
299 
300  if ($prev = $node->previous_sibling()) {
301  $prev = (array)$prev;
302  }
303 
304  if ($next = $node->next_sibling()) {
305  $next = (array)$next;
306  }
307 
308  $this->tree[$node2[0]]["content"] = trim($node->node_value());
309  $this->tree[$node2[0]]["name"] = $node->node_name();
310  $this->tree[$node2[0]]["type"] = $node->type;
311  $this->tree[$node2[0]]["depth"] = $lvl;
312  $this->tree[$node2[0]]["parent"] = $parent[0];
313  $this->tree[$node2[0]]["first"] = $first[0];
314  $this->tree[$node2[0]]["prev"] = $prev[0];
315  $this->tree[$node2[0]]["next"] = $next[0];
316  $this->tree[$node2[0]]["left"] = $left;
317  $left++;
318 
319  // write attributes to sub-array
320  if ($node->has_attributes())
321  {
322  $data = "";
323 
324  foreach ($node->attributes() as $attribute)
325  {
326  $data[$attribute->name] = $attribute->value;
327  }
328 
329  $this->tree[$node2[0]]["attr_list"] = $data;
330  $this->tree[$node2[0]]["struct"] += 1;
331  }
332 
333  // check if one child is a text_node
334  foreach ($node->child_nodes() as $child)
335  {
336  if ($child->node_type() == XML_TEXT_NODE)
337  {
338  $this->tree[$node2[0]]["struct"] += 2;
339  break;
340  }
341  }
342 
343  // recursive call
344  // please don't merge this loop with the one above together!
345  foreach ($node->child_nodes() as $child)
346  {
347  $this->transform($child, $left, $lvl);
348  }
349 
350  $this->tree[$node2[0]]["right"] = $left;
351  $left++;
352  }
353 
364  function buildTree ($a_node = "")
365  {
366  if (empty($a_node)) {
367  $a_node = $this->doc;
368  }
369 
370  $this->transform($a_node,1);
371 
372  return $this->tree;
373  }
374 
387  function dumpDocument ($a_stdout = -1, $a_compress = false, $a_format = false)
388  {
389  if ($a_stdout != -1) {
390  $this->doc->dump_file($a_stdout,$a_compress,$a_format);
391  }
392 
393  return $this->doc->dump_mem();
394  }
395 
408  function getTextFromElement ($a_element)
409  {
410  if ($a_element->node_type() == XML_ELEMENT_NODE) {
411  $value = "";
412 
413  foreach ($a_element->child_nodes() as $child) {
414  if ($child->node_type() == XML_TEXT_NODE) {
415  $value .= $child->content;
416  }
417  }
418 
419  return trim($value);
420  }
421 
422  die("<b>".$a_element."</b> is not a valid element node!");
423  }
424 
435  function isLeafElement ($a_node, $a_elementname, $a_num = 0)
436  {
437  $var = true;
438 
439  if ($childs = $a_node->child_nodes()) {
440  foreach ($childs as $child) {
441  $var = $this->isLeafElement($child, $a_elementname);
442 
443  if (!$var) {
444  return false;
445  }
446  }
447  }
448 
449  if (($a_node->node_type() == XML_ELEMENT_NODE) && ($a_node->tagname == $a_elementname) && ($a_num != 1)) {
450  return false;
451  }
452 
453  return $var;
454  }
455 
467  function getElementsByTagname ($a_elementname, $a_node = "")
468  {
469  if (empty($a_node)) {
470  $a_node = $this->doc;
471  }
472 
473  if (count($node = $a_node->get_elements_by_tagname($a_elementname)) > 0) {
474  return $node;
475  }
476 
477  return false;
478  }
479 
490  function appendReferenceNodeForLO ($a_node, $a_lo_id, $a_lm_id, $a_prev_sibling)
491  {
492  $newnode = $this->createElement("LO");
493 
494  if (empty($a_prev_sibling))
495  {
496  $node = $a_node->append_child($newnode);
497  }
498  else
499  {
500  $node = $a_prev_sibling->append_sibling($newnode);
501  }
502 
503  $node->set_attribute("id",$a_lo_id);
504  $node->set_attribute("lm",$a_lm_id);
505  }
506 
515  function appendChild ($a_node)
516  {
517  return $this->doc->append_child($a_node);
518  }
519 
527  function getRoot ()
528  {
529  return $this->doc->document_element();
530  }
531 
540  function createElement ($a_node)
541  {
542  return $this->doc->create_element($a_node);
543  }
544 
545  function addElement ($a_parent, $a_node)
546  {
547  $node = $this->doc->create_element($a_node);
548  $node = $a_parent->append_child($node);
549 
550  return $node;
551  }
552 
561  function createText ($a_text)
562  {
563  return $this->doc->create_text_node($a_text);
564  }
565 
578  function createNode ($a_parent, $a_elementname, $a_attr_list = NULL, $a_text = NULL)
579  {
580  // create new element node
581  $node = $this->createElement($a_elementname);
582 
583  // set attributes
584  if (is_array($a_attr_list)) {
585  foreach ($a_attr_list as $attr => $value) {
586  $node->set_attribute($attr, $value);
587  }
588  }
589 
590  // create and add a text node to the new element node
591  if (is_string($a_text)) {
592  $node_text = $this->doc->create_text_node($a_text);
593  $node_text = $node->append_child($node_text);
594  }
595 
596  // add element node at at the end of the children of the parent
597  $node = $a_parent->append_child($node);
598 
599  return $node;
600  }
601 
609  function getElementId($a_node)
610  {
611  $node = (array) $a_node;
612  return $node[0];
613  }
614 
622  function getElementName($a_node)
623  {
624  return $a_node->node_name();
625  }
626 
635  function setEncoding ($a_encode,$a_overwrite = false)
636  {
637  if (empty($this->doc->encoding) or ($a_overwrite)) {
638  $this->doc->encoding = $a_encode;
639  return true;
640  }
641 
642  return false;
643  }
644 
651  function getEncoding ()
652  {
653  return $this->doc->encoding;
654  }
655 
664  function setCharset ($a_charset,$a_overwrite = false)
665  {
666  if (is_integer($this->doc->charset) or ($a_overwrite)) {
667  $this->doc->charset = $a_charset;
668  return true;
669  }
670 
671  return false;
672  }
673 
680  function getCharset ()
681  {
682  return $this->doc->charset;
683  }
684 
691  function getInfo ()
692  {
693  $node = $this->getElementsByTagname("MetaData");
694 
695  if($node !== false)
696  {
697  $childs = $node[0]->child_nodes();
698 
699  foreach ($childs as $child)
700  {
701  if (($child->node_type() == XML_ELEMENT_NODE) && ($child->tagname == "General"))
702  {
703  $childs2 = $child->child_nodes();
704 
705  foreach ($childs2 as $child2)
706  {
707  if (($child2->node_type() == XML_ELEMENT_NODE) && ($child2->tagname == "Title" || $child2->tagname == "Description"))
708  {
709  $arr[$child2->tagname] = $child2->get_content();
710  }
711  }
712 
713  // General-tag was found. Stop foreach-loop
714  break;
715  }
716  }
717  }
718 
719  // for compatibility reasons:
720  $arr["title"] = $arr["Title"];
721  $arr["desc"] = $arr["Description"];
722 
723  return $arr;
724  }
725 
732  function getReferences()
733  {
734  if ($nodes = $this->getElementsByTagname("LO"))
735  {
736  foreach ($nodes as $node)
737  {
738  $attr[] = $node->get_attribute("id");
739  }
740  }
741 
742  return $attr;
743  }
744 } // END class.domxml
745 ?>