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

📄 xpath.class.php

📁 国外很不错的一个开源OA系统Group-Office
💻 PHP
📖 第 1 页 / 共 5 页
字号:
    $hilightIsActive = is_array($hilightXpathList);    if ($hilightIsActive) {      $this->indentStep = '&nbsp;&nbsp;&nbsp;&nbsp;';    }            // Cache this now    $this->parseSkipWhiteCache = isSet($this->parseOptions[XML_OPTION_SKIP_WHITE]) ? $this->parseOptions[XML_OPTION_SKIP_WHITE] : FALSE;    ///////////////////////////////////////    // Get the starting node and begin with the header    // Get the start node.  The super root is a special case.    $startNode = NULL;    if (empty($absoluteXPath)) {      $superRoot = $this->nodeIndex[''];      // If they didn't specify an xml header, use the one in the object      if (is_null($xmlHeader)) {        $xmlHeader = $this->parseSkipWhiteCache ? trim($superRoot['textParts'][0]) : $superRoot['textParts'][0];        // If we still don't have an XML header, then use a suitable default        if (empty($xmlHeader)) {            $xmlHeader = '<?xml version="1.0"?>';        }      }      if (isSet($superRoot['childNodes'][0])) $startNode = $superRoot['childNodes'][0];    } else {      $startNode = $this->nodeIndex[$absoluteXPath];    }    if (!empty($xmlHeader)) {       $xmlOut = $this->parseSkipWhiteCache ? $xmlHeader."\n" : $xmlHeader;    } else {      $xmlOut = '';    }    ///////////////////////////////////////    // Output the document.    if (($xmlOut .= $this->_InternalExport($startNode)) === FALSE) {      return FALSE;    }        ///////////////////////////////////////    // Convert our markers to hi-lights.    if ($hilightIsActive) {      $from = array('<', '>', chr(2), chr(3));      $to = array('&lt;', '&gt;', '<font color="#FF0000"><b>', '</b></font>');      $xmlOut = str_replace($from, $to, $xmlOut);    }    return $xmlOut;   }    /**   * Export the xml document starting at the named node.   *   * @param $node (node)   The node we have to start exporting from   * @return      (string) The string representation of the node.   */  function _InternalExport($node) {    $bDebugThisFunction = FALSE;    if ($bDebugThisFunction) {      $aStartTime = $this->_beginDebugFunction("_InternalExport");      echo "Exporting node: ".$node['xpath']."<br>\n";    }    ////////////////////////////////    // Quick out.    if (empty($node)) return '';    // The output starts as empty.    $xmlOut = '';    // This loop will output the text before the current child of a parent then the     // current child.  Where the child is a short tag we output the child, then move    // onto the next child.  Where the child is not a short tag, we output the open tag,     // then queue up on currentParentStack[] the child.      //    // When we run out of children, we then output the last text part, and close the     // 'parent' tag before popping the stack and carrying on.    //    // To illustrate, the numbers in this xml file indicate what is output on each    // pass of the while loop:    //    // 1    // <1>2    //  <2>3    //   <3/>4    //  </4>5    //  <5/>6    // </6>    // Although this is neater done using recursion, there's a 33% performance saving    // to be gained by using this stack mechanism.    // Only add CR's if "skip white spaces" was set. Otherwise leave as is.    $CR = ($this->parseSkipWhiteCache) ? "\n" : '';    $currentIndent = '';    $hilightIsActive = is_array($this->hilightXpathList);    // To keep track of where we are in the document we use a node stack.  The node     // stack has the following parallel entries:    //   'Parent'     => (array) A copy of the parent node that who's children we are     //                           exporting    //   'ChildIndex' => (array) The child index of the corresponding parent that we    //                           are currently exporting.    //   'Highlighted'=> (bool)  If we are highlighting this node.  Only relevant if    //                           the hilight is active.    // Setup our node stack.  The loop is designed to output children of a parent,     // not the parent itself, so we must put the parent on as the starting point.    $nodeStack['Parent'] = array($node['parentNode']);    // And add the childpos of our node in it's parent to our "child index stack".    $nodeStack['ChildIndex'] = array($node['pos']);    // We start at 0.    $nodeStackIndex = 0;    // We have not to output text before/after our node, so blank it.  We will recover it    // later    $OldPreceedingStringValue = $nodeStack['Parent'][0]['textParts'][$node['pos']];    $OldPreceedingStringRef =& $nodeStack['Parent'][0]['textParts'][$node['pos']];    $OldPreceedingStringRef = "";    $currentXpath = "";    // While we still have data on our stack    while ($nodeStackIndex >= 0) {      // Count the children and get a copy of the current child.      $iChildCount = count($nodeStack['Parent'][$nodeStackIndex]['childNodes']);      $currentChild = $nodeStack['ChildIndex'][$nodeStackIndex];      // Only do the auto indenting if the $parseSkipWhiteCache flag was set.      if ($this->parseSkipWhiteCache)        $currentIndent = str_repeat($this->indentStep, $nodeStackIndex);      if ($bDebugThisFunction)        echo "Exporting child ".($currentChild+1)." of node {$nodeStack['Parent'][$nodeStackIndex]['xpath']}\n";      ///////////////////////////////////////////      // Add the text before our child.      // Add the text part before the current child      $tmpTxt =& $nodeStack['Parent'][$nodeStackIndex]['textParts'][$currentChild];      if (isSet($tmpTxt) AND ($tmpTxt!="")) {        // Only add CR indent if there were children        if ($iChildCount)          $xmlOut .= $CR.$currentIndent;        // Hilight if necessary.        $highlightStart = $highlightEnd = '';        if ($hilightIsActive) {          $currentXpath = $nodeStack['Parent'][$nodeStackIndex]['xpath'].'/text()['.($currentChild+1).']';          if (in_array($currentXpath, $this->hilightXpathList)) {           // Yes we hilight            $highlightStart = chr(2);            $highlightEnd   = chr(3);          }        }        $xmlOut .= $highlightStart.$nodeStack['Parent'][$nodeStackIndex]['textParts'][$currentChild].$highlightEnd;      }      if ($iChildCount && $nodeStackIndex) $xmlOut .= $CR;      ///////////////////////////////////////////      // Are there any more children?      if ($iChildCount <= $currentChild) {        // Nope, so output the last text before the closing tag        $tmpTxt =& $nodeStack['Parent'][$nodeStackIndex]['textParts'][$currentChild+1];        if (isSet($tmpTxt) AND ($tmpTxt!="")) {          // Hilight if necessary.          $highlightStart = $highlightEnd = '';          if ($hilightIsActive) {            $currentXpath = $nodeStack['Parent'][$nodeStackIndex]['xpath'].'/text()['.($currentChild+2).']';            if (in_array($currentXpath, $this->hilightXpathList)) {             // Yes we hilight              $highlightStart = chr(2);              $highlightEnd   = chr(3);            }          }          $xmlOut .= $highlightStart                .$currentIndent.$nodeStack['Parent'][$nodeStackIndex]['textParts'][$currentChild+1].$CR                .$highlightEnd;        }        // Now close this tag, as we are finished with this child.        // Potentially output an (slightly smaller indent).        if ($this->parseSkipWhiteCache          && count($nodeStack['Parent'][$nodeStackIndex]['childNodes'])) {          $xmlOut .= str_repeat($this->indentStep, $nodeStackIndex - 1);        }        // Check whether the xml-tag is to be hilighted.        $highlightStart = $highlightEnd = '';        if ($hilightIsActive) {          $currentXpath = $nodeStack['Parent'][$nodeStackIndex]['xpath'];          if (in_array($currentXpath, $this->hilightXpathList)) {            // Yes we hilight            $highlightStart = chr(2);            $highlightEnd   = chr(3);          }        }        $xmlOut .=  $highlightStart                     .'</'.$nodeStack['Parent'][$nodeStackIndex]['name'].'>'                     .$highlightEnd;        // Decrement the $nodeStackIndex to go back to the next unfinished parent.        $nodeStackIndex--;        // If the index is 0 we are finished exporting the last node, as we may have been        // exporting an internal node.        if ($nodeStackIndex == 0) break;        // Indicate to the parent that we are finished with this child.        $nodeStack['ChildIndex'][$nodeStackIndex]++;        continue;      }      ///////////////////////////////////////////      // Ok, there are children still to process.      // Queue up the next child (I can copy because I won't modify and copying is faster.)      $nodeStack['Parent'][$nodeStackIndex + 1] = $nodeStack['Parent'][$nodeStackIndex]['childNodes'][$currentChild];      // Work out if it is a short child tag.      $iGrandChildCount = count($nodeStack['Parent'][$nodeStackIndex + 1]['childNodes']);      $shortGrandChild = (($iGrandChildCount == 0) AND (implode('',$nodeStack['Parent'][$nodeStackIndex + 1]['textParts'])==''));      ///////////////////////////////////////////      // Assemble the attribute string first.      $attrStr = '';      foreach($nodeStack['Parent'][$nodeStackIndex + 1]['attributes'] as $key=>$val) {        // Should we hilight the attribute?        if ($hilightIsActive AND in_array($currentXpath.'/attribute::'.$key, $this->hilightXpathList)) {          $hiAttrStart = chr(2);          $hiAttrEnd   = chr(3);        } else {          $hiAttrStart = $hiAttrEnd = '';        }        $attrStr .= ' '.$hiAttrStart.$key.'="'.$val.'"'.$hiAttrEnd;      }      ///////////////////////////////////////////      // Work out what goes before and after the tag content      $beforeTagContent = $currentIndent;      if ($shortGrandChild) $afterTagContent = '/>';      else                  $afterTagContent = '>';      // Check whether the xml-tag is to be hilighted.      if ($hilightIsActive) {        $currentXpath = $nodeStack['Parent'][$nodeStackIndex + 1]['xpath'];        if (in_array($currentXpath, $this->hilightXpathList)) {          // Yes we hilight          $beforeTagContent .= chr(2);          $afterTagContent  .= chr(3);        }      }      $beforeTagContent .= '<';//      if ($shortGrandChild) $afterTagContent .= $CR;            ///////////////////////////////////////////      // Output the tag      $xmlOut .= $beforeTagContent                  .$nodeStack['Parent'][$nodeStackIndex + 1]['name'].$attrStr                  .$afterTagContent;      ///////////////////////////////////////////      // Carry on.                  // If it is a short tag, then we've already done this child, we just move to the next      if ($shortGrandChild) {        // Move to the next child, we need not go deeper in the tree.        $nodeStack['ChildIndex'][$nodeStackIndex]++;        // But if we are just exporting the one node we'd go no further.        if ($nodeStackIndex == 0) break;      } else {        // Else queue up the child going one deeper in the stack        $nodeStackIndex++;        // Start with it's first child        $nodeStack['ChildIndex'][$nodeStackIndex] = 0;      }    }    $result = $xmlOut;    // Repair what we "undid"    $OldPreceedingStringRef = $OldPreceedingStringValue;    ////////////////////////////////////////////    if ($bDebugThisFunction) {      $this->_closeDebugFunction($aStartTime, $result);    }    return $result;  }       //-----------------------------------------------------------------------------------------  // XPathEngine           ------ Import the XML

⌨️ 快捷键说明

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