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

📄 xpath.class.inc

📁 groupoffice
💻 INC
📖 第 1 页 / 共 5 页
字号:
   * 
   * if $param is not given, all properties will be returned in a hash.
   *
   * @param  $param (string) the property you want the value of, or NULL for all the properties
   * @return        (mixed)  string OR hash of all params, or NULL on an unknown parameter.
   */
  function getProperties($param=NULL) {
    $this->properties['hasContent']      = !empty($this->nodeRoot);
    $this->properties['caseFolding']     = $this->parseOptions[XML_OPTION_CASE_FOLDING];
    $this->properties['skipWhiteSpaces'] = $this->parseOptions[XML_OPTION_SKIP_WHITE];
    
    if (empty($param)) return $this->properties;
    
    if (isSet($this->properties[$param])) {
      return $this->properties[$param];
    } else {
      return NULL;
    }
  }
  
  /**
   * Set an xml_parser_set_option()
   *
   * @param $optionID (int) The option ID (e.g. XML_OPTION_SKIP_WHITE)
   * @param $value    (int) The option value.
   * @see XML parser functions in PHP doc
   */
  function setXmlOption($optionID, $value) {
    if (!is_numeric($optionID)) return;
     $this->parseOptions[$optionID] = $value;
  }

  /**
   * Sets a number of xml_parser_set_option()s
   *
   * @param  $userXmlOptions (array) An array of parser options.
   * @see setXmlOption
   */
  function setXmlOptions($userXmlOptions=array()) {
    if (!is_array($userXmlOptions)) return;
    foreach($userXmlOptions as $key => $val) {
      $this->setXmlOption($key, $val);
    }
  }
  
  /**
   * Alternative way to control whether case-folding is enabled for this XML parser.
   *
   * Short cut to setXmlOptions(XML_OPTION_CASE_FOLDING, TRUE/FALSE)
   *
   * When it comes to XML, case-folding simply means uppercasing all tag- 
   * and attribute-names (NOT the content) if set to TRUE.  Note if you
   * have this option set, then your XPath queries will also be case folded 
   * for you.
   *
   * @param $onOff (bool) (default TRUE) 
   * @see XML parser functions in PHP doc
   */
  function setCaseFolding($onOff=TRUE) {
    $this->parseOptions[XML_OPTION_CASE_FOLDING] = $onOff;
  }
  
  /**
   * Alternative way to control whether skip-white-spaces is enabled for this XML parser.
   *
   * Short cut to setXmlOptions(XML_OPTION_SKIP_WHITE, TRUE/FALSE)
   *
   * When it comes to XML, skip-white-spaces will trim the tag content.
   * An XML file with no whitespace will be faster to process, but will make 
   * your data less human readable when you come to write it out.
   *
   * Running with this option on will slow the class down, so if you want to 
   * speed up your XML, then run it through once skipping white-spaces, then
   * write out the new version of your XML without whitespace, then use the
   * new XML file with skip whitespaces turned off.
   *
   * @param $onOff (bool) (default TRUE) 
   * @see XML parser functions in PHP doc
   */
  function setSkipWhiteSpaces($onOff=TRUE) {
    $this->parseOptions[XML_OPTION_SKIP_WHITE] = $onOff;
  }
   
  /**
   * Get the node defined by the $absoluteXPath.
   *
   * @param   $absoluteXPath (string) (optional, default is 'super-root') xpath to the node.
   * @return                 (array)  The node, or FALSE if the node wasn't found.
   */
  function &getNode($absoluteXPath='') {
    if ($absoluteXPath==='/') $absoluteXPath = '';
    if (!isSet($this->nodeIndex[$absoluteXPath])) return FALSE;
    if ($this->_indexIsDirty) $this->reindexNodeTree();
    return $this->nodeIndex[$absoluteXPath];
  }

  /**
   * Get a the content of a node text part or node attribute.
   * 
   * If the absolute Xpath references an attribute (Xpath ends with @ or attribute::), 
   * then the text value of that node-attribute is returned.
   * Otherwise the Xpath is referencing a text part of the node. This can be either a 
   * direct reference to a text part (Xpath ends with text()[<nr>]) or indirect reference 
   * (a simple abs. Xpath to a node).
   * 1) Direct Reference (xpath ends with text()[<part-number>]):
   *   If the 'part-number' is omitted, the first text-part is assumed; starting by 1.
   *   Negative numbers are allowed, where -1 is the last text-part a.s.o.
   * 2) Indirect Reference (a simple abs. Xpath to a node):
   *   Default is to return the *whole text*; that is the concated text-parts of the matching
   *   node. (NOTE that only in this case you'll only get a copy and changes to the returned  
   *   value wounld have no effect). Optionally you may pass a parameter 
   *   $textPartNr to define the text-part you want;  starting by 1.
   *   Negative numbers are allowed, where -1 is the last text-part a.s.o.
   *
   * NOTE I : The returned value can be fetched by reference
   *          E.g. $text =& wholeText(). If you wish to modify the text.
   * NOTE II: text-part numbers out of range will return FALSE
   * SIDENOTE:The function name is a suggestion from W3C in the XPath specification level 3.
   *
   * @param   $absoluteXPath  (string)  xpath to the node (See above).
   * @param   $textPartNr     (int)     If referring to a node, specifies which text part 
   *                                    to query.
   * @return                  (&string) A *reference* to the text if the node that the other 
   *                                    parameters describe or FALSE if the node is not found.
   */
  function &wholeText($absoluteXPath, $textPartNr=NULL) {
    $status = FALSE;
    $text   = NULL;
    if ($this->_indexIsDirty) $this->reindexNodeTree();
    
    do { // try-block
      if (preg_match(";(.*)/(attribute::|@)([^/]*)$;U", $absoluteXPath, $matches)) {
        $absoluteXPath = $matches[1];
        $attribute = $matches[3];
        if (!isSet($this->nodeIndex[$absoluteXPath]['attributes'][$attribute])) {
          $this->_displayError("The $absoluteXPath/attribute::$attribute value isn't a node in this document.", __LINE__, __FILE__, FALSE);
          break; // try-block
        }
        $text =& $this->nodeIndex[$absoluteXPath]['attributes'][$attribute];
        $status = TRUE;
        break; // try-block
      }
            
      // Xpath contains a 'text()'-function, thus goes right to a text node. If so interpret the Xpath.
      if (preg_match(":(.*)/text\(\)(\[(.*)\])?$:U", $absoluteXPath, $matches)) {
        $absoluteXPath = $matches[1];
 
        if (!isSet($this->nodeIndex[$absoluteXPath])) {
            $this->_displayError("The $absoluteXPath value isn't a node in this document.", __LINE__, __FILE__, FALSE);
            break; // try-block
        }

        // Get the amount of the text parts in the node.
        $textPartSize = sizeOf($this->nodeIndex[$absoluteXPath]['textParts']);

        // default to the first text node if a text node was not specified
        $textPartNr = isSet($matches[2]) ? substr($matches[2],1,-1) : 1;

        // Support negative indexes like -1 === last a.s.o.
        if ($textPartNr < 0) $textPartNr = $textPartSize + $textPartNr +1;
        if (($textPartNr <= 0) OR ($textPartNr > $textPartSize)) {
          $this->_displayError("The $absoluteXPath/text()[$textPartNr] value isn't a NODE in this document.", __LINE__, __FILE__, FALSE);
          break; // try-block
        }
        $text =& $this->nodeIndex[$absoluteXPath]['textParts'][$textPartNr - 1];
        $status = TRUE;
        break; // try-block
      }
      
      // At this point we have been given an xpath with neither a 'text()' nor 'attribute::' axis at the end
      // So we assume a get to text is wanted and use the optioanl fallback parameters $textPartNr
     
      if (!isSet($this->nodeIndex[$absoluteXPath])) {
          $this->_displayError("The $absoluteXPath value isn't a node in this document.", __LINE__, __FILE__, FALSE);
          break; // try-block
      }

      // Get the amount of the text parts in the node.
      $textPartSize = sizeOf($this->nodeIndex[$absoluteXPath]['textParts']);

      // If $textPartNr == NULL we return a *copy* of the whole concated text-parts
      if (is_null($textPartNr)) {
        unset($text);
        $text = implode('', $this->nodeIndex[$absoluteXPath]['textParts']);
        $status = TRUE;
        break; // try-block
      }
      
      // Support negative indexes like -1 === last a.s.o.
      if ($textPartNr < 0) $textPartNr = $textPartSize + $textPartNr +1;
      if (($textPartNr <= 0) OR ($textPartNr > $textPartSize)) {
        $this->_displayError("The $absoluteXPath has no text part at pos [$textPartNr] (Note: text parts start with 1).", __LINE__, __FILE__, FALSE);
        break; // try-block
      }
      $text =& $this->nodeIndex[$absoluteXPath]['textParts'][$textPartNr -1];
      $status = TRUE;
    } while (FALSE); // END try-block
    
    if (!$status) return FALSE;
    return $text;
  }

  /**
   * Obtain the string value of an object
   *
   * http://www.w3.org/TR/xpath#dt-string-value
   *
   * "For every type of node, there is a way of determining a string-value for a node of that type. 
   * For some types of node, the string-value is part of the node; for other types of node, the 
   * string-value is computed from the string-value of descendant nodes."
   *
   * @param $node   (node)   The node we have to convert
   * @return        (string) The string value of the node.  "" if the object has no evaluatable
   *                         string value
   */
  function _stringValue($node) {
    // Decode the entitites and then add the resulting literal string into our array.
    return $this->_addLiteral($this->decodeEntities($this->wholeText($node)));
  }
  
  //-----------------------------------------------------------------------------------------
  // XPathEngine           ------ Export the XML Document ------                             
  //-----------------------------------------------------------------------------------------
   
  /**
   * Returns the containing XML as marked up HTML with specified nodes hi-lighted
   *
   * @param $absoluteXPath    (string) The address of the node you would like to export.
   *                                   If empty the whole document will be exported.
   * @param $hilighXpathList  (array)  A list of nodes that you would like to highlight
   * @return                  (mixed)  The Xml document marked up as HTML so that it can
   *                                   be viewed in a browser, including any XML headers.
   *                                   FALSE on error.
   * @see _export()    
   */
  function exportAsHtml($absoluteXPath='', $hilightXpathList=array()) {
    $htmlString = $this->_export($absoluteXPath, $xmlHeader=NULL, $hilightXpathList);
    if (!$htmlString) return FALSE;
    return "<pre>\n" . $htmlString . "\n</pre>"; 
  }
  
  /**
   * Given a context this function returns the containing XML
   *
   * @param $absoluteXPath  (string) The address of the node you would like to export.
   *                                 If empty the whole document will be exported.
   * @param $xmlHeader      (array)  The string that you would like to appear before
   *                                 the XML content.  ie before the <root></root>.  If you
   *                                 do not specify this argument, the xmlHeader that was 
   *                                 found in the parsed xml file will be used instead.
   * @return                (mixed)  The Xml fragment/document, suitable for writing
   *                                 out to an .xml file or as part of a larger xml file, or
   *                                 FALSE on error.
   * @see _export()    
   */
  function exportAsXml($absoluteXPath='', $xmlHeader=NULL) {
    $this->hilightXpathList = NULL;
    return $this->_export($absoluteXPath, $xmlHeader); 
  }
    
  /**
   * Generates a XML string with the content of the current document and writes it to a file.
   *
   * Per default includes a <?xml ...> tag at the start of the data too. 
   *
   * @param     $fileName       (string) 
   * @param     $absoluteXPath  (string) The path to the parent node you want(see text above)
   * @param     $xmlHeader      (array)  The string that you would like to appear before
   *                                     the XML content.  ie before the <root></root>.  If you
   *                                     do not specify this argument, the xmlHeader that was 
   *                                     found in the parsed xml file will be used instead.
   * @return                    (string) The returned string contains well-formed XML data 
   *                                     or FALSE on error.
   * @see       exportAsXml(), exportAsHtml()
   */
  function exportToFile($fileName, $absoluteXPath='', $xmlHeader=NULL) {   
    $status = FALSE;
    do { // try-block
      if (!($hFile = fopen($fileName, "wb"))) {   // Did we open the file ok?
        $errStr = "Failed to open the $fileName xml file.";
        break; // try-block
      }
      
      if ($this->properties['OS_supports_flock']) {
        if (!flock($hFile, LOCK_EX + LOCK_NB)) {  // Lock the file
          $errStr = "Couldn't get an exclusive lock on the $fileName file.";
          break; // try-block
        }
      }
      if (!($xmlOut = $this->_export($absoluteXPath, $xmlHeader))) {
        $errStr = "Export failed";
        break; // try-block
      }
      

⌨️ 快捷键说明

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