📄 xml_domit_lite_parser.php
字号:
<?php/*** DOMIT! Lite is a non-validating, but lightweight and fast DOM parser for PHP* @package domit-xmlparser* @subpackage domit-xmlparser-lite* @version 1.01* @copyright (C) 2004 John Heinstein. All rights reserved* @license http://www.gnu.org/copyleft/lesser.html LGPL License* @author John Heinstein <johnkarl@nbnet.nb.ca>* @link http://www.engageinteractive.com/domit/ DOMIT! Home Page* DOMIT! is Free Software**/if (!defined('DOMIT_INCLUDE_PATH')) { define('DOMIT_INCLUDE_PATH', (dirname(__FILE__) . "/"));}/** current version of DOMIT! Lite */define ('DOMIT_LITE_VERSION', '1.01');/***@global array Flipped version of $definedEntities array, to allow two-way conversion of entities** Made global so that Attr nodes, which have no ownerDocument property, can access the array*/$GLOBALS['DOMIT_defined_entities_flip'] = array();require_once(DOMIT_INCLUDE_PATH . 'xml_domit_shared.php');/*** The base class of all DOMIT node types** @package domit-xmlparser* @subpackage domit-xmlparser-lite* @author John Heinstein <johnkarl@nbnet.nb.ca>*/class DOMIT_Lite_Node { /** @var string The name of the node, varies according to node type */ var $nodeName = null; /** @var string The value of the node, varies according to node type */ var $nodeValue = null; /** @var int The type of node, e.g. CDataSection */ var $nodeType = null; /** @var Object A reference to the parent of the current node */ var $parentNode = null; /** @var Array An array of child node references */ var $childNodes = null; /** @var Object A reference to the first node in the childNodes list */ var $firstChild = null; /** @var Object A reference to the last node in the childNodes list */ var $lastChild = null; /** @var Object A reference to the node prior to the current node in its parents childNodes list */ var $previousSibling = null; /** @var Object A reference to the node after the current node in its parents childNodes list */ var $nextSibling = null; /** @var Array An array of attribute key / value pairs */ var $attributes = null; /** @var Object A reference to the Document node */ var $ownerDocument = null; /** @var string The unique node id */ var $uid; /** @var int The number of children of the current node */ var $childCount = 0; /** * Raises error if abstract class is directly instantiated */ function DOMIT_Lite_Node() { DOMIT_DOMException::raiseException(DOMIT_ABSTRACT_CLASS_INSTANTIATION_ERR, 'Cannot instantiate abstract class DOMIT_Lite_Node'); } //DOMIT_Lite_Node /** * DOMIT_Lite_Node constructor, assigns a uid */ function _constructor() { global $uidFactory; $this->uid = $uidFactory->generateUID(); } //_constructor /** * Appends a node to the childNodes list of the current node * @abstract * @param Object The node to be appended * @return Object The appended node */ function &appendChild(&$child) { DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, ('Method appendChild cannot be called by class ' . get_class($this))); } //appendChild /** * Inserts a node to the childNodes list of the current node * @abstract * @param Object The node to be inserted * @param Object The node before which the insertion is to occur * @return Object The inserted node */ function &insertBefore(&$newChild, &$refChild) { DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, ('Method insertBefore cannot be called by class ' . get_class($this))); } //insertBefore /** * Replaces a node with another * @abstract * @param Object The new node * @param Object The old node * @return Object The new node */ function &replaceChild(&$newChild, &$oldChild) { DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, ('Method replaceChild cannot be called by class ' . get_class($this))); } //replaceChild /** * Removes a node from the childNodes list of the current node * @abstract * @param Object The node to be removed * @return Object The removed node */ function &removeChild(&$oldChild) { DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, ('Method removeChild cannot be called by class ' . get_class($this))); } //removeChild /** * Returns the index of the specified node in a childNodes list * @param Array The childNodes array to be searched * @param Object The node targeted by the search * @return int The index of the target node, or -1 if not found */ function getChildNodeIndex(&$arr, &$child) { $index = -1; $total = count($arr); for ($i = 0; $i < $total; $i++) { if ($child->uid == $arr[$i]->uid) { $index = $i; break; } } return $index; } //getChildNodeIndex /** * Determines whether a node has any children * @return boolean True if any child nodes are present */ function hasChildNodes() { return ($this->childCount > 0); } //hasChildNodes /** * Copies a node and/or its children * @abstract * @param boolean True if all child nodes are also to be cloned * @return Object A copy of the node and/or its children */ function &cloneNode($deep = false) { DOMIT_DOMException::raiseException(DOMIT_ABSTRACT_METHOD_INVOCATION_ERR, 'Cannot invoke abstract method DOMIT_Lite_Node->cloneNode($deep). Must provide an overridden method in your subclass.'); } //cloneNode /** * Adds elements with the specified tag name to a NodeList collection * @param Object The NodeList collection * @param string The tag name of matching elements */ function getNamedElements(&$nodeList, $tagName) { //Implemented in DOMIT_Lite_Element. //Needs to be here though! This is called against all nodes in the document. } //getNamedElements /** * Sets the ownerDocument property of a node to the containing DOMIT_Document * @param Object A reference to the document element of the DOMIT_Document */ function setOwnerDocument(&$rootNode) { if ($rootNode->ownerDocument == null) { unset($this->ownerDocument); $this->ownerDocument = null; } else { $this->ownerDocument =& $rootNode->ownerDocument; } $total = $this->childCount; for ($i = 0; $i < $total; $i++) { $this->childNodes[$i]->setOwnerDocument($rootNode); } } //setOwnerDocument /** * Tests whether a value is null, and if so, returns a default value * @param mixed The value to be tested * @param mixed The default value * @return mixed The specified value, or the default value if null */ function &nvl(&$value,$default) { if (is_null($value)) return $default; return $value; } //nvl /** * Retrieves an element or DOMIT_NodeList of elements corresponding to an Xpath-like expression. * @abstract * @param string The query pattern * @param int If a single node is to be returned (rather than the entire NodeList) the index of that node * @return mixed A NodeList or single node that matches the pattern */ function &getElementsByPath($pattern, $nodeIndex = 0) { DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, ('Method getElementsByPath cannot be called by class ' . get_class($this))); } //getElementsByPath /** * Returns the concatented text of the current node and its children * @return string The concatented text of the current node and its children */ function getText() { return $this->nodeValue; } //getText /** * Formats a string for presentation as HTML * @param string The string to be formatted * @param boolean True if the string is to be sent directly to output * @return string The HTML formatted string */ function forHTML($str, $doPrint = false) { require_once(DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); return DOMIT_Utilities::forHTML($str, $doPrint); } //forHTML /** * Generates an array representation of the node and its children * @abstract * @return Array A representation of the node and its children */ function toArray() { DOMIT_DOMException::raiseException(DOMIT_HIERARCHY_REQUEST_ERR, ('Method toArray cannot be called by class ' . get_class($this))); } //toArray /** * A node event that can be set to fire upon document loading, used for node initialization * @abstract */ function onLoad() { //you can override this method if you subclass any of the //DOMIT_Lite_Nodes. It's a way of performing //initialization of your subclass as soon as the document //has been loaded (as opposed to as soon as the current node //has been instantiated). } //onLoad /** * Clears previousSibling, nextSibling, and parentNode references from a node that has been removed */ function clearReferences() { if ($this->previousSibling != null) { unset($this->previousSibling); $this->previousSibling = null; } if ($this->nextSibling != null) { unset($this->nextSibling); $this->nextSibling = null; } if ($this->parentNode != null) { unset($this->parentNode); $this->parentNode = null; } } //clearReferences /** * Generates a normalized (formatted for readability) representation of the node and its children * @param boolean True if HTML readable output is desired * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities * @return string The formatted string representation */ function toNormalizedString($htmlSafe = false, $subEntities = false) { //require this file for generating a normalized (readable) xml string representation require_once(DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); global $DOMIT_defined_entities_flip; $result = DOMIT_Utilities::toNormalizedString($this, $subEntities, $DOMIT_defined_entities_flip); if ($htmlSafe) $result = $this->forHTML($result); return $result; } //toNormalizedString} //DOMIT_Lite_Node/*** A parent class for nodes which possess child nodes** @package domit-xmlparser* @subpackage domit-xmlparser-lite* @author John Heinstein <johnkarl@nbnet.nb.ca>*/class DOMIT_Lite_ChildNodes_Interface extends DOMIT_Lite_Node { /** * Raises error if abstract class is directly instantiated */ function DOMIT_Lite_ChildNodes_Interface() { DOMIT_DOMException::raiseException(DOMIT_ABSTRACT_CLASS_INSTANTIATION_ERR, 'Cannot instantiate abstract class DOMIT_Lite_ChildNodes_Interface'); } //DOMIT_Lite_ChildNodes_Interface /** * Appends a node to the childNodes list of the current node * @param Object The node to be appended * @return Object The appended node */ /** * Appends a node to the childNodes list of the current node * @param Object The node to be appended * @return Object The appended node */ function &appendChild(&$child) { if (!($this->hasChildNodes())) { $this->childNodes[0] =& $child; $this->firstChild =& $child; } else { //remove $child if it already exists $index = $this->getChildNodeIndex($this->childNodes, $child); if ($index != -1) { $this->removeChild($child); } //append child $numNodes = $this->childCount; //BB: was bug auto-created wrong childnodes[-1]: added IF if ($numNodes>0) $prevSibling =& $this->childNodes[($numNodes - 1)]; $this->childNodes[$numNodes] =& $child; //set next and previous relationships //BB: added this line and the else part to finish correcting bug if (isset($prevSibling)) { $child->previousSibling =& $prevSibling; $prevSibling->nextSibling =& $child; } else { unset($child->previousSibling); $child->previousSibling = null; $this->firstChild =& $child; } } $this->lastChild =& $child; $child->parentNode =& $this; unset($child->nextSibling); $child->nextSibling = null; $child->setOwnerDocument($this); $this->childCount++; return $child; } //appendChild /** * Inserts a node to the childNodes list of the current node * @param Object The node to be inserted * @param Object The node before which the insertion is to occur * @return Object The inserted node */ function &insertBefore(&$newChild, &$refChild) { if (($refChild->nodeType == DOMIT_DOCUMENT_NODE) || ($refChild->parentNode == null)) { DOMIT_DOMException::raiseException(DOMIT_NOT_FOUND_ERR, 'Reference child not present in the child nodes list.'); } //if reference child is also the node to be inserted //leave the document as is and don't raise an exception if ($refChild->uid == $newChild->uid) { return $newChild; } //remove $newChild if it already exists $index = $this->getChildNodeIndex($this->childNodes, $newChild); if ($index != -1) { $this->removeChild($newChild); } //find index of $refChild in childNodes $index = $this->getChildNodeIndex($this->childNodes, $refChild); if ($index != -1) { //reset sibling chain if ($refChild->previousSibling != null) { $refChild->previousSibling->nextSibling =& $newChild; $newChild->previousSibling =& $refChild->previousSibling; } else { $this->firstChild =& $newChild; if ($newChild->previousSibling != null) { unset($newChild->previousSibling); $newChild->previousSibling = null; } } $newChild->parentNode =& $refChild->parentNode; $newChild->nextSibling =& $refChild; $refChild->previousSibling =& $newChild; //add node to childNodes $i = $this->childCount; while ($i >= 0) { if ($i > $index) { $this->childNodes[$i] =& $this->childNodes[($i - 1)]; } else if ($i == $index) { $this->childNodes[$i] =& $newChild; } $i--; } $this->childCount++; } else { $this->appendChild($newChild); } $newChild->setOwnerDocument($this); return $newChild; } //insertBefore /** * Replaces a node with another * @param Object The new node * @param Object The old node * @return Object The new node */ function &replaceChild(&$newChild, &$oldChild) { if ($this->hasChildNodes()) { //remove $newChild if it already exists $index = $this->getChildNodeIndex($this->childNodes, $newChild); if ($index != -1) { $this->removeChild($newChild); } //find index of $oldChild in childNodes $index = $this->getChildNodeIndex($this->childNodes, $oldChild); if ($index != -1) { $newChild->ownerDocument =& $oldChild->ownerDocument; $newChild->parentNode =& $oldChild->parentNode; //reset sibling chain if ($oldChild->previousSibling == null) { unset($newChild->previousSibling); $newChild->previousSibling = null; } else { $oldChild->previousSibling->nextSibling =& $newChild; $newChild->previousSibling =& $oldChild->previousSibling; } if ($oldChild->nextSibling == null) { unset($newChild->nextSibling); $newChild->nextSibling = null; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -