00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 require_once "./assessment/classes/class.XML2SQL.php";
00025 require_once "./assessment/classes/class.SQL2XML.php";
00026
00039 class XMLNestedSet
00040 {
00047 var $doc;
00048
00055 var $nestedset;
00056
00064 var $error;
00065
00073 function XMLNestedSet ()
00074 {
00075 $num = func_num_args();
00076 $args = func_get_args();
00077
00078 if (($num == 1) && is_object($args[0]))
00079 {
00080 $this->doc = $args[0];
00081 }
00082 $this->nestedset = array();
00083 register_shutdown_function(array(&$this, '_XMLNestedSet'));
00084 }
00085
00086 function _XMLNestedSet() {
00087 if ($this->doc) {
00088 $this->doc->free();
00089 }
00090 }
00091
00092
00103 function loadDocument ($a_filename, $a_validate = false)
00104 {
00105 if ($a_validate) {
00106 $mode = DOMXML_LOAD_VALIDATING;
00107 } else {
00108 $mode = DOMXML_LOAD_PARSING;
00109 }
00110
00111 if (!file_exists($a_filename)) {
00112 array_push($this->error, array(
00113 "line" => "",
00114 "errormessage" => "The file $a_filename does not exist!"
00115 ));
00116 return;
00117 }
00118
00119 $this->doc = domxml_open_file($a_filename, $mode, $this->error);
00120
00121
00122 if ($this->error) {
00123 $error_msg = "Error(s) while parsing the document!<br><br>";
00124
00125 foreach ($this->error as $error) {
00126 $error_msg .= $error["errormessage"]." in line: ".$error["line"]."<br>";
00127 }
00128 print $error_msg;
00129 exit();
00130 }
00131
00132
00133 $this->setEncoding("iso-8859-1", true);
00134
00135 $this->setCharset("iso-8859-1");
00136
00137 return $this->doc;
00138 }
00139
00151 function setEncoding ($a_encode, $a_overwrite = false)
00152 {
00153 if (empty($this->doc->encoding) or ($a_overwrite)) {
00154 $this->doc->encoding = $a_encode;
00155 return true;
00156 }
00157 return false;
00158 }
00159
00168 function getEncoding ()
00169 {
00170 return $this->doc->encoding;
00171 }
00172
00184 function setCharset ($a_charset, $a_overwrite = false)
00185 {
00186 if (is_integer($this->doc->charset) or ($a_overwrite)) {
00187 $this->doc->charset = $a_charset;
00188 return true;
00189 }
00190
00191 return false;
00192 }
00193
00202 function getCharset ()
00203 {
00204 return $this->doc->charset;
00205 }
00206
00233 function transform ($node, $left2 = -1, $lvl = 0)
00234 {
00235
00236 static $left;
00237
00238
00239 $lvl++;
00240
00241
00242 if ($left2 > 0) {
00243 $left = $left2;
00244 }
00245
00246
00247 if (!$left) {
00248 $left = 1;
00249 }
00250
00251
00252 $node2 = (array)$node;
00253
00254
00255
00256
00257
00258
00259 $this->nestedset[$node2[0]]["struct"] = 0;
00260
00261 if ($parent = $node->parent_node())
00262 {
00263 $parent = (array)$parent;
00264 }
00265
00266 if ($first = $node->first_child())
00267 {
00268 $first = (array)$first;
00269 }
00270
00271 if ($prev = $node->previous_sibling())
00272 {
00273 $prev = (array)$prev;
00274 }
00275
00276 if ($next = $node->next_sibling()) {
00277 $next = (array)$next;
00278 }
00279
00280 $this->nestedset[$node2[0]]["content"] = trim($node->node_value());
00281 $this->nestedset[$node2[0]]["name"] = $node->node_name();
00282 $this->nestedset[$node2[0]]["type"] = $node->type;
00283 $this->nestedset[$node2[0]]["depth"] = $lvl;
00284 $this->nestedset[$node2[0]]["parent"] = $parent[0];
00285 $this->nestedset[$node2[0]]["first"] = $first[0];
00286 $this->nestedset[$node2[0]]["prev"] = $prev[0];
00287 $this->nestedset[$node2[0]]["next"] = $next[0];
00288 $this->nestedset[$node2[0]]["left"] = $left;
00289
00290
00291 $left++;
00292
00293
00294 if ($node->has_attributes())
00295 {
00296 $data = "";
00297
00298 foreach ($node->attributes() as $attribute)
00299 {
00300 $data[$attribute->name] = $attribute->value;
00301 }
00302
00303 $this->nestedset[$node2[0]]["attr_list"] = $data;
00304 $this->nestedset[$node2[0]]["struct"] += 1;
00305 }
00306
00307
00308 foreach ($node->child_nodes() as $child)
00309 {
00310 if ($child->node_type() == XML_TEXT_NODE)
00311 {
00312 $this->nestedset[$node2[0]]["struct"] += 2;
00313 break;
00314 }
00315 }
00316
00317
00318 foreach ($node->child_nodes() as $child)
00319 {
00320 $this->transform($child, $left, $lvl);
00321 }
00322
00323 $this->nestedset[$node2[0]]["right"] = $left;
00324 $left++;
00325 }
00326
00337 function &buildTree ($a_node = "")
00338 {
00339 $this->nestedset = array();
00340 if (empty($a_node)) {
00341 $a_node = $this->doc;
00342 }
00343
00344 $this->transform($a_node, 1);
00345
00346 return $this->nestedset;
00347 }
00348
00349
00357 function trim ($a_node)
00358 {
00359 if ($a_node->has_child_nodes()) {
00360 $childs = $a_node->child_nodes();
00361
00362 foreach ($childs as $child) {
00363 $content = trim($child->get_content());
00364
00365 if (empty($content) and ($child->type == XML_TEXT_NODE)) {
00366 $child->unlink_node();
00367 } else {
00368 $this->trim($child);
00369 }
00370 }
00371 }
00372 }
00373
00382 function trimDocument ($a_node = '')
00383 {
00384 if (empty($a_node)) {
00385 $a_node = $this->doc;
00386 }
00387
00388 $this->trim($a_node);
00389 return $a_node;
00390 }
00391
00404 function dumpDocument ($a_stdout = -1, $a_compress = false, $a_format = false)
00405 {
00406 if ($a_stdout != -1) {
00407 $this->doc->dump_file($a_stdout,$a_compress,$a_format);
00408 }
00409
00410 return $this->doc->dump_mem();
00411 }
00412
00425 function getTextFromElement ($a_element)
00426 {
00427 if ($a_element->node_type() == XML_ELEMENT_NODE) {
00428 $value = "";
00429
00430 foreach ($a_element->child_nodes() as $child) {
00431 if ($child->node_type() == XML_TEXT_NODE) {
00432 $value .= $child->content;
00433 }
00434 }
00435
00436 return trim($value);
00437 }
00438
00439 die("<b>".$a_element."</b> is not a valid element node!");
00440 }
00441
00452 function isLeafElement ($a_node, $a_elementname, $a_num = 0)
00453 {
00454 $var = true;
00455
00456 if ($childs = $a_node->child_nodes()) {
00457 foreach ($childs as $child) {
00458 $var = $this->isLeafElement($child, $a_elementname);
00459
00460 if (!$var) {
00461 return false;
00462 }
00463 }
00464 }
00465
00466 if (($a_node->node_type() == XML_ELEMENT_NODE) && ($a_node->tagname == $a_elementname) && ($a_num != 1)) {
00467 return false;
00468 }
00469
00470 return $var;
00471 }
00472
00484 function getElementsByTagname ($a_elementname, $a_node = "")
00485 {
00486 if (empty($a_node)) {
00487 $a_node = $this->doc;
00488 }
00489
00490 if (count($node = $a_node->get_elements_by_tagname($a_elementname)) > 0) {
00491 return $node;
00492 }
00493
00494 return false;
00495 }
00496
00504 function getRoot ()
00505 {
00506 return $this->doc->document_element();
00507 }
00508
00516 function getElementId($a_node)
00517 {
00518 $node = (array) $a_node;
00519 return $node[0];
00520 }
00521
00529 function getElementName($a_node)
00530 {
00531 return $a_node->node_name();
00532 }
00533
00534 function save_to_db($db) {
00535 if (empty($this->doc))
00536 {
00537 return;
00538 }
00539 if (empty($this->nestedset))
00540 {
00541 $this->buildTree();
00542 }
00543 $xml2sql = new XML2SQL($db, $this->nestedset, "1.0", $this->getEncoding(), $this->getCharset());
00544 $xml2sql->insertDocument();
00545 unset($xml2sql);
00546 }
00547
00548 function loadFromDb($db, $xml_object_id) {
00549 $sql2xml = new SQL2XML($db, $xml_object_id);
00550 if ($this->doc) {
00551 $this->doc->free();
00552 }
00553 $this->doc =& $sql2xml->doc;
00554 unset($sql2xml);
00555 }
00556
00557 function delete_from_db($db, $xml_object_id) {
00558 $tables = array(
00559 "xml_element_namespace",
00560 "xml_pi_target",
00561 "xml_pi_data",
00562 "xml_cdata",
00563 "xml_entity_reference",
00564 "xml_attribute_namespace",
00565 "xml_text",
00566 "xml_comment",
00567 "xml_attribute_idx",
00568 "xml_element_idx"
00569 );
00570 foreach ($tables as $table)
00571 {
00572 $q = sprintf ("SELECT $table.* FROM $table, xml_tree WHERE $table.node_id = xml_tree.node_id AND xml_tree.xml_id = %s",
00573 $db->quote("$xml_object_id")
00574 );
00575 $result = $db->query($q);
00576 if ($result->numRows()) {
00577 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
00578 {
00579 $q_delete = sprintf ("DELETE FROM $table WHERE node_id = %s",
00580 $db->quote($row->node_id)
00581 );
00582 $result_delete = $db->query($q_delete);
00583 if (strcmp($table, "xml_attribute_idx") == 0)
00584 {
00585 $q_delete = sprintf ("DELETE FROM xml_attribute_value WHERE value_id = %s",
00586 $db->quote($row->value_id)
00587 );
00588 $result_delete = $db->query($q_delete);
00589 $q_delete = sprintf ("DELETE FROM xml_attribute_name WHERE attribute_id = %s",
00590 $db->quote($row->attribute_id)
00591 );
00592 $result_delete = $db->query($q_delete);
00593 }
00594 if (strcmp($table, "xml_element_idx") == 0)
00595 {
00596 $q_delete = sprintf ("DELETE FROM xml_element_name WHERE element_id = %s",
00597 $db->quote($row->element_id)
00598 );
00599 $result_delete = $db->query($q_delete);
00600 }
00601 }
00602 }
00603 }
00604 $q = sprintf("DELETE FROM xml_object WHERE ID=%s",
00605 $db->quote($xml_object_id)
00606 );
00607 $result = $db->query($q);
00608 $q = sprintf("DELETE FROM xml_tree WHERE xml_id = %s",
00609 $db->quote($xml_object_id)
00610 );
00611 $result = $db->query($q);
00612 }
00613 }
00614
00615 ?>