: : g_XML PARSER

Balíček slouží k postupnému načítání velkého xml souboru a jeho zpracování po jednotlivých sekcích.

Použití:
<? 

  /* vstupni XML souboru ma strukturu
  <data>
    <ip adresa="192.168.2.1">
      <pocitac>Ivanka</pocitac>
      <subadresa budova="D" kancelar="201" />
    </ip>
    <ip>
      ....
    </ip>
    ....
  </data>
  /* */   

  /* funkce pripravena pro zpracovani kazde volane skupiny */
  function ParseXmlData($CurrentSkupina, $Parents) {
  
    switch(strtolower($CurrentSkupina)) {
    
      case "ip":
        G_Xml_ReadAllSectionData("IP", "UlozIPAdresu");
        /* vyvolame nacteni cele aktualni sekce IP do arraye, 
           po ukonceni vyvolat funkci UlozIPAdresu($dataarray) */
        return _XML_NEXT_SAME;       
      break;
    
    }
    return _XML_NEXT;      
  
  }
  
  function UlozIPAdresu($ardata) {

    reset($ardata);

    $arsub = array();
    $arprs = array();
    while(list($k,$h) = each($ardata)) {
      $arsub[$h["name"]] = $h["value"];
      if (!isset($h["attrs"]))
        $arprs[$h["name"]] = array();
      else
        $arprs[$h["name"]] = $h["attrs"];
    }
    
    /* Tady by měl být test! */
    
    SQLQuery(sprintf("
      insert into 
      tabulka_ip_adres (ip, pocitac, budova, kancelar) 
      values ('%s', '%s', '%s', '%s')
    ",
      $arprs["ip"]["adresa"],
      $arsub["pocitac"],
      $arprs["subadresa"]["budova"],
      $arprs["subadresa"]["kancelar"]
    ));
  }

  set_time_limit(600);
  /* nastavit vetsi time limit, protoze soubor je opravdu velky
     a chvili to trva */
  $_XML_ParseFunction = "ParseXmlData";
  // priradime defaultni funkci pro zpracovani kazde sekce

  Do_XML_ParseFile("ipadresy.xml");
  // zparsujeme soubor ipadresy.xml 

  
?>

Kód:
g_xml_parser.php
<?

  $_XML_ParseFunction = '';
  // By mela byt function Funkce($CurrentSkupina {string}, $Parents {array}) {} vratit co udelat {Integer]


  $_XML_Allow_Debug = false;

  define("_XML_STOP", 0);            // - stop a konec

  define("_XML_NEXT", 1);            // - prejdi na dalsi skupinu 

  define("_XML_NEXT_SAME_LEVEL", 2); // - prejdi na dalsi skupinu na stejne urovni

  define("_XML_NEXT_SAME", 3);       // - prejdi na dalsi skupinu stejneho nazvu a stejne urovni

  
  $__Xml_depth = array();
  $__Xml_parents = array();
  $__Xml_Stores = array();  

  $__Xml_TillDepthBack = array(0 => 0, 1 => '');
  $__Xml_Break = false;
  
  $__Xml_ReadTillSection = '';
  $__Xml_ReadTillSectionStartLevel = 0;
  $__Xml_AfterWholeSectionReadedFunction = '';

  $__Xml_Current_Data = '';
  $__Xml_Current_Name = '';
  $__Xml_Current_Attrs = array();
  
  function _Debug($str) {
    echo $str;
  }
  
  function G_Xml_CallParseFunction($Section) {
  
    $str = '$i = '.$GLOBALS['_XML_ParseFunction'].'($Section, $GLOBALS[\'__Xml_parents\']);';
    eval($str);
    
    return $i;
  
  }
  
  function G_Xml_ResetTillDepthBack() {
  
    $GLOBALS['__Xml_TillDepthBack'] = array(0 => 0, 1 => '');
  
  }
  
  function G_Xml_StoreCurrentAttrs() {
  
    if (empty($GLOBALS['__Xml_Current_Name'])) return;

    $ar = array('name' => $GLOBALS['__Xml_Current_Name'], 'value' => $GLOBALS['__Xml_Current_Data']); 
    
    if (count($GLOBALS['__Xml_Current_Attrs']) > 0) {
      
      $attrs = array();
      reset($GLOBALS['__Xml_Current_Attrs']);
      foreach ($GLOBALS['__Xml_Current_Attrs'] as $k => $h) {      
        $attrs[$k] = $h;
      }
      $ar['attrs'] = $attrs;
      
    }
    
    $GLOBALS['__Xml_Stores'][] = $ar;
  
  }
  
  function G_Xml_startElement($parser, $name, $attrs) {
    if ($GLOBALS['__Xml_Break']) 
      return false;
      
    if ($GLOBALS['_XML_Allow_Debug']) _Debug('Start ['.$name.'] ');

    $GLOBALS['__Xml_Current_Name']  = $name;
    $GLOBALS['__Xml_Current_Attrs'] = $attrs;
    $GLOBALS['__Xml_Current_Data']  = '';
        
    $GLOBALS['__Xml_depth'][$parser]++;
    $ar_parents = $GLOBALS['__Xml_parents'][$parser];
    $ar_parents[$level] = $name;    
    $GLOBALS['__Xml_parents'][$parser] = $ar_parents;
    
    if (empty($GLOBALS['__Xml_ReadTillSection'])) {
      
      $level = $GLOBALS['__Xml_depth'][$parser];

      if ($GLOBALS['__Xml_TillDepthBack'][0] > 0) {
      
        if ($level != $GLOBALS['__Xml_TillDepthBack'][0]) return false;
        
        if (!empty($GLOBALS['__Xml_TillDepthBack'][1]) && strtolower($name) != strtolower($GLOBALS['__Xml_TillDepthBack'][1])) return false;
        
        G_Xml_ResetTillDepthBack();
      }
            
      switch (G_Xml_CallParseFunction($name)) {
      
        case _XML_STOP:
          $GLOBALS['__Xml_Break'] = true;
        
          return false;
        break;
        
        case _XML_NEXT_SAME_LEVEL:
          $GLOBALS['__Xml_TillDepthBack'] = array(0 => $level, 1 => '');
        
          return false;
        break;
        
        case _XML_NEXT_SAME:
          $GLOBALS['__Xml_TillDepthBack'] = array(0 => $level, 1 => $name);
        
          return false;
        break;
      
      }    
    
    }
    return true;
  }
  
  function G_Xml_ReadAllSectionData($name, $function) {
  
    $GLOBALS['__Xml_ReadTillSection'] = strtolower($name);

    $GLOBALS['__Xml_AfterWholeSectionReadedFunction'] = $function;
    
    unset($GLOBALS['__Xml_Stores']);
    $GLOBALS['__Xml_Stores'] = array();
    
    G_Xml_StoreCurrentAttrs();
  }
  
  function G_Xml_GetCurrentParent(&$parents) {
    return $parents[count($parents)-1];
  }
  
  function G_Xml_CharacterData($parser, $data) {
  
    if ($GLOBALS['_XML_Allow_Debug']) _Debug(' CharData('.$data.') ');
    if (!empty($GLOBALS['__Xml_ReadTillSection']) && !empty($GLOBALS['__Xml_Current_Name'])) {
      $GLOBALS['__Xml_Current_Data'] .= G_Xml_RepairCzechLanguage($data);
    }    
  
  }
  
  function G_Xml_endElement($parser, $name) {
    if ($GLOBALS['_XML_Allow_Debug']) _Debug(' ['.$name.'] End <br />');
    
    $GLOBALS['__Xml_depth'][$parser]--;

    if (!empty($GLOBALS['__Xml_ReadTillSection'])) {
      global $__Xml_ReadTillSection;
      
      G_Xml_StoreCurrentAttrs();    
    
      if (strtolower($name) == $__Xml_ReadTillSection) {
      
        $__Xml_ReadTillSection = '';
        $GLOBALS['__Xml_ReadTillSectionStartLevel'] = 0;
      
        if (!empty($GLOBALS['__Xml_AfterWholeSectionReadedFunction'])) {
        
          eval($GLOBALS['__Xml_AfterWholeSectionReadedFunction'].'($GLOBALS[\'__Xml_Stores\']);');
        
        }
      
      }

    }

    $GLOBALS['__Xml_Current_Name'] = '';

    if ($GLOBALS['__Xml_Break']) 
      return false;
  }
  
  function G_Xml_RepairCzechLanguage($arstr) {
    if(is_array($arstr)) {
      reset($arstr);
      while(list($k,$h)=each($arstr)) {
        $h=RepairCzechLanguage($h);
        $arstr[$k]=$h;
      }
    } else {
      $arstr=StrTr($arstr, "\xA9\xAB\xAE\xB9\xBB\xBE", "\x8A\x8D\x8E\x9A\x9D\x9E");
    }
    return $arstr;
  }
  
  function G_Xml_GetParents($parser, $level) {
  
    $ret = array();
    if ($level > 0) {
      $ar_parents = $GLOBALS['__Xml_parents'][$parser];
      
      for ($i = 0; $i < $level; $i++) {
        $ret[] = $ar_parents[$i];
      }
      
    }
    return $ret;
  }
 
  function Do_XML_ParseFile($file) {
  
    if (empty($GLOBALS['_XML_ParseFunction'])) return false;
  
    if (file_exists($file)) {
    
      $f = fopen($file, "r");
      if ($f) {

        $xml_parser = xml_parser_create();
        $GLOBALS['__Xml_depth'][$xml_parser] = 0;

        xml_set_element_handler($xml_parser, "G_Xml_startElement", "G_Xml_endElement");
        xml_set_character_data_handler($xml_parser, "G_Xml_CharacterData"); 
        xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0 );
        xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1 );
        xml_parser_set_option($xml_parser, XML_OPTION_TARGET_ENCODING, 'ISO-8859-1');
       
        if (!($fp = fopen($file, "r"))) {
           die("could not open XML input");
        }
        
        while (!feof($fp)) {
          $data = '';
          for ($i = 0; $i < 10; $i++) {
            $data .= fread($fp, 4096);
            if (feof($fp)) 
              break;
          }
          
          if (!xml_parse($xml_parser, $data, feof($fp))) {
            die(sprintf("XML error: %s at line %d",
                         xml_error_string(xml_get_error_code($xml_parser)),
                         xml_get_current_line_number($xml_parser)));
          }
        }

        xml_parser_free($xml_parser);         
    
        fclose($f);
        return true;
      } 
      
      return false;
    
    } else
      return false;

  }

?>