[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/ -> xmlize.php (source)

   1  <?php
   2  
   3  /**
   4   * xmlize.php - xmlize() is by Hans Anderson, {@link http://www.hansanderson.com/contact/}
   5   *
   6   * Ye Ole "Feel Free To Use it However" License [PHP, BSD, GPL].
   7   * some code in xml_depth is based on code written by other PHPers
   8   * as well as one Perl script.  Poor programming practice and organization
   9   * on my part is to blame for the credit these people aren't receiving.
  10   * None of the code was copyrighted, though.
  11   *
  12   * @package core
  13   * @subpackage lib
  14   * @author Hans Anderson
  15   * @version This is a stable release, 1.0.  I don't foresee any changes, but you
  16   * might check {@link http://www.hansanderson.com/php/xml/} to see
  17   * @copyright Hans Anderson
  18   * @license Feel Free To Use it However
  19   */
  20  
  21  /**
  22   * Exception thrown when there is an error parsing an XML file.
  23   *
  24   * @copyright 2010 The Open University
  25   */
  26  class xml_format_exception extends moodle_exception {
  27      /** @var string */
  28      public $errorstring;
  29      public $line;
  30      public $char;
  31      function __construct($errorstring, $line, $char, $link = '') {
  32          $this->errorstring = $errorstring;
  33          $this->line = $line;
  34          $this->char = $char;
  35  
  36          $a = new stdClass();
  37          $a->errorstring = $errorstring;
  38          $a->errorline = $line;
  39          $a->errorchar = $char;
  40          parent::__construct('errorparsingxml', 'error', $link, $a);
  41      }
  42  }
  43  
  44  /**
  45   * Create an array structure from an XML string.
  46   *
  47   * Usage:<br>
  48   * <code>
  49   * $xml = xmlize($array);
  50   * </code>
  51   * See the function {@link traverse_xmlize()} for information about the
  52   * structure of the array, it's much easier to explain by showing you.
  53   * Be aware that the array is somewhat tricky.  I use xmlize all the time,
  54   * but still need to use {@link traverse_xmlize()} quite often to show me the structure!
  55   *
  56   * THIS IS A PHP 5 VERSION:
  57   *
  58   * This modified version basically has a new optional parameter
  59   * to specify an OUTPUT encoding. If not specified, it defaults to UTF-8.
  60   * I recommend you to read this PHP bug. There you can see how PHP4, PHP5.0.0
  61   * and PHP5.0.2 will handle this.
  62   * {@link http://bugs.php.net/bug.php?id=29711}
  63   * Ciao, Eloy :-)
  64   *
  65   * @param string $data The XML source to parse.
  66   * @param int $whitespace  If set to 1 allows the parser to skip "space" characters in xml document. Default is 1
  67   * @param string $encoding Specify an OUTPUT encoding. If not specified, it defaults to UTF-8.
  68   * @param bool $reporterrors if set to true, then a {@link xml_format_exception}
  69   *      exception will be thrown if the XML is not well-formed. Otherwise errors are ignored.
  70   * @return array representation of the parsed XML.
  71   */
  72  function xmlize($data, $whitespace = 1, $encoding = 'UTF-8', $reporterrors = false) {
  73  
  74      $data = trim($data);
  75      $vals = array();
  76      $parser = xml_parser_create($encoding);
  77      xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
  78      xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, $whitespace);
  79      xml_parse_into_struct($parser, $data, $vals);
  80  
  81      // Error handling when the xml file is not well-formed
  82      if ($reporterrors) {
  83          $errorcode = xml_get_error_code($parser);
  84          if ($errorcode) {
  85              $exception = new xml_format_exception(xml_error_string($errorcode),
  86                      xml_get_current_line_number($parser),
  87                      xml_get_current_column_number($parser));
  88              xml_parser_free($parser);
  89              throw $exception;
  90          }
  91      }
  92      xml_parser_free($parser);
  93  
  94      $i = 0;
  95      if (empty($vals)) {
  96          // XML file is invalid or empty, return false
  97          return false;
  98      }
  99  
 100      $array = array();
 101      $tagname = $vals[$i]['tag'];
 102      if (isset($vals[$i]['attributes'])) {
 103          $array[$tagname]['@'] = $vals[$i]['attributes'];
 104      } else {
 105          $array[$tagname]['@'] = array();
 106      }
 107  
 108      $array[$tagname]["#"] = xml_depth($vals, $i);
 109  
 110      return $array;
 111  }
 112  
 113  /**
 114   * @internal You don't need to do anything with this function, it's called by
 115   * xmlize. It's a recursive function, calling itself as it goes deeper
 116   * into the xml levels.  If you make any improvements, please let me know.
 117   * @access private
 118   */
 119  function xml_depth($vals, &$i) {
 120      $children = array();
 121  
 122      if ( isset($vals[$i]['value']) )
 123      {
 124          array_push($children, $vals[$i]['value']);
 125      }
 126  
 127      while (++$i < count($vals)) {
 128  
 129          switch ($vals[$i]['type']) {
 130  
 131             case 'open':
 132  
 133                  if ( isset ( $vals[$i]['tag'] ) )
 134                  {
 135                      $tagname = $vals[$i]['tag'];
 136                  } else {
 137                      $tagname = '';
 138                  }
 139  
 140                  if ( isset ( $children[$tagname] ) )
 141                  {
 142                      $size = sizeof($children[$tagname]);
 143                  } else {
 144                      $size = 0;
 145                  }
 146  
 147                  if ( isset ( $vals[$i]['attributes'] ) ) {
 148                      $children[$tagname][$size]['@'] = $vals[$i]["attributes"];
 149  
 150                  }
 151  
 152                  $children[$tagname][$size]['#'] = xml_depth($vals, $i);
 153  
 154              break;
 155  
 156  
 157              case 'cdata':
 158                  array_push($children, $vals[$i]['value']);
 159              break;
 160  
 161              case 'complete':
 162                  $tagname = $vals[$i]['tag'];
 163  
 164                  if( isset ($children[$tagname]) )
 165                  {
 166                      $size = sizeof($children[$tagname]);
 167                  } else {
 168                      $size = 0;
 169                  }
 170  
 171                  if( isset ( $vals[$i]['value'] ) )
 172                  {
 173                      $children[$tagname][$size]["#"] = $vals[$i]['value'];
 174                  } else {
 175                      $children[$tagname][$size]["#"] = '';
 176                  }
 177  
 178                  if ( isset ($vals[$i]['attributes']) ) {
 179                      $children[$tagname][$size]['@']
 180                                               = $vals[$i]['attributes'];
 181                  }
 182  
 183              break;
 184  
 185              case 'close':
 186                  return $children;
 187              break;
 188          }
 189  
 190      }
 191  
 192          return $children;
 193  
 194  
 195  }
 196  
 197  
 198  /**
 199   * This helps you understand the structure of the array {@link xmlize()} outputs
 200   *
 201   * Function by acebone@f2s.com, a HUGE help!<br>
 202   * Usage:<br>
 203   * <code>
 204   * traverse_xmlize($xml, 'xml_');
 205   * print '<pre>' . implode("", $traverse_array . '</pre>';
 206   * </code>
 207   * @author acebone@f2s.com
 208   * @param array $array ?
 209   * @param string $arrName ?
 210   * @param int $level ?
 211   * @return int
 212   * @todo Finish documenting this function
 213   */
 214  function traverse_xmlize($array, $arrName = 'array', $level = 0) {
 215  
 216      foreach($array as $key=>$val)
 217      {
 218          if ( is_array($val) )
 219          {
 220              traverse_xmlize($val, $arrName . '[' . $key . ']', $level + 1);
 221          } else {
 222              $GLOBALS['traverse_array'][] = '$' . $arrName . '[' . $key . '] = "' . $val . "\"\n";
 223          }
 224      }
 225  
 226      return 1;
 227  
 228  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1