XML_XPath
[ class tree: XML_XPath ] [ index: XML_XPath ] [ all elements ]

Source for file XPath.php

Documentation is available at XPath.php

  1. <?php
  2. // {{{ license
  3.  
  4. // +----------------------------------------------------------------------+
  5. // | PHP version 4.0                                                      |
  6. // +----------------------------------------------------------------------+
  7. // | Copyright (c) 1997-2003 The PHP Group                                |
  8. // +----------------------------------------------------------------------+
  9. // | This source file is subject to version 2.0 of the PHP license,       |
  10. // | that is bundled with this package in the file LICENSE, and is        |
  11. // | available at through the world-wide-web at                           |
  12. // | http://www.php.net/license/2_02.txt.                                 |
  13. // | If you did not receive a copy of the PHP license and are unable to   |
  14. // | obtain it through the world-wide-web, please send a note to          |
  15. // | license@php.net so we can mail you a copy immediately.               |
  16. // +----------------------------------------------------------------------+
  17. // | Authors: Dan Allen <dan@mojavelinux.com>                             |
  18. // +----------------------------------------------------------------------+
  19.  
  20. // $Id: XPath.php,v 1.19 2005/10/12 14:48:52 toggg Exp $
  21.  
  22. // }}}
  23. // {{{ description
  24.  
  25. // Xpath/DOM XML manipulation and query interface.
  26.  
  27. // }}}
  28. // {{{ error codes
  29.  
  30. /*
  31.  * Error codes for the XML_XPath interface, which will be mapped to textual messages
  32.  * in the XML_XPath::errorMessage() function.  If you are to add a new error code, be
  33.  * sure to add the textual messages to the XML_XPath::errorMessage() function as well
  34.  */
  35.  
  36. define('XML_XPATH_OK',                      1);
  37. define('XML_XPATH_ERROR',                  -1);
  38. define('XML_XPATH_ALREADY_EXISTS',         -2);
  39. define('XML_XPATH_INVALID_DOCUMENT',       -3);
  40. define('XML_XPATH_INVALID_QUERY',          -4);
  41. define('XML_XPATH_NO_DOM',                 -5);
  42. define('XML_XPATH_INVALID_INDEX',          -6);
  43. define('XML_XPATH_INVALID_NODESET',        -7);
  44. define('XML_XPATH_NULL_POINTER',           -8);
  45. define('XML_XPATH_NOT_LOADED',             -9);
  46. define('XML_XPATH_INVALID_NODETYPE',      -10);
  47. define('XML_XPATH_FILE_NOT_WRITABLE',     -11);
  48. define('XML_XPATH_NODE_REQUIRED',         -12);
  49. define('XML_XPATH_INDEX_SIZE',            -13);
  50. define('XML_PARSE_ERROR',                 -14);
  51. define('XML_DUPLICATE_ROOT',              -15);
  52.  
  53. // }}}
  54. // {{{ includes
  55.  
  56. require_once 'PEAR.php';
  57. require_once 'XPath/common.php';
  58. require_once 'XPath/result.php';
  59. require_once 'XPath/error.php';
  60.  
  61. // }}}
  62.  
  63. // {{{ class XML_XPath
  64.  
  65. /**
  66.  * The main "XML_XPath" class is simply a container class with some methods for
  67.  * creating DOM xml objects and preparing error codes
  68.  *
  69.  * @version  Revision: 1.1
  70.  * @author   Dan Allen <dan@mojavelinux.com>
  71.  * @access   public
  72.  * @since    PHP 4.2.1
  73.  * @package  XML_XPath
  74.  */
  75.  
  76. // }}}
  77. class XML_XPath extends XML_XPath_common {
  78.     // {{{ properties
  79.  
  80.     /** @var object xml data object */
  81.     var $xml;
  82.  
  83.     /** @var object xpath context object for the xml data object */
  84.     var $ctx;
  85.  
  86.     /** @var object current location in the xml document */
  87.     var $pointer;
  88.  
  89.     /** @var boolean determines if we have loaded a document or not */
  90.     var $loaded = false;
  91.  
  92.     /** @var boolean error indicator */
  93.     var $error = false;
  94.  
  95.     // }}}
  96.     // {{{ constructor
  97.  
  98.     function XML_Xpath($in_xml = null$in_type 'string'
  99.     {
  100.         // load the xml document if passed in here
  101.         // if not defined, require load() to be called
  102.         if (!is_null($in_xml)) {
  103.             if (XML_XPath::isError($result $this->load($in_xml$in_type))) {
  104.                 $this->error = $result;
  105.             }
  106.         }
  107.     }
  108.  
  109.     // }}}
  110.     // {{{ void    load()
  111.  
  112.     /**
  113.      * Load the xml document on which we will execute queries and modifications.  This xml
  114.      * document can be loaded from a previously existing xmldom object, a string or a file.
  115.      * On successful load of the xml document, a new xpath context is created so that queries
  116.      * can be done immediately.
  117.      *
  118.      * @param  mixed   $in_xml xml document, in one of 3 forms (object, string or file)
  119.      *
  120.      * @access public
  121.      * @return void {or XML_XPath_Error exception}
  122.      */
  123.     function load($in_xml$in_type 'string'
  124.     {
  125.         // if we already have a document loaded, then throw a warning
  126.         if ($this->loaded{
  127.             return PEAR::raiseError(nullXML_XPATH_ALREADY_EXISTSnullE_USER_WARNING$this->xml->root()'XML_XPath_Error'true);
  128.         }
  129.         // we need to capture errors, since there is not interface for this
  130.         ob_start();
  131.         // in this case, we already have an xmldom object
  132.         // get_class returns a lowercase name
  133.         if ($in_type == 'object' && strtolower(get_class($in_xml)) == 'domdocument'{
  134.             $this->xml = $in_xml;
  135.         }
  136.         // we can read the file, so use xmldocfile to make a xmldom object
  137.         elseif ($in_type == 'file' && (preg_match(';(https?|ftp)://;'$in_xml|| @file_exists($in_xml))) {
  138.             $this->xml = domxml_open_file($in_xml);
  139.         }
  140.         // this is a string, so attempt to make an xmldom object from string
  141.         elseif($in_type == 'string' && is_string($in_xml)) {
  142.             $this->xml = domxml_open_mem($in_xml);
  143.         }
  144.         // not a valid xml instance, so throw error
  145.         else {
  146.             ob_end_clean();
  147.             return PEAR::raiseError(nullXML_XPATH_INVALID_DOCUMENTnullE_USER_ERROR"The xml $in_type '$in_xml' could not be parsed to xml dom"'XML_XPath_Error'true);
  148.         }
  149.         $loadError ob_get_contents();
  150.         ob_end_clean();
  151.         // make sure a domxml object was created, and if so initialized the state
  152.         // get_class returns a lowercase name        
  153.         if (strtolower(get_class($this->xml)) == 'domdocument'{
  154.             $this->loaded = true;
  155.             $this->ctx = $this->xml->xpath_new_context();    
  156.             $this->pointer = $this->xml->root();
  157.             return true;
  158.         }
  159.         // we could not make a domxml object, so throw an error
  160.         else {
  161.             return PEAR::raiseError(nullXML_XPATH_NO_DOMnullE_USER_ERROR"<b>libxml2 Message:</b> $loadError <b>Document:</b> $in_xml"'XML_XPath_Error'true);
  162.         }
  163.     }
  164.  
  165.     // }}}
  166.     // {{{ void    registerNamespace()
  167.  
  168.     /**
  169.      * This function is sort of temporary hack for registering namespace prefixes
  170.      *
  171.      * The domxml functions should do this automatically when a domxml object is read in.
  172.      * For now, you can use this function.
  173.      *
  174.      * @param  array $in_namespaces 
  175.      *
  176.      * @return void 
  177.      * @access public
  178.      */
  179.     function registerNamespace($in_namespaces)
  180.     {
  181.         settype($in_namespaces'array');
  182.         foreach($in_namespaces as $localName => $namespace{
  183.             $this->ctx->xpath_register_ns($localName$namespace);
  184.         }
  185.     }
  186.  
  187.     // }}}
  188.     // {{{ boolean isError()
  189.  
  190.     /**
  191.      * Tell whether a result code from a XML_XPath method is an error.
  192.      *
  193.      * @param  object  $in_value object in question
  194.      *
  195.      * @access public
  196.      * @return boolean whether object is an error object
  197.      */
  198.     function isError($in_value)
  199.     {
  200.         if (is_a($in_value'xml_xpath_error')) {
  201.             return true;
  202.         }
  203.         if (is_a($in_value'xml_xpath')) {
  204.             return (bool) $in_value->error;
  205.         }
  206.         return false;
  207.     }
  208.  
  209.     // }}}
  210.     // {{{ mixed   errorMessage()
  211.  
  212.     /**
  213.      * Return a textual error message for an XML_XPath error code.
  214.      *
  215.      * @param  int $in_value error code
  216.      *
  217.      * @access public
  218.      * @return string error message, or false if not error code
  219.      */
  220.     function errorMessage($in_value
  221.     {
  222.         // make the variable static so that it only has to do the defining on the first call
  223.         static $errorMessages;
  224.  
  225.         // define the varies error messages
  226.         if (!isset($errorMessages)) {
  227.             $errorMessages = array(
  228.                 XML_XPATH_OK                    => 'no error',
  229.                 XML_XPATH_ERROR                 => 'unknown error',
  230.                 XML_XPATH_ALREADY_EXISTS        => 'xml document already loaded',
  231.                 XML_XPATH_INVALID_DOCUMENT      => 'invalid xml document',
  232.                 XML_XPATH_INVALID_QUERY         => 'invalid xpath query',
  233.                 XML_XPATH_NO_DOM                => 'DomDocument could not be instantiated',
  234.                 XML_XPATH_INVALID_INDEX         => 'invalid index',
  235.                 XML_XPATH_INVALID_NODESET       => 'requires nodeset and one of appropriate type',
  236.                 XML_XPATH_NOT_LOADED            => 'DomDocument has not been loaded',
  237.                 XML_XPATH_NULL_POINTER          => 'Null pointer, probably due to empty result object',
  238.                 XML_XPATH_INVALID_NODETYPE      => 'invalid nodetype for requested feature',
  239.                 XML_XPATH_FILE_NOT_WRITABLE     => 'file could not be written',
  240.                 XML_XPATH_NODE_REQUIRED         => 'DomNode required for operation',
  241.                 XML_XPATH_INDEX_SIZE            => 'index given out of range',
  242.                 XML_PARSE_ERROR             => 'parse error in xml string',
  243.                 XML_DUPLICATE_ROOT          => 'root element already exists'
  244.             );  
  245.         }
  246.  
  247.         // If this is an error object, then grab the corresponding error code
  248.         if (XML_XPath::isError($in_value)) {
  249.             if (is_a($in_value'xml_xpath_error')) {
  250.                 $in_value $in_value->getCode();
  251.             else {
  252.                 $in_value $in_value->error->getCode();
  253.             }
  254.         }
  255.         
  256.         // return the textual error message corresponding to the code
  257.         return isset($errorMessages[$in_value]$errorMessages[$in_value$errorMessages[XML_XPATH_ERROR];
  258.     }
  259.  
  260.     // }}}
  261.     // {{{ void    reset()
  262.  
  263.     /**
  264.      * Resets the object so it is possible to load another xml document.
  265.      *
  266.      * @access public
  267.      * @return void 
  268.      */
  269.     function reset()
  270.     {
  271.         $this->xml = null;
  272.         $this->ctx = null;
  273.         $this->pointer = null;
  274.         $this->loaded = false;
  275.     }
  276.  
  277.     // }}}
  278.     // {{{ void    free()
  279.  
  280.     /**
  281.      * Kill the class object to free memory.  Not really sure how necessary this is, but xml
  282.      * documents can be pretty big.  This will kill everything, so only use it when you are done
  283.      *
  284.      * @access public
  285.      * @return void 
  286.      */
  287.     function free()
  288.     {
  289.         $this->reset();
  290.     }
  291.  
  292.     // }}}
  293. }
  294. ?>

Documentation generated on Mon, 11 Mar 2019 14:44:42 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.