⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml_domit_xpath.php

📁 Joomla!是一套获得过多个奖项的内容管理系统(Content Management System, CMS)。Joomla!采用PHP+MySQL数据库开发
💻 PHP
📖 第 1 页 / 共 3 页
字号:
<?php/*** @package domit-xmlparser* @subpackage domit-xmlparser-main* @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__) . "/"));}/** Separator for absolute path */define('DOMIT_XPATH_SEPARATOR_ABSOLUTE', '/');/** Separator for relative path */define('DOMIT_XPATH_SEPARATOR_RELATIVE', '//');/** OR separator for multiple patterns  */define('DOMIT_XPATH_SEPARATOR_OR', '|');/** Constant for an absolute path search (starting at the document root) */define('DOMIT_XPATH_SEARCH_ABSOLUTE', 0);/** Constant for a relative path search (starting at the level of the calling node) */define('DOMIT_XPATH_SEARCH_RELATIVE', 1);/** Constant for a variable path search (finds all matches, regardless of place in the hierarchy) */define('DOMIT_XPATH_SEARCH_VARIABLE', 2);/*** DOMIT! XPath is an XPath parser.*/class DOMIT_XPath {    /** @var Object The node from which the search is called */	var $callingNode;	/** @var Object The node that is the current parent of the search */	var $searchType;	/** @var array An array containing a series of path segments for which to search */	var $arPathSegments = array();	/** @var Object A DOMIT_NodeList of matching nodes */	var $nodeList;	/** @var string A temporary string container */	var $charContainer;	/** @var string The current character of the current pattern segment being parsed */	var $currChar;	/** @var string The current pattern segment being parsed */	var $currentSegment;	/** @var array A temporary node container for caching node references at the pattern level*/	var $globalNodeContainer;	/** @var array A temporary node container for caching node references at the pattern segment level */	var $localNodeContainer;	/** @var array Normalization table for XPath syntax */	var $normalizationTable = array('child::' => '', 'self::' => '.',							'attribute::' => '@', 'descendant::' => '*//',							"\t" => ' ', "\x0B" => ' ');	/** @var array A second-pass normalization table for XPath syntax */	var $normalizationTable2 = array(' =' => '=', '= ' => '=', ' <' => '<',							' >' => '>', '< ' => '<', '> ' => '>',							' !' => '!', '( ' => '(',							' )' => ')', ' ]' => ']', '] ' => ']',							' [' => '[', '[ ' => '[', ' /' => '/',							'/ ' => '/', '"' => "'");	/** @var array A third-pass normalization table for XPath syntax */	var $normalizationTable3 = array('position()=' => '',							'/descendant-or-self::node()/' => "//", 'self::node()' => '.',							'parent::node()' => '..');	/**	* Constructor - creates an empty DOMIT_NodeList to store matching nodes	*/	function DOMIT_XPath() {		require_once(DOMIT_INCLUDE_PATH . 'xml_domit_nodemaps.php');		$this->nodeList = new DOMIT_NodeList();	} //DOMIT_XPath	/**	* Parses the supplied "path"-based pattern	* @param Object The node from which the search is called	* @param string The pattern	* @return Object The NodeList containing matching nodes	*/	function &parsePattern(&$node, $pattern, $nodeIndex = 0) {		$this->callingNode =& $node;		$pattern = $this->normalize(trim($pattern));		$this->splitPattern($pattern);		$total = count($this->arPathSegments);		//whole pattern level		for ($i = 0; $i < $total; $i++) {			$outerArray =& $this->arPathSegments[$i];			$this->initSearch($outerArray);			$outerTotal = count($outerArray);			$isInitialMatchAttempt = true;			//variable path segment level			for ($j = 0; $j < $outerTotal; $j++) {				$innerArray =& $outerArray[$j];				$innerTotal = count($innerArray);				if (!$isInitialMatchAttempt) {					$this->searchType = DOMIT_XPATH_SEARCH_VARIABLE;				}				//pattern segment level				for ($k = 0; $k < $innerTotal; $k++) {					$currentPattern = $innerArray[$k];					if (($k == 0) && ($currentPattern == null)) {						if ($innerTotal == 1) {							$isInitialMatchAttempt = false;						}						//else just skip current step and don't alter searchType					}					else {						if (!$isInitialMatchAttempt && ($k > 0)) {							$this->searchType = DOMIT_XPATH_SEARCH_RELATIVE;						}						$this->currentSegment = $currentPattern;						$this->processPatternSegment();						$isInitialMatchAttempt = false;					}				}			}		}		if ($nodeIndex > 0) {			if ($nodeIndex <= count($this->globalNodeContainer)) {				return $this->globalNodeContainer[($nodeIndex - 1)];			}			else {				$null = null;				return $null;			}		}		if (count($this->globalNodeContainer) != 0) {			foreach ($this->globalNodeContainer as $key =>$value) {				$currNode =& $this->globalNodeContainer[$key];				$this->nodeList->appendNode($currNode);			}		}		return $this->nodeList;	} //parsePattern	/**	* Generates a new globalNodeContainer of matches	*/	function processPatternSegment() {		$total = strlen($this->currentSegment);		$this->charContainer = '';		$this->localNodeContainer = array();		for ($i = 0; $i < $total; $i++) {//			$this->currChar = $this->currentSegment{$i};			$this->currChar = substr($this->currentSegment, $i, 1);			switch ($this->currChar) {				case '@':					$this->selectAttribute(substr($this->currentSegment, ($this->currChar + 1)));					$this->updateNodeContainers();					return;					//break;				case '*':					if ($i == ($total - 1)) {						$this->selectNamedChild('*');					}					else {						$this->charContainer .= $this->currChar;					}					break;				case '.':					$this->charContainer .= $this->currChar;					if ($i == ($total - 1)) {						if ($this->charContainer == '..') {							$this->selectParent();						}						else {							return;						}					}					break;				case ')':					$this->charContainer .= $this->currChar;					$this->selectNodesByFunction();					break;				case '[':					$this->parsePredicate($this->charContainer,									substr($this->currentSegment, ($i + 1)));					return;					//break;				default:					$this->charContainer .= $this->currChar;			}		}		if ($this->charContainer != '') {			$this->selectNamedChild($this->charContainer);		}		$this->updateNodeContainers();	} //processPatternSegment	/**	* Replaces the global node container with the local node container	*/	function updateNodeContainers() {		$this->globalNodeContainer =& $this->localNodeContainer;		unset($this->localNodeContainer);	} //updateNodeContainers	/**	* Parses a predicate expression [...]	* @param string The pattern segment containing the node expression	* @param string The pattern segment containing the predicate expression	*/	function parsePredicate($nodeName, $patternSegment) {		$arPredicates =& explode('][', $patternSegment);		$total = count($arPredicates);		$lastIndex = $total - 1;		$arPredicates[$lastIndex] = substr($arPredicates[$lastIndex],										0, (strlen($arPredicates[$lastIndex]) - 1));		for ($i = 0; $i < $total; $i++) {			$isRecursive = ($this->searchType == DOMIT_XPATH_SEARCH_VARIABLE) ? true : false;			$currPredicate = $arPredicates[$i];			if (is_numeric($currPredicate)) {				if ($i == 0) {					$this->filterByIndex($nodeName, intval($currPredicate), $isRecursive);				}				else {					$this->refilterByIndex(intval($currPredicate));				}			}			else {				if ($i == 0) {					$this->selectNamedChild($nodeName);					$this->updateNodeContainers();				}				$phpExpression = $this->predicateToPHP($currPredicate);				$this->filterByPHPExpression($phpExpression);			}			$this->updateNodeContainers();		}		$this->charContainer = '';	} //parsePredicate	/**	* Converts the predicate into PHP evaluable code	* @param string The predicate	* @return string The converted PHP expression	*/	function predicateToPHP($predicate) {		$phpExpression = $predicate;		$currChar = '';		$charContainer = '';		$totalChars = strlen($predicate);		for ($i = 0; $i < $totalChars; $i++) {			$currChar = substr($predicate, $i, 1);			switch ($currChar) {				case '(':				case ')':				case ' ':					if ($charContainer != '') {						$convertedPredicate = $this->expressionToPHP($charContainer);						$phpExpression = str_replace($charContainer, $convertedPredicate, $phpExpression);						$charContainer = '';					}					break;				default:					$charContainer .= $currChar;			}		}		if ($charContainer != '') {			$convertedPredicate = $this->expressionToPHP($charContainer);			$phpExpression = str_replace($charContainer, $convertedPredicate, $phpExpression);		}		return $phpExpression;	} //predicateToPHP	/**	* Converts the predicate expression into a PHP expression	* @param string The predicate expression	* @return string The converted PHP expression	*/	function expressionToPHP($expression) {		if ($expression == 'and') {			$expression = '&&';		}		else if ($expression == 'or') {			$expression = '||';		}		else if ($expression == 'not') {			$expression = '!';		}		else {			$expression = trim($expression);			if (strpos($expression, '@') !== false) {				if (strpos($expression, '>=') !== false) {					$expression = str_replace('@', ('floatval($' . "contextNode->getAttribute('"), $expression);					$expression = str_replace('>=', "')) >= floatval(", $expression);					if (!is_numeric($expression)) $expression = str_replace('floatval', '', $expression);					$expression .= ')';				}				else if (strpos($expression, '<=') !== false) {					$expression = str_replace('@', ('floatval($' . "contextNode->getAttribute('"), $expression);					$expression = str_replace('<=', "')) <= floatval(", $expression);					if (!is_numeric($expression)) $expression = str_replace('floatval', '', $expression);					$expression .= ')';				}				else if (strpos($expression, '!=') !== false) {					$expression = str_replace('@', ('$' . "contextNode->getAttribute('"), $expression);					$expression = str_replace('!=', "') != ", $expression);				}				else if (strpos($expression, '=') !== false) {					$expression = str_replace('@', ('$' . "contextNode->getAttribute('"), $expression);					$expression = str_replace('=', "') == ", $expression);				}				else if (strpos($expression, '>') !== false) {					$expression = str_replace('>', "')) > floatval(", $expression); //reverse so > doesn't get replaced					$expression = str_replace('@', ('floatval($' . "contextNode->getAttribute('"), $expression);					if (!is_numeric($expression)) $expression = str_replace('floatval', '', $expression);					$expression .= ')';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -