📄 xpath.class.php
字号:
} if ($bracketCounter == 0) { // Check whether we can find the expression at this index. if (substr($term, $i, $exprLeng) == $expression) return $i; } } // Nothing was found. return (-1); } /** * Split a string by a searator-string -- BUT the separator-string must be located *outside* of any brackets. * * Returns an array of strings, each of which is a substring of string formed * by splitting it on boundaries formed by the string separator. * * @param $separator (string) String that should be searched. * @param $term (string) String in which the search shall take place. * @return (array) see above */ function _bracketExplode($separator, $term) { // Note that it doesn't make sense for $separator to itself contain (,),[ or ], // but as this is a private function we should be ok. $resultArr = array(); $bracketCounter = 0; // Record where we are in the brackets. do { // BEGIN try block // Check if any separator is in the term $sepLeng = strlen($separator); if (strpos($term, $separator)===FALSE) { // no separator found so end now $resultArr[] = $term; break; // try-block } // Make a substitute separator out of 'unused chars'. $substituteSep = str_repeat(chr(2), $sepLeng); // Now determine the first bracket '(' or '['. $tmp1 = strpos($term, '('); $tmp2 = strpos($term, '['); if ($tmp1===FALSE) { $startAt = (int)$tmp2; } elseif ($tmp2===FALSE) { $startAt = (int)$tmp1; } else { $startAt = min($tmp1, $tmp2); } // Get prefix string part before the first bracket. $preStr = substr($term, 0, $startAt); // Substitute separator in prefix string. $preStr = str_replace($separator, $substituteSep, $preStr); // Now get the rest-string (postfix string) $postStr = substr($term, $startAt); // Go all the way through the rest-string. $strLeng = strlen($postStr); for ($i=0; $i < $strLeng; $i++) { $char = $postStr[$i]; // Spot (,),[,] and modify our bracket counter. Note there is an // assumption here that you don't have a string(with[mis)matched]brackets. // This should be ok as the dodgy string will be detected elsewhere. if ($char=='(' || $char=='[') { $bracketCounter++; continue; } elseif ($char==')' || $char==']') { $bracketCounter--; } // If no brackets surround us check for separator if ($bracketCounter == 0) { // Check whether we can find the expression starting at this index. if ((substr($postStr, $i, $sepLeng) == $separator)) { // Substitute the found separator for ($j=0; $j<$sepLeng; $j++) { $postStr[$i+$j] = $substituteSep[$j]; } } } } // Now explod using the substitute separator as key. $resultArr = explode($substituteSep, $preStr . $postStr); } while (FALSE); // End try block // Return the results that we found. May be a array with 1 entry. return $resultArr; } /** * Split a string at it's groups, ie bracketed expressions * * Returns an array of strings, when concatenated together would produce the original * string. ie a(b)cde(f)(g) would map to: * array ('a', '(b)', cde', '(f)', '(g)') * * @param $string (string) The string to process * @param $open (string) The substring for the open of a group * @param $close (string) The substring for the close of a group * @return (array) The parsed string, see above */ function _getEndGroups($string, $open='[', $close=']') { // Note that it doesn't make sense for $separator to itself contain (,),[ or ], // but as this is a private function we should be ok. $resultArr = array(); do { // BEGIN try block // Check if we have both an open and a close tag if (empty($open) and empty($close)) { // no separator found so end now $resultArr[] = $string; break; // try-block } if (empty($string)) { $resultArr[] = $string; break; // try-block } while (!empty($string)) { // Now determine the first bracket '(' or '['. $openPos = strpos($string, $open); $closePos = strpos($string, $close); if ($openPos===FALSE || $closePos===FALSE) { // Oh, no more groups to be found then. Quit $resultArr[] = $string; break; } // Sanity check if ($openPos > $closePos) { // Malformed string, dump the rest and quit. $resultArr[] = $string; break; } // Get prefix string part before the first bracket. $preStr = substr($string, 0, $openPos); // This is the first string that will go in our output if (!empty($preStr)) $resultArr[] = $preStr; // Skip over what we've proceed, including the open char $string = substr($string, $openPos + 1 - strlen($string)); // Find the next open char and adjust our close char//echo "close: $closePos\nopen: $openPos\n\n"; $closePos -= $openPos + 1; $openPos = strpos($string, $open);//echo "close: $closePos\nopen: $openPos\n\n"; // While we have found nesting... while ($openPos && $closePos && ($closePos > $openPos)) { // Find another close pos after the one we are looking at $closePos = strpos($string, $close, $closePos + 1); // And skip our open $openPos = strpos($string, $open, $openPos + 1); }//echo "close: $closePos\nopen: $openPos\n\n"; // If we now have a close pos, then it's the end of the group. if ($closePos === FALSE) { // We didn't... so bail dumping what was left $resultArr[] = $open.$string; break; } // We did, so we can extract the group $resultArr[] = $open.substr($string, 0, $closePos + 1); // Skip what we have processed $string = substr($string, $closePos + 1); } } while (FALSE); // End try block // Return the results that we found. May be a array with 1 entry. return $resultArr; } /** * Retrieves a substring before a delimiter. * * This method retrieves everything from a string before a given delimiter, * not including the delimiter. * * @param $string (string) String, from which the substring should be extracted. * @param $delimiter (string) String containing the delimiter to use. * @return (string) Substring from the original string before the delimiter. * @see _afterstr() */ function _prestr(&$string, $delimiter, $offset=0) { // Return the substring. $offset = ($offset<0) ? 0 : $offset; $pos = strpos($string, $delimiter, $offset); if ($pos===FALSE) return $string; else return substr($string, 0, $pos); } /** * Retrieves a substring after a delimiter. * * This method retrieves everything from a string after a given delimiter, * not including the delimiter. * * @param $string (string) String, from which the substring should be extracted. * @param $delimiter (string) String containing the delimiter to use. * @return (string) Substring from the original string after the delimiter. * @see _prestr() */ function _afterstr($string, $delimiter, $offset=0) { $offset = ($offset<0) ? 0 : $offset; // Return the substring. return substr($string, strpos($string, $delimiter, $offset) + strlen($delimiter)); } //----------------------------------------------------------------------------------------- // XPathBase ------ Debug Stuff ------ //----------------------------------------------------------------------------------------- /** * Alter the verbose (error) level reporting. * * Pass an int. >0 to turn on, 0 to turn off. The higher the number, the * higher the level of verbosity. By default, the class has a verbose level * of 1. * * @param $levelOfVerbosity (int) default is 1 = on */ function setVerbose($levelOfVerbosity = 1) { $level = -1; if ($levelOfVerbosity === TRUE) { $level = 1; } elseif ($levelOfVerbosity === FALSE) { $level = 0; } elseif (is_numeric($levelOfVerbosity)) { $level = $levelOfVerbosity; } if ($level >= 0) $this->properties['verboseLevel'] = $levelOfVerbosity; } /** * Returns the last occured error message. * * @access public * @return string (may be empty if there was no error at all) * @see _setLastError(), _lastError */ function getLastError() { return $this->_lastError; } /** * Creates a textual error message and sets it. * * example: 'XPath error in THIS_FILE_NAME:LINE. Message: YOUR_MESSAGE'; * * I don't think the message should include any markup because not everyone wants to debug * into the browser window. * * You should call _displayError() rather than _setLastError() if you would like the message, * dependant on their verbose settings, echoed to the screen. * * @param $message (string) a textual error message default is '' * @param $line (int) the line number where the error occured, use __LINE__ * @see getLastError() */ function _setLastError($message='', $line='-', $file='-') { $this->_lastError = 'XPath error in ' . basename($file) . ':' . $line . '. Message: ' . $message; } /** * Displays an error message. * * This method displays an error messages depending on the users verbose settings * and sets the last error message. * * If also possibly stops the execution of the script. * ### Terminate should not be allowed --fab. Should it?? N.S. * * @param $message (string) Error message to be displayed. * @param $lineNumber (int) line number given by __LINE__ * @param $terminate (bool) (default TURE) End the execution of this script. */ function _displayError($message, $lineNumber='-', $file='-', $terminate=TRUE) { // Display the error message. $err = '<b>XPath error in '.basename($file).':'.$lineNumber.'</b> '.$message."<br \>\n"; $this->_setLastError($message, $lineNumber, $file); if (($this->properties['verboseLevel'] > 0) OR ($terminate)) echo $err; // End the execution of this script. if ($terminate) exit; } /** * Displays a diagnostic message * * This method displays an error messages * * @param $message (string) Error message to be displayed. * @param $lineNumber (int) line number given by __LINE__ */ function _displayMessage($message, $lineNumber='-', $file='-') { // Display the error message. $err = '<b>XPath message from '.basename($file).':'.$lineNumber.'</b> '.$message."<br \>\n"; if ($this->properties['verboseLevel'] > 0) echo $err; } /** * Called to begin the debug run of a function. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -