[ Index ] |
|
Code source de Joomla 1.0.13 |
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 return null; 584 } 585 586 return $nodelist; 587 } //getElementsByAttribute 588 589 /** 590 * Searches the element tree for an element with the specified attribute name and value. 591 * @param object The node list of found elements 592 * @param string The value of the attribute 593 * @param string The name of the attribute 594 * @param boolean True if the first found node is to be returned as a node instead of a nodelist 595 * @param boolean True if uid is to be considered an attribute 596 * @param boolean True the node has been found 597 */ 598 function _getElementsByAttribute(&$nodelist, $attrName, $attrValue, 599 $returnFirstFoundNode, $treatUIDAsAttribute, $foundNode = false) { 600 if (!($foundNode && $returnFirstFoundNode)) { 601 if (($this->getAttribute($attrName) == $attrValue) || 602 ($treatUIDAsAttribute && ($attrName == 'uid') && ($this->uid == $attrValue))) { 603 $nodelist->appendNode($this); 604 $foundNode = true; 605 if ($returnFirstFoundNode) return; 606 } 607 608 $total = $this->childCount; 609 610 for ($i = 0; $i < $total; $i++) { 611 $currNode =& $this->childNodes[$i]; 612 613 if ($currNode->nodeType == DOMIT_ELEMENT_NODE) { 614 $currNode->_getElementsByAttribute($nodelist, 615 $attrName, $attrValue, $returnFirstFoundNode, 616 $treatUIDAsAttribute, $foundNode); 617 } 618 } 619 } 620 } //_getElementsByAttribute 621 } //DOMIT_Lite_ChildNodes_Interface 622 623 /** 624 * A class representing the DOM Document 625 * 626 * @package domit-xmlparser 627 * @subpackage domit-xmlparser-lite 628 * @author John Heinstein <johnkarl@nbnet.nb.ca> 629 */ 630 class DOMIT_Lite_Document extends DOMIT_Lite_ChildNodes_Interface { 631 /** @var string The xml declaration text */ 632 var $xmlDeclaration; 633 /** @var string The doctype text */ 634 var $doctype; 635 /** @var Object A reference to the root node of the DOM document */ 636 var $documentElement; 637 /** @var string The parser used to process the DOM document, either "EXPAT" or "SAXY_LITE" */ 638 var $parser; 639 /** @var Object A reference to the DOMIT_DOMImplementation object */ 640 var $implementation; 641 /** @var Array User defined translation table for XML entities */ 642 var $definedEntities = array(); 643 /** @var boolean If true, loadXML or parseXML will attempt to detect and repair invalid xml */ 644 var $doResolveErrors = false; 645 /** @var boolean True if whitespace is to be preserved during parsing */ 646 var $preserveWhitespace = false; 647 /** @var boolean If true, elements tags will be rendered to string as <element></element> rather than <element/> */ 648 var $doExpandEmptyElementTags = false; 649 /** @var array A list of exceptions to the empty element expansion rule */ 650 var $expandEmptyElementExceptions = array(); 651 /** @var int The error code returned by the SAX parser */ 652 var $errorCode = 0; 653 /** @var string The error string returned by the SAX parser */ 654 var $errorString = ''; 655 /** @var object A reference to a http connection or proxy server, if one is required */ 656 var $httpConnection = null; 657 /** @var boolean True if php_http_client_generic is to be used instead of PHP get_file_contents to retrieve xml data */ 658 var $doUseHTTPClient = false; 659 660 /** 661 * DOM Document constructor 662 */ 663 function DOMIT_Lite_Document() { 664 $this->_constructor(); 665 $this->xmlDeclaration = ''; 666 $this->doctype = ''; 667 $this->documentElement = null; 668 $this->nodeType = DOMIT_DOCUMENT_NODE; 669 $this->nodeName = '#document'; 670 $this->ownerDocument =& $this; 671 $this->parser = ''; 672 $this->implementation = new DOMIT_DOMImplementation(); 673 } //DOMIT_Lite_Document 674 675 /** 676 * Specifies whether DOMIT! Lite will try to fix invalid XML before parsing begins 677 * @param boolean True if errors are to be resolved 678 */ 679 function resolveErrors($truthVal) { 680 $this->doResolveErrors = $truthVal; 681 } //resolveErrors 682 683 /** 684 * Specifies the parameters of the http conection used to obtain the xml data 685 * @param string The ip address or domain name of the connection 686 * @param string The path of the connection 687 * @param int The port that the connection is listening on 688 * @param int The timeout value for the connection 689 * @param string The user name, if authentication is required 690 * @param string The password, if authentication is required 691 */ 692 function setConnection($host, $path = '/', $port = 80, $timeout = 0, $user = null, $password = null) { 693 require_once (DOMIT_INCLUDE_PATH . 'php_http_client_generic.php'); 694 695 $this->httpConnection = new php_http_client_generic($host, $path, $port, $timeout, $user, $password); 696 } //setConnection 697 698 /** 699 * Specifies whether DOMIT! preserves whitespace when parsing 700 * @param boolean True if whitespace is to be preserved 701 */ 702 function preserveWhitespace($truthVal) { 703 $this->preserveWhitespace = $truthVal; 704 } //preserveWhitespace 705 706 /** 707 * Specifies basic authentication for an http connection 708 * @param string The user name 709 * @param string The password 710 */ 711 function setAuthorization($user, $password) { 712 $this->httpConnection->setAuthorization($user, $password); 713 } //setAuthorization 714 715 /** 716 * Specifies that a proxy is to be used to obtain the xml data 717 * @param string The ip address or domain name of the proxy 718 * @param string The path to the proxy 719 * @param int The port that the proxy is listening on 720 * @param int The timeout value for the connection 721 * @param string The user name, if authentication is required 722 * @param string The password, if authentication is required 723 */ 724 function setProxyConnection($host, $path = '/', $port = 80, $timeout = 0, $user = null, $password = null) { 725 require_once (DOMIT_INCLUDE_PATH . 'php_http_proxy.php'); 726 727 $this->httpConnection = new php_http_proxy($host, $path, $port, $timeout, $user, $password); 728 } //setProxyConnection 729 730 /** 731 * Specifies basic authentication for the proxy 732 * @param string The user name 733 * @param string The password 734 */ 735 function setProxyAuthorization($user, $password) { 736 $this->httpConnection->setProxyAuthorization($user, $password); 737 } //setProxyAuthorization 738 739 /** 740 * Specifies whether an HTTP client should be used to establish a connection 741 * @param boolean True if an HTTP client is to be used to establish the connection 742 */ 743 function useHTTPClient($truthVal) { 744 $this->doUseHTTPClient = $truthVal; 745 } //useHTTPClient 746 747 /** 748 * Returns the error code from the underlying SAX parser 749 * @return int The error code 750 */ 751 function getErrorCode() { 752 return $this->errorCode; 753 } //getErrorCode 754 755 /** 756 * Returns the error string from the underlying SAX parser 757 * @return string The error string 758 */ 759 function getErrorString() { 760 return $this->errorString; 761 } //getErrorString 762 763 /** 764 * Specifies whether elements tags will be rendered to string as <element></element> rather than <element/> 765 * @param boolean True if the expanded form is to be used 766 * @param mixed An array of tag names that should be excepted from expandEmptyElements rule (optional) 767 */ 768 function expandEmptyElementTags($truthVal, $expandEmptyElementExceptions = false) { 769 $this->doExpandEmptyElementTags = $truthVal; 770 771 if (is_array($expandEmptyElementExceptions)) { 772 $this->expandEmptyElementExceptions = $expandEmptyElementExceptions; 773 } 774 } //expandEmptyElementTags 775 776 /** 777 * Set the specified node as document element 778 * @param Object The node that is to become document element 779 * @return Object The new document element 780 */ 781 function &setDocumentElement(&$node) { 782 if ($node->nodeType == DOMIT_ELEMENT_NODE) { 783 if ($this->documentElement == null) { 784 parent::appendChild($node); 785 } 786 else { 787 parent::replaceChild($node, $this->documentElement); 788 } 789 790 $this->documentElement =& $node; 791 } 792 else { 793 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 794 ('Cannot add a node of type ' . get_class($node) . ' as a Document Element.')); 795 } 796 797 return $node; 798 } //setDocumentElement 799 800 /** 801 * Appends a node to the childNodes list of the current node 802 * @param Object The node to be appended 803 * @return Object The appended node 804 */ 805 function &appendChild(&$node) { 806 if ($node->nodeType == DOMIT_ELEMENT_NODE) { 807 if ($this->documentElement == null) { 808 parent::appendChild($node); 809 $this->setDocumentElement($node); 810 } 811 else { 812 //error thrown if documentElement already exists! 813 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 814 ('Cannot have more than one root node (documentElement) in a DOMIT_Document.')); 815 } 816 } 817 else { 818 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 819 ('Cannot add a node of type ' . get_class($node) . ' to a DOMIT_Document.')); 820 } 821 822 return $node; 823 } //appendChild 824 825 /** 826 * Replaces a node with another 827 * @param Object The new node 828 * @param Object The old node 829 * @return Object The new node 830 */ 831 function &replaceChild(&$newChild, &$oldChild) { 832 if (($this->documentElement != null) && ($oldChild->uid == $this->documentElement->uid)) { 833 if ($node->nodeType == DOMIT_ELEMENT_NODE) { 834 //replace documentElement with new node 835 $this->setDocumentElement($newChild); 836 } 837 else { 838 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 839 ('Cannot replace Document Element with a node of class ' . get_class($newChild))); 840 } 841 } 842 else { 843 if ($node->nodeType == DOMIT_ELEMENT_NODE) { 844 if ($this->documentElement != null) { 845 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 846 ('Cannot have more than one root node (documentElement) in a DOMIT_Document.')); 847 } 848 else { 849 parent::replaceChild($newChild, $oldChild); 850 } 851 } 852 else { 853 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 854 ('Nodes of class ' . get_class($newChild) . ' cannot be children of a DOMIT_Document.')); 855 } 856 } 857 858 return $newChild; 859 } //replaceChild 860 861 /** 862 * Inserts a node to the childNodes list of the current node 863 * @param Object The node to be inserted 864 * @param Object The node before which the insertion is to occur 865 * @return Object The inserted node 866 */ 867 function &insertBefore(&$newChild, &$refChild) { 868 $type = $newChild->nodeType; 869 870 if ($type == DOMIT_ELEMENT_NODE) { 871 if ($this->documentElement == null) { 872 parent::insertBefore($newChild, $refChild); 873 $this->setDocumentElement($newChild); 874 } 875 else { 876 //error thrown if documentElement already exists! 877 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 878 ('Cannot have more than one root node (documentElement) in a DOMIT_Document.')); 879 } 880 } 881 else { 882 DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, 883 ('Cannot insert a node of type ' . get_class($newChild) . ' to a DOMIT_Document.')); 884 } 885 886 return $newChild; 887 } //insertBefore 888 889 /** 890 * Removes a node from the childNodes list of the current node 891 * @param Object The node to be removed 892 * @return Object The removed node 893 */ 894 function &removeChild(&$oldChild) { 895 if (($this->documentElement != null) && ($oldChild->uid == $this->documentElement->uid)) { 896 parent::removeChild($oldChild); 897 $this->documentElement = null; 898 } 899 else { 900 parent::removeChild($oldChild); 901 } 902 903 $oldChild->clearReferences(); 904 return $oldChild; 905 } //removeChild 906 907 /** 908 * Creates a new DOMIT_Lite_Element node 909 * @param string The tag name of the element 910 * @return Object The new element 911 */ 912 function &createElement($tagName) { 913 $node = new DOMIT_Lite_Element($tagName); 914 $node->ownerDocument = $this; 915 916 return $node; 917 } //createElement 918 919 /** 920 * Creates a new DOMIT_Text node 921 * @param string The text of the node 922 * @return Object The new text node 923 */ 924 function &createTextNode($data) { 925 $node = new DOMIT_Lite_TextNode($data); 926 $node->ownerDocument = $this; 927 928 return $node; 929 } //createTextNode 930 931 /** 932 * Creates a new DOMIT_Lite_CDATASection node 933 * @param string The text of the CDATASection 934 * @return Object The new CDATASection node 935 */ 936 function &createCDATASection($data) { 937 $node = new DOMIT_Lite_CDATASection($data); 938 $node->ownerDocument = $this; 939 940 return $node; 941 } //createCDATASection 942 943 /** 944 * Retrieves a NodeList of child elements with the specified tag name 945 * @param string The matching element tag name 946 * @return Object A NodeList of found elements 947 */ 948 function &getElementsByTagName($tagName) { 949 $nodeList = new DOMIT_NodeList(); 950 951 if ($this->documentElement != null) { 952 $this->documentElement->getNamedElements($nodeList, $tagName); 953 } 954 955 return $nodeList; 956 } //getElementsByTagName 957 958 /** 959 * Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like expression. 960 * @param string The query pattern 961 * @param int If a single node is to be returned (rather than the entire NodeList) the index of that node 962 * @return mixed A NodeList or single node that matches the pattern 963 */ 964 function &getElementsByPath($pattern, $nodeIndex = 0) { 965 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_getelementsbypath.php'); 966 967 $gebp = new DOMIT_GetElementsByPath(); 968 $myResponse =& $gebp->parsePattern($this, $pattern, $nodeIndex); 969 970 return $myResponse; 971 } //getElementsByPath 972 973 /** 974 * Parses an xml string; first encodes string as UTF-8 975 * @param string The xml text to be parsed 976 * @param boolean True if SAXY is to be used instead of Expat 977 * @param boolean False if CDATA Section are to be generated as Text nodes 978 * @param boolean True if onLoad is to be called on each node after parsing 979 * @return boolean True if parsing is successful 980 */ 981 function parseXML_utf8($xmlText, $useSAXY = true, $preserveCDATA = true, $fireLoadEvent = false) { 982 return $this->parseXML(utf8_encode($xmlText), $useSAXY, $preserveCDATA, $fireLoadEvent); 983 } //parseXML_utf8 984 985 /** 986 * Parses an xml string 987 * @param string The xml text to be parsed 988 * @param boolean True if SAXY is to be used instead of Expat 989 * @param boolean False if CDATA Section are to be generated as Text nodes 990 * @param boolean True if onLoad is to be called on each node after parsing 991 * @return boolean True if parsing is successful 992 */ 993 function parseXML($xmlText, $useSAXY = true, $preserveCDATA = true, $fireLoadEvent = false) { 994 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); 995 996 if ($this->doResolveErrors) { 997 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_doctor.php'); 998 $xmlText = DOMIT_Doctor::fixAmpersands($xmlText); 999 } 1000 1001 if (DOMIT_Utilities::validateXML($xmlText)) { 1002 $domParser = new DOMIT_Lite_Parser(); 1003 1004 if ($useSAXY || (!function_exists('xml_parser_create'))) { 1005 //use SAXY parser to populate xml tree 1006 $this->parser = 'SAXY_LITE'; 1007 $success = $domParser->parseSAXY($this, $xmlText, $preserveCDATA, $this->definedEntities); 1008 } 1009 else { 1010 //use Expat parser to populate xml tree 1011 $this->parser = 'EXPAT'; 1012 $success = $domParser->parse($this, $xmlText, $preserveCDATA); 1013 } 1014 1015 if ($fireLoadEvent && ($this->documentElement != null)) $this->load($this->documentElement); 1016 1017 return $success; 1018 } 1019 1020 return false; 1021 } //parseXML 1022 1023 /** 1024 * Parses an xml file; first encodes text as UTF-8 1025 * @param string The xml file to be parsed 1026 * @param boolean True if SAXY is to be used instead of Expat 1027 * @param boolean False if CDATA Section are to be generated as Text nodes 1028 * @param boolean True if onLoad is to be called on each node after parsing 1029 * @return boolean True if parsing is successful 1030 */ 1031 function loadXML_utf8($filename, $useSAXY = true, $preserveCDATA = true, $fireLoadEvent = false) { 1032 $xmlText = $this->getTextFromFile($filename); 1033 return $this->parseXML_utf8($xmlText, $useSAXY, $preserveCDATA, $fireLoadEvent); 1034 } //loadXML_utf8 1035 1036 /** 1037 * Parses an xml file 1038 * @param string The xml file to be parsed 1039 * @param boolean True if SAXY is to be used instead of Expat 1040 * @param boolean False if CDATA Section are to be generated as Text nodes 1041 * @param boolean True if onLoad is to be called on each node after parsing 1042 * @return boolean True if parsing is successful 1043 */ 1044 function loadXML($filename, $useSAXY = true, $preserveCDATA = true, $fireLoadEvent = false) { 1045 $xmlText = $this->getTextFromFile($filename); 1046 return $this->parseXML($xmlText, $useSAXY, $preserveCDATA, $fireLoadEvent); 1047 } //loadXML 1048 1049 /** 1050 * Establishes a connection, given an url 1051 * @param string The url of the data 1052 */ 1053 function establishConnection($url) { 1054 require_once (DOMIT_INCLUDE_PATH . 'php_http_client_generic.php'); 1055 1056 $host = php_http_connection::formatHost($url); 1057 $host = substr($host, 0, strpos($host, '/')); 1058 1059 $this->setConnection($host); 1060 } //establishConnection 1061 1062 /** 1063 * Retrieves text from a file 1064 * @param string The file path 1065 * @return string The text contained in the file 1066 */ 1067 function getTextFromFile($filename) { 1068 if ($this->doUseHTTPClient && (substr($filename, 0, 5) == 'http:')) { 1069 $this->establishConnection($filename); 1070 } 1071 1072 if ($this->httpConnection != null) { 1073 $response =& $this->httpConnection->get($filename); 1074 $this->httpConnection->disconnect(); 1075 return $response->getResponse(); 1076 } 1077 else if (function_exists('file_get_contents')) { 1078 //if (file_exists($filename)) { 1079 return file_get_contents($filename); 1080 //} 1081 } 1082 else { 1083 require_once (DOMIT_INCLUDE_PATH . 'php_file_utilities.php'); 1084 1085 $fileContents =& php_file_utilities::getDataFromFile($filename, 'r'); 1086 return $fileContents; 1087 } 1088 1089 return ''; 1090 } //getTextFromFile 1091 1092 /** 1093 * Saves the current DOM document as an xml file; first encodes text as UTF-8 1094 * @param string The path of the xml file 1095 * @param boolean True if xml text is to be normalized before saving 1096 * @return boolean True if save is successful 1097 */ 1098 function saveXML_utf8($filename, $normalized=false) { 1099 if ($normalized) { 1100 $stringRep = $this->toNormalizedString(false, true); //param 2 is $subEntities 1101 } 1102 else { 1103 $stringRep = $this->toString(false, true); 1104 } 1105 1106 return $this->saveTextToFile($filename, utf8_encode($stringRep)); 1107 } //saveXML_utf8 1108 1109 /** 1110 * Saves the current DOM document as an xml file 1111 * @param string The path of the xml file 1112 * @param boolean True if xml text is to be normalized before saving 1113 * @return boolean True if save is successful 1114 */ 1115 function saveXML($filename, $normalized=false) { 1116 if ($normalized) { 1117 $stringRep = $this->toNormalizedString(false, true); 1118 } 1119 else { 1120 $stringRep = $this->toString(false, true); 1121 } 1122 if ($this->xmlDeclaration) { 1123 $stringRep = $this->xmlDeclaration . "\n" . $stringRep; 1124 } 1125 return $this->saveTextToFile($filename, $stringRep); 1126 } //saveXML 1127 1128 /** 1129 * Saves text to a file 1130 * @param string The file path 1131 * @param string The text to be saved 1132 * @return boolean True if the save is successful 1133 */ 1134 function saveTextToFile($filename, $text) { 1135 if (function_exists('file_put_contents')) { 1136 file_put_contents($filename, $text); 1137 } 1138 else { 1139 require_once (DOMIT_INCLUDE_PATH . 'php_file_utilities.php'); 1140 php_file_utilities::putDataToFile($filename, $text, 'w'); 1141 } 1142 1143 return (file_exists($filename) && is_writable($filename)); 1144 } //saveTextToFile 1145 1146 /** 1147 * Indicates the SAX parser used to parse the current document 1148 * @return string Either "SAXY_LITE" or "EXPAT" 1149 */ 1150 function parsedBy() { 1151 return $this->parser; 1152 } //parsedBy 1153 1154 /** 1155 * Returns the concatented text of the current node and its children 1156 * @return string The concatented text of the current node and its children 1157 */ 1158 function getText() { 1159 if ($this->documentElement != null) { 1160 $root =& $this->documentElement; 1161 return $root->getText(); 1162 } 1163 1164 return ''; 1165 } //getText 1166 1167 /** 1168 * Returns the doctype text 1169 * @return string The doctype text, or an emty string 1170 */ 1171 function getDocType() { 1172 return $this->doctype; 1173 } //getDocType 1174 1175 /** 1176 * Returns the xml declaration text 1177 * @return mixed The xml declaration text, or an empty string 1178 */ 1179 function getXMLDeclaration() { 1180 return $this->xmlDeclaration; 1181 } //getXMLDeclaration 1182 1183 /** 1184 * Returns the xml declaration text 1185 * @return mixed The xml declaration text, or an empty string 1186 */ 1187 function setXMLDeclaration( $decl ) { 1188 $this->xmlDeclaration = $decl; 1189 } //setXMLDeclaration 1190 1191 /** 1192 * Returns a reference to the DOMIT_DOMImplementation object 1193 * @return Object A reference to the DOMIT_DOMImplementation object 1194 */ 1195 function &getDOMImplementation() { 1196 return $this->implementation; 1197 } //getDOMImplementation 1198 1199 /** 1200 * Manages the firing of the onLoad() event 1201 * @param Object The parent node of the current recursion 1202 */ 1203 function load(&$contextNode) { 1204 $total = $contextNode->childCount; 1205 1206 for ($i = 0; $i < $total; $i++) { 1207 $currNode =& $contextNode->childNodes[$i]; 1208 $currNode->ownerDocument->load($currNode); 1209 } 1210 1211 $contextNode->onLoad(); 1212 } //load 1213 1214 /** 1215 * Returns the current version of DOMIT! Lite 1216 * @return Object The current version of DOMIT! Lite 1217 */ 1218 function getVersion() { 1219 return DOMIT_LITE_VERSION; 1220 } //getVersion 1221 1222 /** 1223 * Appends an array of entity mappings to the existing translation table 1224 * 1225 * Intended mainly to facilitate the conversion of non-ASCII entities into equivalent characters 1226 * 1227 * @param array A list of entity mappings in the format: array('&' => '&'); 1228 */ 1229 function appendEntityTranslationTable($table) { 1230 $this->definedEntities = $table; 1231 1232 global $DOMIT_defined_entities_flip; 1233 $DOMIT_defined_entities_flip = array_flip($table); 1234 } //appendEntityTranslationTable 1235 1236 /** 1237 * Generates an array representation of the node and its children 1238 * @return Array A representation of the node and its children 1239 */ 1240 function toArray() { 1241 $arReturn = array($this->nodeName => array()); 1242 $total = $this->childCount; 1243 1244 for ($i = 0; $i < $total; $i++) { 1245 $arReturn[$this->nodeName][$i] = $this->childNodes[$i]->toArray(); 1246 } 1247 1248 return $arReturn; 1249 } //toArray 1250 1251 /** 1252 * Copies a node and/or its children 1253 * @param boolean True if all child nodes are also to be cloned 1254 * @return Object A copy of the node and/or its children 1255 */ 1256 function &cloneNode($deep = false) { 1257 $className = get_class($this); 1258 $clone = new $className($this->nodeName); 1259 1260 if ($deep) { 1261 $total = $this->childCount; 1262 1263 for ($i = 0; $i < $total; $i++) { 1264 $currentChild =& $this->childNodes[$i]; 1265 $clone->appendChild($currentChild->cloneNode($deep)); 1266 } 1267 } 1268 1269 return $clone; 1270 } //cloneNode 1271 1272 /** 1273 * Generates a string representation of the node and its children 1274 * @param boolean True if HTML readable output is desired 1275 * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities 1276 * @return string The string representation 1277 */ 1278 function toString($htmlSafe = false, $subEntities = false) { 1279 $result = ''; 1280 $total = $this->childCount; 1281 1282 for ($i = 0; $i < $total; $i++) { 1283 $result .= $this->childNodes[$i]->toString(false, $subEntities); 1284 } 1285 1286 if ($htmlSafe) $result = $this->forHTML($result); 1287 1288 return $result; 1289 } //toString 1290 } //DOMIT_Lite_Document 1291 1292 /** 1293 * A class representing the DOM Element 1294 * 1295 * @package domit-xmlparser 1296 * @subpackage domit-xmlparser-lite 1297 * @author John Heinstein <johnkarl@nbnet.nb.ca> 1298 */ 1299 class DOMIT_Lite_Element extends DOMIT_Lite_ChildNodes_Interface { 1300 /** 1301 * DOM Element constructor 1302 * @param string The tag name of the element 1303 */ 1304 function DOMIT_Lite_Element($tagName) { 1305 $this->_constructor(); 1306 $this->nodeType = DOMIT_ELEMENT_NODE; 1307 $this->nodeName = $tagName; 1308 $this->attributes = array(); 1309 $this->childNodes = array(); 1310 } //DOMIT_Lite_Element 1311 1312 /** 1313 * Returns the tag name of the element 1314 * @return string The tag name of the element 1315 */ 1316 function getTagName() { 1317 return $this->nodeName; 1318 } //getTagName 1319 1320 /** 1321 * Adds elements with the specified tag name to a NodeList collection 1322 * @param Object The NodeList collection 1323 * @param string The tag name of matching elements 1324 */ 1325 function getNamedElements(&$nodeList, $tagName) { 1326 if (($this->nodeName == $tagName) || ($tagName == '*')) { 1327 $nodeList->appendNode($this); 1328 } 1329 1330 $total = $this->childCount; 1331 1332 for ($i = 0; $i < $total; $i++) { 1333 $this->childNodes[$i]->getNamedElements($nodeList, $tagName); 1334 } 1335 } //getNamedElements 1336 1337 /** 1338 * Returns the concatented text of the current node and its children 1339 * @return string The concatented text of the current node and its children 1340 */ 1341 function getText() { 1342 $text = ''; 1343 $numChildren = $this->childCount; 1344 1345 for ($i = 0; $i < $numChildren; $i++) { 1346 $child =& $this->childNodes[$i]; 1347 $text .= $child->getText(); 1348 } 1349 1350 return $text; 1351 } //getText 1352 1353 /** 1354 * If a child text node exists, sets the nodeValue to $data. A child text node is created if none exists 1355 * @param string The text data of the node 1356 */ 1357 function setText($data) { 1358 switch ($this->childCount) { 1359 case 1: 1360 if ($this->firstChild->nodeType == DOMIT_TEXT_NODE) { 1361 $this->firstChild->setText($data); 1362 } 1363 break; 1364 1365 case 0: 1366 $childTextNode =& $this->ownerDocument->createTextNode($data); 1367 $this->appendChild($childTextNode); 1368 break; 1369 1370 default: 1371 //do nothing. Maybe throw error??? 1372 } 1373 } //setText 1374 1375 /** 1376 * Retrieves a NodeList of child elements with the specified tag name 1377 * @param string The matching element tag name 1378 * @return Object A NodeList of found elements 1379 */ 1380 function &getElementsByTagName($tagName) { 1381 $nodeList = new DOMIT_NodeList(); 1382 $this->getNamedElements($nodeList, $tagName); 1383 1384 return $nodeList; 1385 } //getElementsByTagName 1386 1387 /** 1388 * Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like expression. 1389 * @param string The query pattern 1390 * @param int If a single node is to be returned (rather than the entire NodeList) the index of that node 1391 * @return mixed A NodeList or single node that matches the pattern 1392 */ 1393 function &getElementsByPath($pattern, $nodeIndex = 0) { 1394 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_getelementsbypath.php'); 1395 1396 $gebp = new DOMIT_GetElementsByPath(); 1397 $myResponse = $gebp->parsePattern($this, $pattern, $nodeIndex); 1398 1399 return $myResponse; 1400 } //getElementsByPath 1401 1402 /** 1403 * Gets the value of the specified attribute, if it exists 1404 * @param string The attribute name 1405 * @return string The attribute value 1406 */ 1407 function getAttribute($name) { 1408 if ($this->hasAttribute($name)) { 1409 return $this->attributes[$name]; 1410 } 1411 else { 1412 /* 1413 DOMIT_DOMException::raiseException(DOMIT_NOT_FOUND_ERR, 1414 ('No attribute named ' . $name . 'exists.')); 1415 */ 1416 // Joomla! hack 1417 return null; 1418 } 1419 } //getAttribute 1420 1421 /** 1422 * Sets the value of the specified attribute; creates a new attribute if one doesn't exist 1423 * @param string The attribute name 1424 * @param string The desired attribute value 1425 */ 1426 function setAttribute($name, $value) { 1427 $this->attributes[$name] = $value; 1428 } //setAttribute 1429 1430 /** 1431 * Removes the specified attribute 1432 * @param string The name of the attribute to be removed 1433 */ 1434 function removeAttribute($name) { 1435 if ($this->hasAttribute($name)) { 1436 unset($this->attributes[$name]); 1437 } 1438 } //removeAttribute 1439 1440 /** 1441 * Determines whether an attribute with the specified name exists 1442 * @param string The name of the attribute 1443 * @return boolean True if the attribute exists 1444 */ 1445 function hasAttribute($name) { 1446 return isset($this->attributes[$name]); 1447 } //hasAttribute 1448 1449 /** 1450 * Collapses adjacent text nodes in entire element subtree 1451 */ 1452 function normalize() { 1453 if ($this->hasChildNodes()) { 1454 $currNode =& $this->childNodes[0]; 1455 1456 while ($currNode->nextSibling != null) { 1457 $nextNode =& $currNode->nextSibling; 1458 1459 if (($currNode->nodeType == DOMIT_TEXT_NODE) && 1460 ($nextNode->nodeType == DOMIT_TEXT_NODE)) { 1461 $currNode->nodeValue .= $nextNode->nodeValue; 1462 $this->removeChild($nextNode); 1463 } 1464 else { 1465 $currNode->normalize(); 1466 } 1467 1468 if ($currNode->nextSibling != null) { 1469 $currNode =& $currNode->nextSibling; 1470 } 1471 } 1472 } 1473 } //normalize 1474 1475 /** 1476 * Generates an array representation of the node and its children 1477 * @return Array A representation of the node and its children 1478 */ 1479 function toArray() { 1480 $arReturn = array($this->nodeName => array("attributes" => $this->attributes)); 1481 $total = $this->childCount; 1482 1483 for ($i = 0; $i < $total; $i++) { 1484 $arReturn[$this->nodeName][$i] = $this->childNodes[$i]->toArray(); 1485 } 1486 1487 return $arReturn; 1488 } //toArray 1489 1490 /** 1491 * Copies a node and/or its children 1492 * @param boolean True if all child nodes are also to be cloned 1493 * @return Object A copy of the node and/or its children 1494 */ 1495 function &cloneNode($deep = false) { 1496 $className = get_class($this); 1497 $clone = new $className($this->nodeName); 1498 1499 $clone->attributes = $this->attributes; 1500 1501 if ($deep) { 1502 $total = $this->childCount; 1503 1504 for ($i = 0; $i < $total; $i++) { 1505 $currentChild =& $this->childNodes[$i]; 1506 $clone->appendChild($currentChild->cloneNode($deep)); 1507 } 1508 } 1509 1510 return $clone; 1511 } //cloneNode 1512 1513 /** 1514 * Generates a string representation of the node and its children 1515 * @param boolean True if HTML readable output is desired 1516 * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities 1517 * @return string The string representation 1518 */ 1519 function toString($htmlSafe = false, $subEntities = false) { 1520 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); 1521 global $DOMIT_defined_entities_flip; 1522 1523 $result = '<' . $this->nodeName; 1524 1525 //get attributes 1526 foreach ($this->attributes as $key => $value) { 1527 $result .= ' ' . $key . '="'; 1528 $result .= $subEntities ? DOMIT_Utilities::convertEntities($value, 1529 $DOMIT_defined_entities_flip) : $value; 1530 $result .= '"'; 1531 } 1532 1533 //get children 1534 $myNodes =& $this->childNodes; 1535 $total = count($myNodes); 1536 1537 if ($total != 0) { 1538 $result .= '>'; 1539 1540 for ($i = 0; $i < $total; $i++) { 1541 $child =& $myNodes[$i]; 1542 $result .= $child->toString(false, $subEntities); 1543 } 1544 1545 $result .= '</' . $this->nodeName . '>'; 1546 } 1547 else { 1548 if ($this->ownerDocument->doExpandEmptyElementTags) { 1549 if (in_array($this->nodeName, $this->ownerDocument->expandEmptyElementExceptions)) { 1550 $result .= ' />'; 1551 } 1552 else { 1553 $result .= '></' . $this->nodeName . '>'; 1554 } 1555 } 1556 else { 1557 if (in_array($this->nodeName, $this->ownerDocument->expandEmptyElementExceptions)) { 1558 $result .= '></' . $this->nodeName . '>'; 1559 } 1560 else { 1561 $result .= ' />'; 1562 } 1563 } 1564 } 1565 1566 if ($htmlSafe) $result = $this->forHTML($result); 1567 1568 return $result; 1569 } //toString 1570 } //DOMIT_Lite_Element 1571 1572 /** 1573 * A class representing the DOM Text Node 1574 * 1575 * @package domit-xmlparser 1576 * @subpackage domit-xmlparser-lite 1577 * @author John Heinstein <johnkarl@nbnet.nb.ca> 1578 */ 1579 class DOMIT_Lite_TextNode extends DOMIT_Lite_Node { 1580 /** 1581 * DOM Text Node constructor 1582 * @param string The text of the node 1583 */ 1584 function DOMIT_Lite_TextNode($data) { 1585 $this->_constructor(); 1586 $this->nodeType = DOMIT_TEXT_NODE; 1587 $this->nodeName = '#text'; 1588 $this->setText($data); 1589 } //DOMIT_Lite_TextNode 1590 1591 /** 1592 * Returns the text contained in the current node 1593 * @return string The text of the current node 1594 */ 1595 function getText() { 1596 return $this->nodeValue; 1597 } //getText 1598 1599 /** 1600 * Sets the text contained in the current node to $data. 1601 * @param string The text data of the node 1602 */ 1603 function setText($data) { 1604 $this->nodeValue = $data; 1605 } //setText 1606 1607 /** 1608 * Generates an array representation of the node and its children 1609 * @return Array A representation of the node and its children 1610 */ 1611 function toArray() { 1612 return $this->toString(); 1613 } //toArray 1614 1615 /** 1616 * Copies a node and/or its children 1617 * @param boolean True if all child nodes are also to be cloned 1618 * @return Object A copy of the node and/or its children 1619 */ 1620 function &cloneNode($deep = false) { 1621 $className = get_class($this); 1622 $clone = new $className($this->nodeValue); 1623 1624 return $clone; 1625 } //cloneNode 1626 1627 /** 1628 * Generates a string representation of the node and its children 1629 * @param boolean True if HTML readable output is desired 1630 * @param boolean True if illegal xml characters should be converted to entities 1631 * @return string The string representation 1632 */ 1633 function toString($htmlSafe = false, $subEntities = false) { 1634 require_once (DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); 1635 global $DOMIT_defined_entities_flip; 1636 1637 $result = $subEntities ? DOMIT_Utilities::convertEntities($this->nodeValue, 1638 $DOMIT_defined_entities_flip) : $this->nodeValue; 1639 1640 if ($htmlSafe) $result = $this->forHTML($result); 1641 1642 return $result; 1643 } //toString 1644 } //DOMIT_Lite_TextNode 1645 1646 /** 1647 * A class representing the DOM CDATA Section 1648 * 1649 * @package domit-xmlparser 1650 * @subpackage domit-xmlparser-lite 1651 * @author John Heinstein <johnkarl@nbnet.nb.ca> 1652 */ 1653 class DOMIT_Lite_CDATASection extends DOMIT_Lite_TextNode { 1654 /** 1655 * DOM CDATA Section node constructor 1656 * @param string The text of the node 1657 */ 1658 function DOMIT_Lite_CDATASection($data) { 1659 $this->_constructor(); 1660 $this->nodeType = DOMIT_CDATA_SECTION_NODE; 1661 $this->nodeName = '#cdata-section'; 1662 $this->setText($data); 1663 } //DOMIT_Lite_CDATASection 1664 1665 /** 1666 * Generates a string representation of the node and its children 1667 * @param boolean True if HTML readable output is desired 1668 * @param boolean True if illegal xml characters should be converted to entities 1669 * @return string The string representation 1670 */ 1671 function toString($htmlSafe = false, $subEntities = false) { 1672 $result = '<![CDATA['; 1673 $result .= $subEntities ? str_replace("]]>", "]]>", $this->nodeValue) : 1674 $this->nodeValue; 1675 $result .= ']]>'; 1676 1677 if ($htmlSafe) $result = $this->forHTML($result); 1678 1679 return $result; 1680 } //toString 1681 } //DOMIT_Lite_CDATASection 1682 1683 /** 1684 * Manages the generation of a DOMIT! document from SAX events 1685 * 1686 * @package domit-xmlparser 1687 * @subpackage domit-xmlparser-lite 1688 * @author John Heinstein <johnkarl@nbnet.nb.ca> 1689 */ 1690 class DOMIT_Lite_Parser { 1691 /** @var Object A reference to the resulting xmldoc */ 1692 var $xmlDoc = null; 1693 /** @var Object A reference to the current node in the parsing process */ 1694 var $currentNode = null; 1695 /** @var Object A reference to the last child in the parsing process */ 1696 var $lastChild = null; 1697 /** @var boolean True if currently parsing a CDATA Section */ 1698 var $inCDATASection = false; //flag for Expat 1699 /** @var boolean True if currently parsing a Text node */ 1700 var $inTextNode = false; 1701 /** @var boolean True is CDATA Section nodes are not to be converted into Text nodes */ 1702 var $preserveCDATA; 1703 /** @var string A container for holding the currently parsed text data */ 1704 var $parseContainer = ''; 1705 /** @var string The current docutype text */ 1706 var $parseItem = ''; 1707 1708 /** 1709 * Parses xml text using Expat 1710 * @param Object A reference to the DOM document that the xml is to be parsed into 1711 * @param string The text to be parsed 1712 * @param boolean True if CDATA Section nodes are not to be converted into Text nodes 1713 * @return boolean True if the parsing is successful 1714 */ 1715 function parse (&$myXMLDoc, $xmlText, $preserveCDATA = true) { 1716 $this->xmlDoc =& $myXMLDoc; 1717 $this->lastChild =& $this->xmlDoc; 1718 1719 $this->preserveCDATA = $preserveCDATA; 1720 1721 /* 1722 //create instance of expat parser (should be included in php distro) 1723 if (version_compare(phpversion(), '5.0', '<=')) { 1724 $parser = xml_parser_create(''); 1725 } else { 1726 // special handling for encoding support 1727 if (defined( '_ISO' )) { 1728 $iso = explode( '=', _ISO ); 1729 $parser = xml_parser_create($iso[1]); 1730 } else { 1731 $parser = xml_parser_create(); 1732 } 1733 } 1734 */ 1735 1736 //create instance of expat parser (should be included in php distro) 1737 if (version_compare(phpversion(), '5.0', '<=')) { 1738 $parser = xml_parser_create(''); 1739 } else { 1740 $parser = xml_parser_create('iso-8859-1'); 1741 } 1742 1743 //set handlers for SAX events 1744 xml_set_object($parser, $this); 1745 xml_set_element_handler($parser, 'startElement', 'endElement'); 1746 xml_set_character_data_handler($parser, 'dataElement'); 1747 xml_set_default_handler($parser, 'defaultDataElement'); 1748 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 1749 1750 if (!$this->xmlDoc->preserveWhitespace) { 1751 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 1752 } 1753 else { 1754 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); 1755 } 1756 1757 //parse out whitespace - (XML_OPTION_SKIP_WHITE = 1 does not 1758 //seem to work consistently across versions of PHP and Expat 1759 if (!$this->xmlDoc->preserveWhitespace) { 1760 $xmlText = eregi_replace('>' . "[[:space:]]+" . '<' , '><', $xmlText); 1761 } 1762 1763 $success = xml_parse($parser, $xmlText); 1764 1765 $this->xmlDoc->errorCode = xml_get_error_code($parser); 1766 $this->xmlDoc->errorString = xml_error_string($this->xmlDoc->errorCode); 1767 1768 xml_parser_free($parser); 1769 1770 return $success; 1771 } //parse 1772 1773 /** 1774 * Parses xml text using SAXY 1775 * @param Object A reference to the DOM document that the xml is to be parsed into 1776 * @param string The text to be parsed 1777 * @param boolean True if CDATA Section nodes are not to be converted into Text nodes 1778 * @return boolean True if the parsing is successful 1779 */ 1780 function parseSAXY(&$myXMLDoc, $xmlText, $preserveCDATA, $definedEntities) { 1781 require_once (DOMIT_INCLUDE_PATH . 'xml_saxy_lite_parser.php'); 1782 1783 $this->xmlDoc =& $myXMLDoc; 1784 $this->lastChild =& $this->xmlDoc; 1785 1786 //create instance of SAXY parser 1787 $parser = new SAXY_Lite_Parser(); 1788 $parser->appendEntityTranslationTable($definedEntities); 1789 1790 //not yet implemented in SAXY!!! 1791 $parser->preserveWhitespace = $this->xmlDoc->preserveWhitespace; 1792 1793 $parser->xml_set_element_handler(array(&$this, 'startElement'), array(&$this, 'endElement')); 1794 $parser->xml_set_character_data_handler(array(&$this, 'dataElement')); 1795 1796 if ($preserveCDATA) { 1797 $parser->xml_set_cdata_section_handler(array(&$this, 'cdataElement')); 1798 } 1799 1800 $success = $parser->parse($xmlText); 1801 1802 $this->xmlDoc->errorCode = $parser->xml_get_error_code(); 1803 $this->xmlDoc->errorString = $parser->xml_error_string($this->xmlDoc->errorCode); 1804 1805 return $success; 1806 } //parseSAXY 1807 1808 /** 1809 * Generates and appends a new text node from the parseContainer text 1810 */ 1811 function dumpTextNode() { 1812 //traps for mixed content 1813 $currentNode =& $this->xmlDoc->createTextNode($this->parseContainer); 1814 $this->lastChild->appendChild($currentNode); 1815 $this->inTextNode = false; 1816 $this->parseContainer = ''; 1817 } //dumpTextNode 1818 1819 /** 1820 * Catches a start element event and processes the data 1821 * @param Object A reference to the current SAX parser 1822 * @param string The tag name of the current element 1823 * @param Array An array of the element attributes 1824 */ 1825 function startElement(&$parser, $name, $attrs) { 1826 if ($this->inTextNode) { 1827 $this->dumpTextNode(); 1828 } 1829 1830 $currentNode =& $this->xmlDoc->createElement($name); 1831 $currentNode->attributes = $attrs; 1832 $this->lastChild->appendChild($currentNode); 1833 $this->lastChild =& $currentNode; 1834 } //startElement 1835 1836 /** 1837 * Catches an end element event and processes the data 1838 * @param Object A reference to the current SAX parser 1839 * @param string The tag name of the current element 1840 */ 1841 function endElement(&$parser, $name) { 1842 if ($this->inTextNode) { 1843 $this->dumpTextNode(); 1844 } 1845 1846 $this->lastChild =& $this->lastChild->parentNode; 1847 } //endElement 1848 1849 /** 1850 * Catches a data 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 dataElement(&$parser, $data) { 1855 if (!$this->inCDATASection) $this->inTextNode = true; 1856 1857 $this->parseContainer .= $data; 1858 } //dataElement 1859 1860 /** 1861 * Catches a CDATA Section event and processes the text 1862 * @param Object A reference to the current SAX parser 1863 * @param string The current text data 1864 */ 1865 function cdataElement(&$parser, $data) { 1866 $currentNode =& $this->xmlDoc->createCDATASection($data); 1867 1868 $this->lastChild->appendChild($currentNode); 1869 } //cdataElement 1870 1871 /** 1872 * Catches a default data event and processes the data 1873 * @param Object A reference to the current SAX parser 1874 * @param string The current data 1875 */ 1876 function defaultDataElement(&$parser, $data) { 1877 if (strlen($data) > 2){ 1878 $pre = strtoupper(substr($data, 0, 3)); 1879 1880 switch ($pre) { 1881 case '<![': //cdata section coming 1882 if ($this->preserveCDATA) { 1883 $this->inCDATASection = true; 1884 } 1885 break; 1886 case ']]>': //cdata remnant - ignore 1887 if ($this->preserveCDATA) { 1888 $currentNode =& $this->xmlDoc->createCDATASection($this->parseContainer); 1889 $this->lastChild->appendChild($currentNode); 1890 $this->inCDATASection = false; 1891 $this->parseContainer = ''; 1892 } 1893 else { 1894 $this->dumpTextNode(); 1895 } 1896 1897 break; 1898 } 1899 } 1900 } //defaultDataElement 1901 } //DOMIT_Lite_Parser 1902 1903 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Wed Nov 21 14:43:32 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |