| [ Index ] |
PHP Cross Reference of Joomla 1.5.26 DE |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * DOMIT! Lite is a non-validating, but lightweight and fast DOM parser for PHP 4 * @package domit-xmlparser 5 * @subpackage domit-xmlparser-lite 6 * @version 1.01 7 * @copyright (C) 2004 John Heinstein. All rights reserved 8 * @license http://www.gnu.org/copyleft/lesser.html LGPL License 9 * @author John Heinstein <johnkarl@nbnet.nb.ca> 10 * @link http://www.engageinteractive.com/domit/ DOMIT! Home Page 11 * DOMIT! is Free Software 12 **/ 13 14 if (!defined('DOMIT_INCLUDE_PATH')) { 15 define('DOMIT_INCLUDE_PATH', (dirname(__FILE__) . "/")); 16 } 17 18 /** current version of DOMIT! Lite */ 19 define ('DOMIT_LITE_VERSION', '1.01'); 20 21 /** 22 *@global array Flipped version of $definedEntities array, to allow two-way conversion of entities 23 * 24 * Made global so that Attr nodes, which have no ownerDocument property, can access the array 25 */ 26 $GLOBALS['DOMIT_defined_entities_flip'] = array(); 27 28 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_shared.php'); 29 30 /** 31 * The base class of all DOMIT node types 32 * 33 * @package domit-xmlparser 34 * @subpackage domit-xmlparser-lite 35 * @author John Heinstein <johnkarl@nbnet.nb.ca> 36 */ 37 class DOMIT_Lite_Node { 38 /** @var string The name of the node, varies according to node type */ 39 var $nodeName = null; 40 /** @var string The value of the node, varies according to node type */ 41 var $nodeValue = null; 42 /** @var int The type of node, e.g. CDataSection */ 43 var $nodeType = null; 44 /** @var Object A reference to the parent of the current node */ 45 var $parentNode = null; 46 /** @var Array An array of child node references */ 47 var $childNodes = null; 48 /** @var Object A reference to the first node in the childNodes list */ 49 var $firstChild = null; 50 /** @var Object A reference to the last node in the childNodes list */ 51 var $lastChild = null; 52 /** @var Object A reference to the node prior to the current node in its parents childNodes list */ 53 var $previousSibling = null; 54 /** @var Object A reference to the node after the current node in its parents childNodes list */ 55 var $nextSibling = null; 56 /** @var Array An array of attribute key / value pairs */ 57 var $attributes = null; 58 /** @var Object A reference to the Document node */ 59 var $ownerDocument = null; 60 /** @var string The unique node id */ 61 var $uid; 62 /** @var int The number of children of the current node */ 63 var $childCount = 0; 64 65 /** 66 * Raises error if abstract class is directly instantiated 67 */ 68 function DOMIT_Lite_Node() { 69 DOMIT_DOMException::raiseException(DOMIT_ABSTRACT_CLASS_INSTANTIATION_ERR, 70 'Cannot instantiate abstract class DOMIT_Lite_Node'); 71 } //DOMIT_Lite_Node 72 73 /** 74 * DOMIT_Lite_Node constructor, assigns a uid 75 */ 76 function _constructor() { 77 global $uidFactory; 78 $this->uid = $uidFactory->generateUID(); 79 } //_constructor 80 81 /** 82 * Appends a node to the childNodes list of the current node 83 * @abstract 84 * @param Object The node to be appended 85 * @return Object The appended node 86 */ 87 function &appendChild(&$child) { 88 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 89 ('Method appendChild cannot be called by class ' . get_class($this))); 90 } //appendChild 91 92 /** 93 * Inserts a node to the childNodes list of the current node 94 * @abstract 95 * @param Object The node to be inserted 96 * @param Object The node before which the insertion is to occur 97 * @return Object The inserted node 98 */ 99 function &insertBefore(&$newChild, &$refChild) { 100 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 101 ('Method insertBefore cannot be called by class ' . get_class($this))); 102 } //insertBefore 103 104 /** 105 * Replaces a node with another 106 * @abstract 107 * @param Object The new node 108 * @param Object The old node 109 * @return Object The new node 110 */ 111 function &replaceChild(&$newChild, &$oldChild) { 112 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 113 ('Method replaceChild cannot be called by class ' . get_class($this))); 114 } //replaceChild 115 116 /** 117 * Removes a node from the childNodes list of the current node 118 * @abstract 119 * @param Object The node to be removed 120 * @return Object The removed node 121 */ 122 function &removeChild(&$oldChild) { 123 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 124 ('Method removeChild cannot be called by class ' . get_class($this))); 125 } //removeChild 126 127 /** 128 * Returns the index of the specified node in a childNodes list 129 * @param Array The childNodes array to be searched 130 * @param Object The node targeted by the search 131 * @return int The index of the target node, or -1 if not found 132 */ 133 function getChildNodeIndex(&$arr, &$child) { 134 $index = -1; 135 $total = count($arr); 136 137 for ($i = 0; $i < $total; $i++) { 138 if ($child->uid == $arr[$i]->uid) { 139 $index = $i; 140 break; 141 } 142 } 143 144 return $index; 145 } //getChildNodeIndex 146 147 /** 148 * Determines whether a node has any children 149 * @return boolean True if any child nodes are present 150 */ 151 function hasChildNodes() { 152 return ($this->childCount > 0); 153 } //hasChildNodes 154 155 /** 156 * Copies a node and/or its children 157 * @abstract 158 * @param boolean True if all child nodes are also to be cloned 159 * @return Object A copy of the node and/or its children 160 */ 161 function &cloneNode($deep = false) { 162 DOMIT_DOMException::raiseException(DOMIT_ABSTRACT_METHOD_INVOCATION_ERR, 163 'Cannot invoke abstract method DOMIT_Lite_Node->cloneNode($deep). Must provide an overridden method in your subclass.'); 164 } //cloneNode 165 166 /** 167 * Adds elements with the specified tag name to a NodeList collection 168 * @param Object The NodeList collection 169 * @param string The tag name of matching elements 170 */ 171 function getNamedElements(&$nodeList, $tagName) { 172 //Implemented in DOMIT_Lite_Element. 173 //Needs to be here though! This is called against all nodes in the document. 174 } //getNamedElements 175 176 /** 177 * Sets the ownerDocument property of a node to the containing DOMIT_Document 178 * @param Object A reference to the document element of the DOMIT_Document 179 */ 180 function setOwnerDocument(&$rootNode) { 181 if ($rootNode->ownerDocument == null) { 182 unset($this->ownerDocument); 183 $this->ownerDocument = null; 184 } 185 else { 186 $this->ownerDocument =& $rootNode->ownerDocument; 187 } 188 189 $total = $this->childCount; 190 191 for ($i = 0; $i < $total; $i++) { 192 $this->childNodes[$i]->setOwnerDocument($rootNode); 193 } 194 } //setOwnerDocument 195 196 /** 197 * Tests whether a value is null, and if so, returns a default value 198 * @param mixed The value to be tested 199 * @param mixed The default value 200 * @return mixed The specified value, or the default value if null 201 */ 202 function &nvl(&$value,$default) { 203 if (is_null($value)) return $default; 204 return $value; 205 } //nvl 206 207 /** 208 * Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like expression. 209 * @abstract 210 * @param string The query pattern 211 * @param int If a single node is to be returned (rather than the entire NodeList) the index of that node 212 * @return mixed A NodeList or single node that matches the pattern 213 */ 214 function &getElementsByPath($pattern, $nodeIndex = 0) { 215 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 216 ('Method getElementsByPath cannot be called by class ' . get_class($this))); 217 } //getElementsByPath 218 219 /** 220 * Returns the concatented text of the current node and its children 221 * @return string The concatented text of the current node and its children 222 */ 223 function getText() { 224 return $this->nodeValue; 225 } //getText 226 227 /** 228 * Formats a string for presentation as HTML 229 * @param string The string to be formatted 230 * @param boolean True if the string is to be sent directly to output 231 * @return string The HTML formatted string 232 */ 233 function forHTML($str, $doPrint = false) { 234 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); 235 return DOMIT_Utilities::forHTML($str, $doPrint); 236 } //forHTML 237 238 /** 239 * Generates an array representation of the node and its children 240 * @abstract 241 * @return Array A representation of the node and its children 242 */ 243 function toArray() { 244 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 245 ('Method toArray cannot be called by class ' . get_class($this))); 246 } //toArray 247 248 /** 249 * A node event that can be set to fire upon document loading, used for node initialization 250 * @abstract 251 */ 252 function onLoad() { 253 //you can override this method if you subclass any of the 254 //DOMIT_Lite_Nodes. It's a way of performing 255 //initialization of your subclass as soon as the document 256 //has been loaded (as opposed to as soon as the current node 257 //has been instantiated). 258 } //onLoad 259 260 /** 261 * Clears previousSibling, nextSibling, and parentNode references from a node that has been removed 262 */ 263 function clearReferences() { 264 if ($this->previousSibling != null) { 265 unset($this->previousSibling); 266 $this->previousSibling = null; 267 } 268 if ($this->nextSibling != null) { 269 unset($this->nextSibling); 270 $this->nextSibling = null; 271 } 272 if ($this->parentNode != null) { 273 unset($this->parentNode); 274 $this->parentNode = null; 275 } 276 } //clearReferences 277 278 /** 279 * Generates a normalized (formatted for readability) representation of the node and its children 280 * @param boolean True if HTML readable output is desired 281 * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities 282 * @return string The formatted string representation 283 */ 284 function toNormalizedString($htmlSafe = false, $subEntities = false) { 285 //require this file for generating a normalized (readable) xml string representation 286 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); 287 global $DOMIT_defined_entities_flip; 288 289 $result = DOMIT_Utilities::toNormalizedString($this, $subEntities, $DOMIT_defined_entities_flip); 290 291 if ($htmlSafe) $result = $this->forHTML($result); 292 293 return $result; 294 } //toNormalizedString 295 } //DOMIT_Lite_Node 296 297 298 /** 299 * A parent class for nodes which possess child nodes 300 * 301 * @package domit-xmlparser 302 * @subpackage domit-xmlparser-lite 303 * @author John Heinstein <johnkarl@nbnet.nb.ca> 304 */ 305 class DOMIT_Lite_ChildNodes_Interface extends DOMIT_Lite_Node { 306 /** 307 * Raises error if abstract class is directly instantiated 308 */ 309 function DOMIT_Lite_ChildNodes_Interface() { 310 DOMIT_DOMException::raiseException(DOMIT_ABSTRACT_CLASS_INSTANTIATION_ERR, 311 'Cannot instantiate abstract class DOMIT_Lite_ChildNodes_Interface'); 312 } //DOMIT_Lite_ChildNodes_Interface 313 314 /** 315 * Appends a node to the childNodes list of the current node 316 * @param Object The node to be appended 317 * @return Object The appended node 318 */ 319 /** 320 * Appends a node to the childNodes list of the current node 321 * @param Object The node to be appended 322 * @return Object The appended node 323 */ 324 function &appendChild(&$child) { 325 if (!($this->hasChildNodes())) { 326 $this->childNodes[0] =& $child; 327 $this->firstChild =& $child; 328 } 329 else { 330 //remove $child if it already exists 331 $index = $this->getChildNodeIndex($this->childNodes, $child); 332 333 if ($index != -1) { 334 $this->removeChild($child); 335 } 336 337 //append child 338 $numNodes = $this->childCount; 339 //BB: was bug auto-created wrong childnodes[-1]: added IF 340 if ($numNodes>0) $prevSibling =& $this->childNodes[($numNodes - 1)]; 341 342 $this->childNodes[$numNodes] =& $child; 343 344 //set next and previous relationships 345 //BB: added this line and the else part to finish correcting bug 346 if (isset($prevSibling)) { 347 $child->previousSibling =& $prevSibling; 348 $prevSibling->nextSibling =& $child; 349 } else { 350 unset($child->previousSibling); 351 $child->previousSibling = null; 352 $this->firstChild =& $child; 353 } 354 } 355 356 $this->lastChild =& $child; 357 $child->parentNode =& $this; 358 359 unset($child->nextSibling); 360 $child->nextSibling = null; 361 362 $child->setOwnerDocument($this); 363 $this->childCount++; 364 365 return $child; 366 } //appendChild 367 368 /** 369 * Inserts a node to the childNodes list of the current node 370 * @param Object The node to be inserted 371 * @param Object The node before which the insertion is to occur 372 * @return Object The inserted node 373 */ 374 function &insertBefore(&$newChild, &$refChild) { 375 if (($refChild->nodeType == DOMIT_DOCUMENT_NODE) || 376 ($refChild->parentNode == null)) { 377 378 DOMIT_DOMException::raiseException(DOMIT_NOT_FOUND_ERR, 379 'Reference child not present in the child nodes list.'); 380 } 381 382 //if reference child is also the node to be inserted 383 //leave the document as is and don't raise an exception 384 if ($refChild->uid == $newChild->uid) { 385 return $newChild; 386 } 387 388 //remove $newChild if it already exists 389 $index = $this->getChildNodeIndex($this->childNodes, $newChild); 390 if ($index != -1) { 391 $this->removeChild($newChild); 392 } 393 394 //find index of $refChild in childNodes 395 $index = $this->getChildNodeIndex($this->childNodes, $refChild); 396 397 if ($index != -1) { 398 //reset sibling chain 399 if ($refChild->previousSibling != null) { 400 $refChild->previousSibling->nextSibling =& $newChild; 401 $newChild->previousSibling =& $refChild->previousSibling; 402 } 403 else { 404 $this->firstChild =& $newChild; 405 406 if ($newChild->previousSibling != null) { 407 unset($newChild->previousSibling); 408 $newChild->previousSibling = null; 409 } 410 } 411 412 $newChild->parentNode =& $refChild->parentNode; 413 $newChild->nextSibling =& $refChild; 414 $refChild->previousSibling =& $newChild; 415 416 //add node to childNodes 417 $i = $this->childCount; 418 419 while ($i >= 0) { 420 if ($i > $index) { 421 $this->childNodes[$i] =& $this->childNodes[($i - 1)]; 422 } 423 else if ($i == $index) { 424 $this->childNodes[$i] =& $newChild; 425 } 426 $i--; 427 } 428 429 $this->childCount++; 430 } 431 else { 432 $this->appendChild($newChild); 433 } 434 435 $newChild->setOwnerDocument($this); 436 437 return $newChild; 438 } //insertBefore 439 440 /** 441 * Replaces a node with another 442 * @param Object The new node 443 * @param Object The old node 444 * @return Object The new node 445 */ 446 function &replaceChild(&$newChild, &$oldChild) { 447 if ($this->hasChildNodes()) { 448 //remove $newChild if it already exists 449 $index = $this->getChildNodeIndex($this->childNodes, $newChild); 450 if ($index != -1) { 451 $this->removeChild($newChild); 452 } 453 454 //find index of $oldChild in childNodes 455 $index = $this->getChildNodeIndex($this->childNodes, $oldChild); 456 457 if ($index != -1) { 458 $newChild->ownerDocument =& $oldChild->ownerDocument; 459 $newChild->parentNode =& $oldChild->parentNode; 460 461 //reset sibling chain 462 if ($oldChild->previousSibling == null) { 463 unset($newChild->previousSibling); 464 $newChild->previousSibling = null; 465 } 466 else { 467 $oldChild->previousSibling->nextSibling =& $newChild; 468 $newChild->previousSibling =& $oldChild->previousSibling; 469 } 470 471 if ($oldChild->nextSibling == null) { 472 unset($newChild->nextSibling); 473 $newChild->nextSibling = null; 474 } 475 else { 476 $oldChild->nextSibling->previousSibling =& $newChild; 477 $newChild->nextSibling =& $oldChild->nextSibling; 478 } 479 480 $this->childNodes[$index] =& $newChild; 481 482 if ($index == 0) $this->firstChild =& $newChild; 483 if ($index == ($this->childCount - 1)) $this->lastChild =& $newChild; 484 485 $newChild->setOwnerDocument($this); 486 487 return $newChild; 488 } 489 } 490 491 DOMIT_DOMException::raiseException(DOMIT_NOT_FOUND_ERR, 492 ('Reference node for replaceChild not found.')); 493 } //replaceChild 494 495 /** 496 * Removes a node from the childNodes list of the current node 497 * @param Object The node to be removed 498 * @return Object The removed node 499 */ 500 function &removeChild(&$oldChild) { 501 if ($this->hasChildNodes()) { 502 //find index of $oldChild in childNodes 503 $index = $this->getChildNodeIndex($this->childNodes, $oldChild); 504 505 if ($index != -1) { 506 //reset sibling chain 507 if (($oldChild->previousSibling != null) && ($oldChild->nextSibling != null)) { 508 $oldChild->previousSibling->nextSibling =& $oldChild->nextSibling; 509 $oldChild->nextSibling->previousSibling =& $oldChild->previousSibling; 510 } 511 else if (($oldChild->previousSibling != null) && ($oldChild->nextSibling == null)) { 512 $this->lastChild =& $oldChild->previousSibling; 513 unset($oldChild->previousSibling->nextSibling); 514 $oldChild->previousSibling->nextSibling = null; 515 } 516 else if (($oldChild->previousSibling == null) && ($oldChild->nextSibling != null)) { 517 unset($oldChild->nextSibling->previousSibling); 518 $oldChild->nextSibling->previousSibling = null; 519 $this->firstChild =& $oldChild->nextSibling; 520 } 521 else if (($oldChild->previousSibling == null) && ($oldChild->nextSibling == null)) { 522 unset($this->firstChild); 523 $this->firstChild = null; 524 unset($this->lastChild); 525 $this->lastChild = null; 526 } 527 528 $total = $this->childCount; 529 530 //remove node from childNodes 531 for ($i = 0; $i < $total; $i++) { 532 if ($i == ($total - 1)) { 533 array_splice($this->childNodes, $i, 1); 534 } 535 else if ($i >= $index) { 536 $this->childNodes[$i] =& $this->childNodes[($i + 1)]; 537 } 538 } 539 540 $this->childCount--; 541 542 $oldChild->clearReferences(); 543 return $oldChild; 544 } 545 } 546 547 DOMIT_DOMException::raiseException(DOMIT_NOT_FOUND_ERR, 548 ('Target node for removeChild not found.')); 549 } //removeChild 550 551 /** 552 * Searches the element tree for an element with the specified attribute name and value. 553 * @param string The value of the attribute 554 * @param string The name of the attribute 555 * @param boolean True if the first found node is to be returned as a node instead of a nodelist 556 * @param boolean True if uid is to be considered an attribute 557 * @return object A NodeList of found elements, or null 558 */ 559 function &getElementsByAttribute($attrName = 'id', $attrValue = '', 560 $returnFirstFoundNode = false, $treatUIDAsAttribute = false) { 561 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_nodemaps.php'); 562 563 $nodelist = new DOMIT_NodeList(); 564 565 switch ($this->nodeType) { 566 case DOMIT_ELEMENT_NODE: 567 $this->_getElementsByAttribute($nodelist, $attrName, $attrValue, 568 $returnFirstFoundNode, $treatUIDAsAttribute); 569 break; 570 571 case DOMIT_DOCUMENT_NODE: 572 if ($this->documentElement != null) { 573 $this->documentElement->_getElementsByAttribute($nodelist, 574 $attrName, $attrValue, $returnFirstFoundNode, $treatUIDAsAttribute); 575 } 576 break; 577 } 578 579 if ($returnFirstFoundNode) { 580 if ($nodelist->getLength() > 0) { 581 return $nodelist->item(0); 582 } 583 $null = null; 584 return $null; 585 } 586 587 return $nodelist; 588 } //getElementsByAttribute 589 590 /** 591 * Searches the element tree for an element with the specified attribute name and value. 592 * @param object The node list of found elements 593 * @param string The value of the attribute 594 * @param string The name of the attribute 595 * @param boolean True if the first found node is to be returned as a node instead of a nodelist 596 * @param boolean True if uid is to be considered an attribute 597 * @param boolean True the node has been found 598 */ 599 function _getElementsByAttribute(&$nodelist, $attrName, $attrValue, 600 $returnFirstFoundNode, $treatUIDAsAttribute, $foundNode = false) { 601 if (!($foundNode && $returnFirstFoundNode)) { 602 if (($this->getAttribute($attrName) == $attrValue) || 603 ($treatUIDAsAttribute && ($attrName == 'uid') && ($this->uid == $attrValue))) { 604 $nodelist->appendNode($this); 605 $foundNode = true; 606 if ($returnFirstFoundNode) return; 607 } 608 609 $total = $this->childCount; 610 611 for ($i = 0; $i < $total; $i++) { 612 $currNode =& $this->childNodes[$i]; 613 614 if ($currNode->nodeType == DOMIT_ELEMENT_NODE) { 615 $currNode->_getElementsByAttribute($nodelist, 616 $attrName, $attrValue, $returnFirstFoundNode, 617 $treatUIDAsAttribute, $foundNode); 618 } 619 } 620 } 621 } //_getElementsByAttribute 622 } //DOMIT_Lite_ChildNodes_Interface 623 624 /** 625 * A class representing the DOM Document 626 * 627 * @package domit-xmlparser 628 * @subpackage domit-xmlparser-lite 629 * @author John Heinstein <johnkarl@nbnet.nb.ca> 630 */ 631 class DOMIT_Lite_Document extends DOMIT_Lite_ChildNodes_Interface { 632 /** @var string The xml declaration text */ 633 var $xmlDeclaration; 634 /** @var string The doctype text */ 635 var $doctype; 636 /** @var Object A reference to the root node of the DOM document */ 637 var $documentElement; 638 /** @var string The parser used to process the DOM document, either "EXPAT" or "SAXY_LITE" */ 639 var $parser; 640 /** @var Object A reference to the DOMIT_DOMImplementation object */ 641 var $implementation; 642 /** @var Array User defined translation table for XML entities */ 643 var $definedEntities = array(); 644 /** @var boolean If true, loadXML or parseXML will attempt to detect and repair invalid xml */ 645 var $doResolveErrors = false; 646 /** @var boolean True if whitespace is to be preserved during parsing */ 647 var $preserveWhitespace = false; 648 /** @var boolean If true, elements tags will be rendered to string as <element></element> rather than <element/> */ 649 var $doExpandEmptyElementTags = false; 650 /** @var array A list of exceptions to the empty element expansion rule */ 651 var $expandEmptyElementExceptions = array(); 652 /** @var int The error code returned by the SAX parser */ 653 var $errorCode = 0; 654 /** @var string The error string returned by the SAX parser */ 655 var $errorString = ''; 656 /** @var object A reference to a http connection or proxy server, if one is required */ 657 var $httpConnection = null; 658 /** @var boolean True if php_http_client_generic is to be used instead of PHP get_file_contents to retrieve xml data */ 659 var $doUseHTTPClient = false; 660 661 /** 662 * DOM Document constructor 663 */ 664 function DOMIT_Lite_Document() { 665 $this->_constructor(); 666 $this->xmlDeclaration = ''; 667 $this->doctype = ''; 668 $this->documentElement = null; 669 $this->nodeType = DOMIT_DOCUMENT_NODE; 670 $this->nodeName = '#document'; 671 $this->ownerDocument =& $this; 672 $this->parser = ''; 673 $this->implementation = new DOMIT_DOMImplementation(); 674 } //DOMIT_Lite_Document 675 676 /** 677 * Specifies whether DOMIT! Lite will try to fix invalid XML before parsing begins 678 * @param boolean True if errors are to be resolved 679 */ 680 function resolveErrors($truthVal) { 681 $this->doResolveErrors = $truthVal; 682 } //resolveErrors 683 684 /** 685 * Specifies the parameters of the http conection used to obtain the xml data 686 * @param string The ip address or domain name of the connection 687 * @param string The path of the connection 688 * @param int The port that the connection is listening on 689 * @param int The timeout value for the connection 690 * @param string The user name, if authentication is required 691 * @param string The password, if authentication is required 692 */ 693 function setConnection($host, $path = '/', $port = 80, $timeout = 0, $user = null, $password = null) { 694 require_once (DOMIT_INCLUDE_PATH . 'php_http_client_generic.php'); 695 696 $this->httpConnection = new php_http_client_generic($host, $path, $port, $timeout, $user, $password); 697 } //setConnection 698 699 /** 700 * Specifies whether DOMIT! preserves whitespace when parsing 701 * @param boolean True if whitespace is to be preserved 702 */ 703 function preserveWhitespace($truthVal) { 704 $this->preserveWhitespace = $truthVal; 705 } //preserveWhitespace 706 707 /** 708 * Specifies basic authentication for an http connection 709 * @param string The user name 710 * @param string The password 711 */ 712 function setAuthorization($user, $password) { 713 $this->httpConnection->setAuthorization($user, $password); 714 } //setAuthorization 715 716 /** 717 * Specifies that a proxy is to be used to obtain the xml data 718 * @param string The ip address or domain name of the proxy 719 * @param string The path to the proxy 720 * @param int The port that the proxy is listening on 721 * @param int The timeout value for the connection 722 * @param string The user name, if authentication is required 723 * @param string The password, if authentication is required 724 */ 725 function setProxyConnection($host, $path = '/', $port = 80, $timeout = 0, $user = null, $password = null) { 726 require_once (DOMIT_INCLUDE_PATH . 'php_http_proxy.php'); 727 728 $this->httpConnection = new php_http_proxy($host, $path, $port, $timeout, $user, $password); 729 } //setProxyConnection 730 731 /** 732 * Specifies basic authentication for the proxy 733 * @param string The user name 734 * @param string The password 735 */ 736 function setProxyAuthorization($user, $password) { 737 $this->httpConnection->setProxyAuthorization($user, $password); 738 } //setProxyAuthorization 739 740 /** 741 * Specifies whether an HTTP client should be used to establish a connection 742 * @param boolean True if an HTTP client is to be used to establish the connection 743 */ 744 function useHTTPClient($truthVal) { 745 $this->doUseHTTPClient = $truthVal; 746 } //useHTTPClient 747 748 /** 749 * Returns the error code from the underlying SAX parser 750 * @return int The error code 751 */ 752 function getErrorCode() { 753 return $this->errorCode; 754 } //getErrorCode 755 756 /** 757 * Returns the error string from the underlying SAX parser 758 * @return string The error string 759 */ 760 function getErrorString() { 761 return $this->errorString; 762 } //getErrorString 763 764 /** 765 * Specifies whether elements tags will be rendered to string as <element></element> rather than <element/> 766 * @param boolean True if the expanded form is to be used 767 * @param mixed An array of tag names that should be excepted from expandEmptyElements rule (optional) 768 */ 769 function expandEmptyElementTags($truthVal, $expandEmptyElementExceptions = false) { 770 $this->doExpandEmptyElementTags = $truthVal; 771 772 if (is_array($expandEmptyElementExceptions)) { 773 $this->expandEmptyElementExceptions = $expandEmptyElementExceptions; 774 } 775 } //expandEmptyElementTags 776 777 /** 778 * Set the specified node as document element 779 * @param Object The node that is to become document element 780 * @return Object The new document element 781 */ 782 function &setDocumentElement(&$node) { 783 if ($node->nodeType == DOMIT_ELEMENT_NODE) { 784 if ($this->documentElement == null) { 785 parent::appendChild($node); 786 } 787 else { 788 parent::replaceChild($node, $this->documentElement); 789 } 790 791 $this->documentElement =& $node; 792 } 793 else { 794 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 795 ('Cannot add a node of type ' . get_class($node) . ' as a Document Element.')); 796 } 797 798 return $node; 799 } //setDocumentElement 800 801 /** 802 * Appends a node to the childNodes list of the current node 803 * @param Object The node to be appended 804 * @return Object The appended node 805 */ 806 function &appendChild(&$node) { 807 if ($node->nodeType == DOMIT_ELEMENT_NODE) { 808 if ($this->documentElement == null) { 809 parent::appendChild($node); 810 $this->setDocumentElement($node); 811 } 812 else { 813 //error thrown if documentElement already exists! 814 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 815 ('Cannot have more than one root node (documentElement) in a DOMIT_Document.')); 816 } 817 } 818 else { 819 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 820 ('Cannot add a node of type ' . get_class($node) . ' to a DOMIT_Document.')); 821 } 822 823 return $node; 824 } //appendChild 825 826 /** 827 * Replaces a node with another 828 * @param Object The new node 829 * @param Object The old node 830 * @return Object The new node 831 */ 832 function &replaceChild(&$newChild, &$oldChild) { 833 if (($this->documentElement != null) && ($oldChild->uid == $this->documentElement->uid)) { 834 if ($node->nodeType == DOMIT_ELEMENT_NODE) { 835 //replace documentElement with new node 836 $this->setDocumentElement($newChild); 837 } 838 else { 839 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 840 ('Cannot replace Document Element with a node of class ' . get_class($newChild))); 841 } 842 } 843 else { 844 if ($node->nodeType == DOMIT_ELEMENT_NODE) { 845 if ($this->documentElement != null) { 846 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 847 ('Cannot have more than one root node (documentElement) in a DOMIT_Document.')); 848 } 849 else { 850 parent::replaceChild($newChild, $oldChild); 851 } 852 } 853 else { 854 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 855 ('Nodes of class ' . get_class($newChild) . ' cannot be children of a DOMIT_Document.')); 856 } 857 } 858 859 return $newChild; 860 } //replaceChild 861 862 /** 863 * Inserts a node to the childNodes list of the current node 864 * @param Object The node to be inserted 865 * @param Object The node before which the insertion is to occur 866 * @return Object The inserted node 867 */ 868 function &insertBefore(&$newChild, &$refChild) { 869 $type = $newChild->nodeType; 870 871 if ($type == DOMIT_ELEMENT_NODE) { 872 if ($this->documentElement == null) { 873 parent::insertBefore($newChild, $refChild); 874 $this->setDocumentElement($newChild); 875 } 876 else { 877 //error thrown if documentElement already exists! 878 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 879 ('Cannot have more than one root node (documentElement) in a DOMIT_Document.')); 880 } 881 } 882 else { 883 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 884 ('Cannot insert a node of type ' . get_class($newChild) . ' to a DOMIT_Document.')); 885 } 886 887 return $newChild; 888 } //insertBefore 889 890 /** 891 * Removes a node from the childNodes list of the current node 892 * @param Object The node to be removed 893 * @return Object The removed node 894 */ 895 function &removeChild(&$oldChild) { 896 if (($this->documentElement != null) && ($oldChild->uid == $this->documentElement->uid)) { 897 parent::removeChild($oldChild); 898 $this->documentElement = null; 899 } 900 else { 901 parent::removeChild($oldChild); 902 } 903 904 $oldChild->clearReferences(); 905 return $oldChild; 906 } //removeChild 907 908 /** 909 * Creates a new DOMIT_Lite_Element node 910 * @param string The tag name of the element 911 * @return Object The new element 912 */ 913 function &createElement($tagName) { 914 $node = new DOMIT_Lite_Element($tagName); 915 $node->ownerDocument = $this; 916 917 $reference =& $node; 918 return $node; 919 } //createElement 920 921 /** 922 * Creates a new DOMIT_Text node 923 * @param string The text of the node 924 * @return Object The new text node 925 */ 926 function &createTextNode($data) { 927 $node = new DOMIT_Lite_TextNode($data); 928 $node->ownerDocument = $this; 929 930 $reference =& $node; 931 return $reference; 932 } //createTextNode 933 934 /** 935 * Creates a new DOMIT_Lite_CDATASection node 936 * @param string The text of the CDATASection 937 * @return Object The new CDATASection node 938 */ 939 function &createCDATASection($data) { 940 $node = new DOMIT_Lite_CDATASection($data); 941 $node->ownerDocument = $this; 942 943 return $node; 944 } //createCDATASection 945 946 /** 947 * Retrieves a NodeList of child elements with the specified tag name 948 * @param string The matching element tag name 949 * @return Object A NodeList of found elements 950 */ 951 function &getElementsByTagName($tagName) { 952 $nodeList = new DOMIT_NodeList(); 953 954 if ($this->documentElement != null) { 955 $this->documentElement->getNamedElements($nodeList, $tagName); 956 } 957 958 return $nodeList; 959 } //getElementsByTagName 960 961 /** 962 * Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like expression. 963 * @param string The query pattern 964 * @param int If a single node is to be returned (rather than the entire NodeList) the index of that node 965 * @return mixed A NodeList or single node that matches the pattern 966 */ 967 function &getElementsByPath($pattern, $nodeIndex = 0) { 968 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_getelementsbypath.php'); 969 970 $gebp = new DOMIT_GetElementsByPath(); 971 $myResponse =& $gebp->parsePattern($this, $pattern, $nodeIndex); 972 973 return $myResponse; 974 } //getElementsByPath 975 976 /** 977 * Parses an xml string; first encodes string as UTF-8 978 * @param string The xml text to be parsed 979 * @param boolean True if SAXY is to be used instead of Expat 980 * @param boolean False if CDATA Section are to be generated as Text nodes 981 * @param boolean True if onLoad is to be called on each node after parsing 982 * @return boolean True if parsing is successful 983 */ 984 function parseXML_utf8($xmlText, $useSAXY = true, $preserveCDATA = true, $fireLoadEvent = false) { 985 return $this->parseXML(utf8_encode($xmlText), $useSAXY, $preserveCDATA, $fireLoadEvent); 986 } //parseXML_utf8 987 988 /** 989 * Parses an xml string 990 * @param string The xml text to be parsed 991 * @param boolean True if SAXY is to be used instead of Expat 992 * @param boolean False if CDATA Section are to be generated as Text nodes 993 * @param boolean True if onLoad is to be called on each node after parsing 994 * @return boolean True if parsing is successful 995 */ 996 function parseXML($xmlText, $useSAXY = true, $preserveCDATA = true, $fireLoadEvent = false) { 997 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); 998 999 if ($this->doResolveErrors) { 1000 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_doctor.php'); 1001 $xmlText = DOMIT_Doctor::fixAmpersands($xmlText); 1002 } 1003 1004 if (DOMIT_Utilities::validateXML($xmlText)) { 1005 $domParser = new DOMIT_Lite_Parser(); 1006 1007 if ($useSAXY || (!function_exists('xml_parser_create'))) { 1008 //use SAXY parser to populate xml tree 1009 $this->parser = 'SAXY_LITE'; 1010 $success = $domParser->parseSAXY($this, $xmlText, $preserveCDATA, $this->definedEntities); 1011 } 1012 else { 1013 //use Expat parser to populate xml tree 1014 $this->parser = 'EXPAT'; 1015 $success = $domParser->parse($this, $xmlText, $preserveCDATA); 1016 } 1017 1018 if ($fireLoadEvent && ($this->documentElement != null)) $this->load($this->documentElement); 1019 1020 return $success; 1021 } 1022 1023 return false; 1024 } //parseXML 1025 1026 /** 1027 * Parses an xml file; first encodes text as UTF-8 1028 * @param string The xml file to be parsed 1029 * @param boolean True if SAXY is to be used instead of Expat 1030 * @param boolean False if CDATA Section are to be generated as Text nodes 1031 * @param boolean True if onLoad is to be called on each node after parsing 1032 * @return boolean True if parsing is successful 1033 */ 1034 function loadXML_utf8($filename, $useSAXY = true, $preserveCDATA = true, $fireLoadEvent = false) { 1035 $xmlText = $this->getTextFromFile($filename); 1036 return $this->parseXML_utf8($xmlText, $useSAXY, $preserveCDATA, $fireLoadEvent); 1037 } //loadXML_utf8 1038 1039 /** 1040 * Parses an xml file 1041 * @param string The xml file to be parsed 1042 * @param boolean True if SAXY is to be used instead of Expat 1043 * @param boolean False if CDATA Section are to be generated as Text nodes 1044 * @param boolean True if onLoad is to be called on each node after parsing 1045 * @return boolean True if parsing is successful 1046 */ 1047 function loadXML($filename, $useSAXY = true, $preserveCDATA = true, $fireLoadEvent = false) { 1048 $xmlText = $this->getTextFromFile($filename); 1049 return $this->parseXML($xmlText, $useSAXY, $preserveCDATA, $fireLoadEvent); 1050 } //loadXML 1051 1052 /** 1053 * Establishes a connection, given an url 1054 * @param string The url of the data 1055 */ 1056 function establishConnection($url) { 1057 require_once (DOMIT_INCLUDE_PATH . 'php_http_client_generic.php'); 1058 1059 $host = php_http_connection::formatHost($url); 1060 $host = substr($host, 0, strpos($host, '/')); 1061 1062 $this->setConnection($host); 1063 } //establishConnection 1064 1065 /** 1066 * Retrieves text from a file 1067 * @param string The file path 1068 * @return string The text contained in the file 1069 */ 1070 function getTextFromFile($filename) { 1071 if ($this->doUseHTTPClient && (substr($filename, 0, 5) == 'http:')) { 1072 $this->establishConnection($filename); 1073 } 1074 1075 if ($this->httpConnection != null) { 1076 $response =& $this->httpConnection->get($filename); 1077 $this->httpConnection->disconnect(); 1078 return $response->getResponse(); 1079 } 1080 else if (function_exists('file_get_contents')) { 1081 //if (file_exists($filename)) { 1082 return file_get_contents($filename); 1083 //} 1084 } 1085 else { 1086 require_once (DOMIT_INCLUDE_PATH . 'php_file_utilities.php'); 1087 1088 $fileContents =& php_file_utilities::getDataFromFile($filename, 'r'); 1089 return $fileContents; 1090 } 1091 1092 return ''; 1093 } //getTextFromFile 1094 1095 /** 1096 * Saves the current DOM document as an xml file; first encodes text as UTF-8 1097 * @param string The path of the xml file 1098 * @param boolean True if xml text is to be normalized before saving 1099 * @return boolean True if save is successful 1100 */ 1101 function saveXML_utf8($filename, $normalized=false) { 1102 if ($normalized) { 1103 $stringRep = $this->toNormalizedString(false, true); //param 2 is $subEntities 1104 } 1105 else { 1106 $stringRep = $this->toString(false, true); 1107 } 1108 1109 return $this->saveTextToFile($filename, utf8_encode($stringRep)); 1110 } //saveXML_utf8 1111 1112 /** 1113 * Saves the current DOM document as an xml file 1114 * @param string The path of the xml file 1115 * @param boolean True if xml text is to be normalized before saving 1116 * @return boolean True if save is successful 1117 */ 1118 function saveXML($filename, $normalized=false) { 1119 if ($normalized) { 1120 $stringRep = $this->toNormalizedString(false, true); 1121 } 1122 else { 1123 $stringRep = $this->toString(false, true); 1124 } 1125 if ($this->xmlDeclaration) { 1126 $stringRep = $this->xmlDeclaration . "\n" . $stringRep; 1127 } 1128 return $this->saveTextToFile($filename, $stringRep); 1129 } //saveXML 1130 1131 /** 1132 * Saves text to a file 1133 * @param string The file path 1134 * @param string The text to be saved 1135 * @return boolean True if the save is successful 1136 */ 1137 function saveTextToFile($filename, $text) { 1138 if (function_exists('file_put_contents')) { 1139 file_put_contents($filename, $text); 1140 } 1141 else { 1142 require_once (DOMIT_INCLUDE_PATH . 'php_file_utilities.php'); 1143 php_file_utilities::putDataToFile($filename, $text, 'w'); 1144 } 1145 1146 return (file_exists($filename) && is_writable($filename)); 1147 } //saveTextToFile 1148 1149 /** 1150 * Indicates the SAX parser used to parse the current document 1151 * @return string Either "SAXY_LITE" or "EXPAT" 1152 */ 1153 function parsedBy() { 1154 return $this->parser; 1155 } //parsedBy 1156 1157 /** 1158 * Returns the concatented text of the current node and its children 1159 * @return string The concatented text of the current node and its children 1160 */ 1161 function getText() { 1162 if ($this->documentElement != null) { 1163 $root =& $this->documentElement; 1164 return $root->getText(); 1165 } 1166 1167 return ''; 1168 } //getText 1169 1170 /** 1171 * Returns the doctype text 1172 * @return string The doctype text, or an emty string 1173 */ 1174 function getDocType() { 1175 return $this->doctype; 1176 } //getDocType 1177 1178 /** 1179 * Returns the xml declaration text 1180 * @return mixed The xml declaration text, or an empty string 1181 */ 1182 function getXMLDeclaration() { 1183 return $this->xmlDeclaration; 1184 } //getXMLDeclaration 1185 1186 /** 1187 * Returns the xml declaration text 1188 * @return mixed The xml declaration text, or an empty string 1189 */ 1190 function setXMLDeclaration( $decl ) { 1191 $this->xmlDeclaration = $decl; 1192 } //setXMLDeclaration 1193 1194 /** 1195 * Returns a reference to the DOMIT_DOMImplementation object 1196 * @return Object A reference to the DOMIT_DOMImplementation object 1197 */ 1198 function &getDOMImplementation() { 1199 return $this->implementation; 1200 } //getDOMImplementation 1201 1202 /** 1203 * Manages the firing of the onLoad() event 1204 * @param Object The parent node of the current recursion 1205 */ 1206 function load(&$contextNode) { 1207 $total = $contextNode->childCount; 1208 1209 for ($i = 0; $i < $total; $i++) { 1210 $currNode =& $contextNode->childNodes[$i]; 1211 $currNode->ownerDocument->load($currNode); 1212 } 1213 1214 $contextNode->onLoad(); 1215 } //load 1216 1217 /** 1218 * Returns the current version of DOMIT! Lite 1219 * @return Object The current version of DOMIT! Lite 1220 */ 1221 function getVersion() { 1222 return DOMIT_LITE_VERSION; 1223 } //getVersion 1224 1225 /** 1226 * Appends an array of entity mappings to the existing translation table 1227 * 1228 * Intended mainly to facilitate the conversion of non-ASCII entities into equivalent characters 1229 * 1230 * @param array A list of entity mappings in the format: array('&' => '&'); 1231 */ 1232 function appendEntityTranslationTable($table) { 1233 $this->definedEntities = $table; 1234 1235 global $DOMIT_defined_entities_flip; 1236 $DOMIT_defined_entities_flip = array_flip($table); 1237 } //appendEntityTranslationTable 1238 1239 /** 1240 * Generates an array representation of the node and its children 1241 * @return Array A representation of the node and its children 1242 */ 1243 function toArray() { 1244 $arReturn = array($this->nodeName => array()); 1245 $total = $this->childCount; 1246 1247 for ($i = 0; $i < $total; $i++) { 1248 $arReturn[$this->nodeName][$i] = $this->childNodes[$i]->toArray(); 1249 } 1250 1251 return $arReturn; 1252 } //toArray 1253 1254 /** 1255 * Copies a node and/or its children 1256 * @param boolean True if all child nodes are also to be cloned 1257 * @return Object A copy of the node and/or its children 1258 */ 1259 function &cloneNode($deep = false) { 1260 $className = get_class($this); 1261 $clone = new $className($this->nodeName); 1262 1263 if ($deep) { 1264 $total = $this->childCount; 1265 1266 for ($i = 0; $i < $total; $i++) { 1267 $currentChild =& $this->childNodes[$i]; 1268 $clone->appendChild($currentChild->cloneNode($deep)); 1269 } 1270 } 1271 1272 return $clone; 1273 } //cloneNode 1274 1275 /** 1276 * Generates a string representation of the node and its children 1277 * @param boolean True if HTML readable output is desired 1278 * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities 1279 * @return string The string representation 1280 */ 1281 function toString($htmlSafe = false, $subEntities = false) { 1282 $result = ''; 1283 $total = $this->childCount; 1284 1285 for ($i = 0; $i < $total; $i++) { 1286 $result .= $this->childNodes[$i]->toString(false, $subEntities); 1287 } 1288 1289 if ($htmlSafe) $result = $this->forHTML($result); 1290 1291 return $result; 1292 } //toString 1293 } //DOMIT_Lite_Document 1294 1295 /** 1296 * A class representing the DOM Element 1297 * 1298 * @package domit-xmlparser 1299 * @subpackage domit-xmlparser-lite 1300 * @author John Heinstein <johnkarl@nbnet.nb.ca> 1301 */ 1302 class DOMIT_Lite_Element extends DOMIT_Lite_ChildNodes_Interface { 1303 /** 1304 * DOM Element constructor 1305 * @param string The tag name of the element 1306 */ 1307 function DOMIT_Lite_Element($tagName) { 1308 $this->_constructor(); 1309 $this->nodeType = DOMIT_ELEMENT_NODE; 1310 $this->nodeName = $tagName; 1311 $this->attributes = array(); 1312 $this->childNodes = array(); 1313 } //DOMIT_Lite_Element 1314 1315 /** 1316 * Returns the tag name of the element 1317 * @return string The tag name of the element 1318 */ 1319 function getTagName() { 1320 return $this->nodeName; 1321 } //getTagName 1322 1323 /** 1324 * Adds elements with the specified tag name to a NodeList collection 1325 * @param Object The NodeList collection 1326 * @param string The tag name of matching elements 1327 */ 1328 function getNamedElements(&$nodeList, $tagName) { 1329 if (($this->nodeName == $tagName) || ($tagName == '*')) { 1330 $nodeList->appendNode($this); 1331 } 1332 1333 $total = $this->childCount; 1334 1335 for ($i = 0; $i < $total; $i++) { 1336 $this->childNodes[$i]->getNamedElements($nodeList, $tagName); 1337 } 1338 } //getNamedElements 1339 1340 /** 1341 * Returns the concatented text of the current node and its children 1342 * @return string The concatented text of the current node and its children 1343 */ 1344 function getText() { 1345 $text = ''; 1346 $numChildren = $this->childCount; 1347 1348 for ($i = 0; $i < $numChildren; $i++) { 1349 $child =& $this->childNodes[$i]; 1350 $text .= $child->getText(); 1351 } 1352 1353 return $text; 1354 } //getText 1355 1356 /** 1357 * If a child text node exists, sets the nodeValue to $data. A child text node is created if none exists 1358 * @param string The text data of the node 1359 */ 1360 function setText($data) { 1361 switch ($this->childCount) { 1362 case 1: 1363 if ($this->firstChild->nodeType == DOMIT_TEXT_NODE) { 1364 $this->firstChild->setText($data); 1365 } 1366 break; 1367 1368 case 0: 1369 $childTextNode =& $this->ownerDocument->createTextNode($data); 1370 $this->appendChild($childTextNode); 1371 break; 1372 1373 default: 1374 //do nothing. Maybe throw error??? 1375 } 1376 } //setText 1377 1378 /** 1379 * Retrieves a NodeList of child elements with the specified tag name 1380 * @param string The matching element tag name 1381 * @return Object A NodeList of found elements 1382 */ 1383 function &getElementsByTagName($tagName) { 1384 $nodeList = new DOMIT_NodeList(); 1385 $this->getNamedElements($nodeList, $tagName); 1386 1387 return $nodeList; 1388 } //getElementsByTagName 1389 1390 /** 1391 * Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like expression. 1392 * @param string The query pattern 1393 * @param int If a single node is to be returned (rather than the entire NodeList) the index of that node 1394 * @return mixed A NodeList or single node that matches the pattern 1395 */ 1396 function &getElementsByPath($pattern, $nodeIndex = 0) { 1397 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_getelementsbypath.php'); 1398 1399 $gebp = new DOMIT_GetElementsByPath(); 1400 $myResponse = $gebp->parsePattern($this, $pattern, $nodeIndex); 1401 1402 return $myResponse; 1403 } //getElementsByPath 1404 1405 /** 1406 * Gets the value of the specified attribute, if it exists 1407 * @param string The attribute name 1408 * @return string The attribute value 1409 */ 1410 function getAttribute($name) { 1411 if ($this->hasAttribute($name)) { 1412 return $this->attributes[$name]; 1413 } 1414 else { 1415 /* 1416 DOMIT_DOMException::raiseException(DOMIT_NOT_FOUND_ERR, 1417 ('No attribute named ' . $name . 'exists.')); 1418 */ 1419 // Joomla! hack 1420 return null; 1421 } 1422 } //getAttribute 1423 1424 /** 1425 * Sets the value of the specified attribute; creates a new attribute if one doesn't exist 1426 * @param string The attribute name 1427 * @param string The desired attribute value 1428 */ 1429 function setAttribute($name, $value) { 1430 $this->attributes[$name] = $value; 1431 } //setAttribute 1432 1433 /** 1434 * Removes the specified attribute 1435 * @param string The name of the attribute to be removed 1436 */ 1437 function removeAttribute($name) { 1438 if ($this->hasAttribute($name)) { 1439 unset($this->attributes[$name]); 1440 } 1441 } //removeAttribute 1442 1443 /** 1444 * Determines whether an attribute with the specified name exists 1445 * @param string The name of the attribute 1446 * @return boolean True if the attribute exists 1447 */ 1448 function hasAttribute($name) { 1449 return isset($this->attributes[$name]); 1450 } //hasAttribute 1451 1452 /** 1453 * Collapses adjacent text nodes in entire element subtree 1454 */ 1455 function normalize() { 1456 if ($this->hasChildNodes()) { 1457 $currNode =& $this->childNodes[0]; 1458 1459 while ($currNode->nextSibling != null) { 1460 $nextNode =& $currNode->nextSibling; 1461 1462 if (($currNode->nodeType == DOMIT_TEXT_NODE) && 1463 ($nextNode->nodeType == DOMIT_TEXT_NODE)) { 1464 $currNode->nodeValue .= $nextNode->nodeValue; 1465 $this->removeChild($nextNode); 1466 } 1467 else { 1468 $currNode->normalize(); 1469 } 1470 1471 if ($currNode->nextSibling != null) { 1472 $currNode =& $currNode->nextSibling; 1473 } 1474 } 1475 } 1476 } //normalize 1477 1478 /** 1479 * Generates an array representation of the node and its children 1480 * @return Array A representation of the node and its children 1481 */ 1482 function toArray() { 1483 $arReturn = array($this->nodeName => array("attributes" => $this->attributes)); 1484 $total = $this->childCount; 1485 1486 for ($i = 0; $i < $total; $i++) { 1487 $arReturn[$this->nodeName][$i] = $this->childNodes[$i]->toArray(); 1488 } 1489 1490 return $arReturn; 1491 } //toArray 1492 1493 /** 1494 * Copies a node and/or its children 1495 * @param boolean True if all child nodes are also to be cloned 1496 * @return Object A copy of the node and/or its children 1497 */ 1498 function &cloneNode($deep = false) { 1499 $className = get_class($this); 1500 $clone = new $className($this->nodeName); 1501 1502 $clone->attributes = $this->attributes; 1503 1504 if ($deep) { 1505 $total = $this->childCount; 1506 1507 for ($i = 0; $i < $total; $i++) { 1508 $currentChild =& $this->childNodes[$i]; 1509 $clone->appendChild($currentChild->cloneNode($deep)); 1510 } 1511 } 1512 1513 return $clone; 1514 } //cloneNode 1515 1516 /** 1517 * Generates a string representation of the node and its children 1518 * @param boolean True if HTML readable output is desired 1519 * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities 1520 * @return string The string representation 1521 */ 1522 function toString($htmlSafe = false, $subEntities = false) { 1523 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); 1524 global $DOMIT_defined_entities_flip; 1525 1526 $result = '<' . $this->nodeName; 1527 1528 //get attributes 1529 foreach ($this->attributes as $key => $value) { 1530 $result .= ' ' . $key . '="'; 1531 $result .= $subEntities ? DOMIT_Utilities::convertEntities($value, 1532 $DOMIT_defined_entities_flip) : $value; 1533 $result .= '"'; 1534 } 1535 1536 //get children 1537 $myNodes =& $this->childNodes; 1538 $total = count($myNodes); 1539 1540 if ($total != 0) { 1541 $result .= '>'; 1542 1543 for ($i = 0; $i < $total; $i++) { 1544 $child =& $myNodes[$i]; 1545 $result .= $child->toString(false, $subEntities); 1546 } 1547 1548 $result .= '</' . $this->nodeName . '>'; 1549 } 1550 else { 1551 if ($this->ownerDocument->doExpandEmptyElementTags) { 1552 if (in_array($this->nodeName, $this->ownerDocument->expandEmptyElementExceptions)) { 1553 $result .= ' />'; 1554 } 1555 else { 1556 $result .= '></' . $this->nodeName . '>'; 1557 } 1558 } 1559 else { 1560 if (in_array($this->nodeName, $this->ownerDocument->expandEmptyElementExceptions)) { 1561 $result .= '></' . $this->nodeName . '>'; 1562 } 1563 else { 1564 $result .= ' />'; 1565 } 1566 } 1567 } 1568 1569 if ($htmlSafe) $result = $this->forHTML($result); 1570 1571 return $result; 1572 } //toString 1573 } //DOMIT_Lite_Element 1574 1575 /** 1576 * A class representing the DOM Text Node 1577 * 1578 * @package domit-xmlparser 1579 * @subpackage domit-xmlparser-lite 1580 * @author John Heinstein <johnkarl@nbnet.nb.ca> 1581 */ 1582 class DOMIT_Lite_TextNode extends DOMIT_Lite_Node { 1583 /** 1584 * DOM Text Node constructor 1585 * @param string The text of the node 1586 */ 1587 function DOMIT_Lite_TextNode($data) { 1588 $this->_constructor(); 1589 $this->nodeType = DOMIT_TEXT_NODE; 1590 $this->nodeName = '#text'; 1591 $this->setText($data); 1592 } //DOMIT_Lite_TextNode 1593 1594 /** 1595 * Returns the text contained in the current node 1596 * @return string The text of the current node 1597 */ 1598 function getText() { 1599 return $this->nodeValue; 1600 } //getText 1601 1602 /** 1603 * Sets the text contained in the current node to $data. 1604 * @param string The text data of the node 1605 */ 1606 function setText($data) { 1607 $this->nodeValue = $data; 1608 } //setText 1609 1610 /** 1611 * Generates an array representation of the node and its children 1612 * @return Array A representation of the node and its children 1613 */ 1614 function toArray() { 1615 return $this->toString(); 1616 } //toArray 1617 1618 /** 1619 * Copies a node and/or its children 1620 * @param boolean True if all child nodes are also to be cloned 1621 * @return Object A copy of the node and/or its children 1622 */ 1623 function &cloneNode($deep = false) { 1624 $className = get_class($this); 1625 $clone = new $className($this->nodeValue); 1626 1627 return $clone; 1628 } //cloneNode 1629 1630 /** 1631 * Generates a string representation of the node and its children 1632 * @param boolean True if HTML readable output is desired 1633 * @param boolean True if illegal xml characters should be converted to entities 1634 * @return string The string representation 1635 */ 1636 function toString($htmlSafe = false, $subEntities = false) { 1637 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); 1638 global $DOMIT_defined_entities_flip; 1639 1640 $result = $subEntities ? DOMIT_Utilities::convertEntities($this->nodeValue, 1641 $DOMIT_defined_entities_flip) : $this->nodeValue; 1642 1643 if ($htmlSafe) $result = $this->forHTML($result); 1644 1645 return $result; 1646 } //toString 1647 } //DOMIT_Lite_TextNode 1648 1649 /** 1650 * A class representing the DOM CDATA Section 1651 * 1652 * @package domit-xmlparser 1653 * @subpackage domit-xmlparser-lite 1654 * @author John Heinstein <johnkarl@nbnet.nb.ca> 1655 */ 1656 class DOMIT_Lite_CDATASection extends DOMIT_Lite_TextNode { 1657 /** 1658 * DOM CDATA Section node constructor 1659 * @param string The text of the node 1660 */ 1661 function DOMIT_Lite_CDATASection($data) { 1662 $this->_constructor(); 1663 $this->nodeType = DOMIT_CDATA_SECTION_NODE; 1664 $this->nodeName = '#cdata-section'; 1665 $this->setText($data); 1666 } //DOMIT_Lite_CDATASection 1667 1668 /** 1669 * Generates a string representation of the node and its children 1670 * @param boolean True if HTML readable output is desired 1671 * @param boolean True if illegal xml characters should be converted to entities 1672 * @return string The string representation 1673 */ 1674 function toString($htmlSafe = false, $subEntities = false) { 1675 $result = '<![CDATA['; 1676 $result .= $subEntities ? str_replace("]]>", "]]>", $this->nodeValue) : 1677 $this->nodeValue; 1678 $result .= ']]>'; 1679 1680 if ($htmlSafe) $result = $this->forHTML($result); 1681 1682 return $result; 1683 } //toString 1684 } //DOMIT_Lite_CDATASection 1685 1686 /** 1687 * Manages the generation of a DOMIT! document from SAX events 1688 * 1689 * @package domit-xmlparser 1690 * @subpackage domit-xmlparser-lite 1691 * @author John Heinstein <johnkarl@nbnet.nb.ca> 1692 */ 1693 class DOMIT_Lite_Parser { 1694 /** @var Object A reference to the resulting xmldoc */ 1695 var $xmlDoc = null; 1696 /** @var Object A reference to the current node in the parsing process */ 1697 var $currentNode = null; 1698 /** @var Object A reference to the last child in the parsing process */ 1699 var $lastChild = null; 1700 /** @var boolean True if currently parsing a CDATA Section */ 1701 var $inCDATASection = false; //flag for Expat 1702 /** @var boolean True if currently parsing a Text node */ 1703 var $inTextNode = false; 1704 /** @var boolean True is CDATA Section nodes are not to be converted into Text nodes */ 1705 var $preserveCDATA; 1706 /** @var string A container for holding the currently parsed text data */ 1707 var $parseContainer = ''; 1708 /** @var string The current docutype text */ 1709 var $parseItem = ''; 1710 1711 /** 1712 * Parses xml text using Expat 1713 * @param Object A reference to the DOM document that the xml is to be parsed into 1714 * @param string The text to be parsed 1715 * @param boolean True if CDATA Section nodes are not to be converted into Text nodes 1716 * @return boolean True if the parsing is successful 1717 */ 1718 function parse (&$myXMLDoc, $xmlText, $preserveCDATA = true) { 1719 $this->xmlDoc =& $myXMLDoc; 1720 $this->lastChild =& $this->xmlDoc; 1721 1722 $this->preserveCDATA = $preserveCDATA; 1723 1724 //create instance of expat parser (should be included in php distro) 1725 if (version_compare(phpversion(), '5.0', '<=')) { 1726 $parser = xml_parser_create(''); 1727 } 1728 else { 1729 $parser = xml_parser_create(); 1730 } 1731 1732 //set handlers for SAX events 1733 xml_set_object($parser, $this); 1734 xml_set_element_handler($parser, 'startElement', 'endElement'); 1735 xml_set_character_data_handler($parser, 'dataElement'); 1736 xml_set_default_handler($parser, 'defaultDataElement'); 1737 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 1738 1739 if (!$this->xmlDoc->preserveWhitespace) { 1740 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 1741 } 1742 else { 1743 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); 1744 } 1745 1746 //parse out whitespace - (XML_OPTION_SKIP_WHITE = 1 does not 1747 //seem to work consistently across versions of PHP and Expat 1748 if (!$this->xmlDoc->preserveWhitespace) { 1749 $xmlText = preg_replace('#>' . "[[:space:]]+" . '<#i' , '><', $xmlText); 1750 } 1751 1752 $success = xml_parse($parser, $xmlText); 1753 1754 $this->xmlDoc->errorCode = xml_get_error_code($parser); 1755 $this->xmlDoc->errorString = xml_error_string($this->xmlDoc->errorCode); 1756 1757 xml_parser_free($parser); 1758 1759 return $success; 1760 } //parse 1761 1762 /** 1763 * Parses xml text using SAXY 1764 * @param Object A reference to the DOM document that the xml is to be parsed into 1765 * @param string The text to be parsed 1766 * @param boolean True if CDATA Section nodes are not to be converted into Text nodes 1767 * @return boolean True if the parsing is successful 1768 */ 1769 function parseSAXY(&$myXMLDoc, $xmlText, $preserveCDATA, $definedEntities) { 1770 require_once (DOMIT_INCLUDE_PATH . 'xml_saxy_lite_parser.php'); 1771 1772 $this->xmlDoc =& $myXMLDoc; 1773 $this->lastChild =& $this->xmlDoc; 1774 1775 //create instance of SAXY parser 1776 $parser = new SAXY_Lite_Parser(); 1777 $parser->appendEntityTranslationTable($definedEntities); 1778 1779 //not yet implemented in SAXY!!! 1780 $parser->preserveWhitespace = $this->xmlDoc->preserveWhitespace; 1781 1782 $parser->xml_set_element_handler(array(&$this, 'startElement'), array(&$this, 'endElement')); 1783 $parser->xml_set_character_data_handler(array(&$this, 'dataElement')); 1784 1785 if ($preserveCDATA) { 1786 $parser->xml_set_cdata_section_handler(array(&$this, 'cdataElement')); 1787 } 1788 1789 $success = $parser->parse($xmlText); 1790 1791 $this->xmlDoc->errorCode = $parser->xml_get_error_code(); 1792 $this->xmlDoc->errorString = $parser->xml_error_string($this->xmlDoc->errorCode); 1793 1794 return $success; 1795 } //parseSAXY 1796 1797 /** 1798 * Generates and appends a new text node from the parseContainer text 1799 */ 1800 function dumpTextNode() { 1801 //traps for mixed content 1802 $currentNode =& $this->xmlDoc->createTextNode($this->parseContainer); 1803 $this->lastChild->appendChild($currentNode); 1804 $this->inTextNode = false; 1805 $this->parseContainer = ''; 1806 } //dumpTextNode 1807 1808 /** 1809 * Catches a start element event and processes the data 1810 * @param Object A reference to the current SAX parser 1811 * @param string The tag name of the current element 1812 * @param Array An array of the element attributes 1813 */ 1814 function startElement(&$parser, $name, $attrs) { 1815 if ($this->inTextNode) { 1816 $this->dumpTextNode(); 1817 } 1818 1819 $currentNode =& $this->xmlDoc->createElement($name); 1820 $currentNode->attributes = $attrs; 1821 $this->lastChild->appendChild($currentNode); 1822 $this->lastChild =& $currentNode; 1823 } //startElement 1824 1825 /** 1826 * Catches an end element event and processes the data 1827 * @param Object A reference to the current SAX parser 1828 * @param string The tag name of the current element 1829 */ 1830 function endElement(&$parser, $name) { 1831 if ($this->inTextNode) { 1832 $this->dumpTextNode(); 1833 } 1834 1835 $this->lastChild =& $this->lastChild->parentNode; 1836 } //endElement 1837 1838 /** 1839 * Catches a data event and processes the text 1840 * @param Object A reference to the current SAX parser 1841 * @param string The current text data 1842 */ 1843 function dataElement(&$parser, $data) { 1844 if (!$this->inCDATASection) $this->inTextNode = true; 1845 1846 $this->parseContainer .= $data; 1847 } //dataElement 1848 1849 /** 1850 * Catches a CDATA Section event and processes the text 1851 * @param Object A reference to the current SAX parser 1852 * @param string The current text data 1853 */ 1854 function cdataElement(&$parser, $data) { 1855 $currentNode =& $this->xmlDoc->createCDATASection($data); 1856 1857 $this->lastChild->appendChild($currentNode); 1858 } //cdataElement 1859 1860 /** 1861 * Catches a default data event and processes the data 1862 * @param Object A reference to the current SAX parser 1863 * @param string The current data 1864 */ 1865 function defaultDataElement(&$parser, $data) { 1866 if (strlen($data) > 2){ 1867 $pre = strtoupper(substr($data, 0, 3)); 1868 1869 switch ($pre) { 1870 case '<![': //cdata section coming 1871 if ($this->preserveCDATA) { 1872 $this->inCDATASection = true; 1873 } 1874 break; 1875 case ']]>': //cdata remnant - ignore 1876 if ($this->preserveCDATA) { 1877 $currentNode =& $this->xmlDoc->createCDATASection($this->parseContainer); 1878 $this->lastChild->appendChild($currentNode); 1879 $this->inCDATASection = false; 1880 $this->parseContainer = ''; 1881 } 1882 else { 1883 $this->dumpTextNode(); 1884 } 1885 1886 break; 1887 } 1888 } 1889 } //defaultDataElement 1890 } //DOMIT_Lite_Parser 1891 1892 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Mar 28 15:54:07 2012 | Cross-referenced by PHPXref 0.7.1 |