Parser un xml ( durée du traitement )

seabird
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 305
Inscription: 1 Déc 2003

Message le Sam Juil 05, 2008 10:44

Ok merci pour ton aide. je vais voir ce que cela donne comme ça. Sinon après j'abandonne....
En fait ce sont maintenant les requètes sql qui ralentissent l'exécution. C'est çà ?


julienr
WRInaute impliqué
WRInaute impliqué
 
Messages: 911
Inscription: 5 Aoû 2003

Message le Sam Juil 05, 2008 15:01

vi normalement lire un fichier avec php de 4mo doit te prendre 1 ou 2s pas plus
le parser normalement c'est pas non plus d'une complexité énorme surtout avec xml_parse
par contre faire 800 insert dans mysql ca ca à cout surtout que cela dépend bcp de la config du serveur (mémoire / charge, vitesse accès disque)

essaye simplement mes handlers avec le fichiers complets sans insert mysql, pour mesurer le tps de parse

ensuite je suis retourné voir tes insert dans ton premier script, je pense que tu devrais dénormaliser et faire qu'une seule table avec comme colonnes toutes les infos d'un produit/retailer/details du xml, ca te ferait 3 fois moins d'insert...

tiens moi au courant ;-)

edit (17h): je viens de me constituer un fichier de 800 fois l'enregistrement que tu as donné (taille 1mo), parser en moins de 1s en local sur mon ordi. En rajoutant un insert sur une table avec un seul champ id_produit, script fini en 2s max. Ca commence par quel lettre ton hébergeur :) ?

seabird
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 305
Inscription: 1 Déc 2003

Message le Dim Juil 06, 2008 0:24

Me revoilà :D . Bon je viens de faire des tests sur un fichier de 900 produits d'une taille de 7Mo.

J'ai testé ton script brut ( que je trouve excellent d'ailleurs ) , il a mis 15 s à s'accomplir. Par contre je viens de remarquer qu'il faut faire une modification dedans car pour un produit donné il y a plusieurs groupes différents du style :
Code: Tout sélectionner
<group>
      <name>nom</name>
      <property>
        <id>13</id>
        <name>Type </name>
        <value>valeur</value>
      </property>

    </group>   

Comme donné dans l'exemple.
Lorsque le script se lance ,seul le dernier apparait vu que cela est écrasé au fur et à mesure. Il en est de même pour le groupe
Code: Tout sélectionner
<retailer>
    <id>27907</id>

    <name>nom1</name>
    <link>lien</link>
    <logo height="50" width="150">image logo</logo>
    <stock-info>Disponible en stock</stock-info>

    <price currency="EUR"prix</price>
    <source-type>www</source-type>
    <source-date>2008-07-04</source-date>
    <price-with-shipping-min currency="EUR">prix1</price-with-shipping-min>
    <price-with-shipping-max currency="EUR">prix2</price-with-shipping-max>
  </retailer>


De mon côté j'ai modifié mon dernier script de la façon ci-dessous. J'arrive
maintenant à un temps d'exécution de 30s avec insertion en bdd . On y arrive petit à petit :D

Code: Tout sélectionner
<?php
include 'bdd.php';

     @mysql_connect($host,$user,$pass)
      or die("Impossible de se connecter");
   @mysql_select_db("$bdd")
       or die("Impossible de se connecter");

$profondeur = array(); // profondeur des items

$fichier = "fichier.xml";

// *********************************************************** BALISE OUVRANTE *******************************************************************************************
    function fonctionBaliseOuvrante($parseur, $nomBalise, $tableauAttributs)
      {

        global $derniereBaliseRencontree;
        $derniereBaliseRencontree = $nomBalise;
     
      global $profondeur;
   
      $profondeur[$parseur]++;
 
      
      }// Fin fonction balise ouvrante
   
   
// *********************************************************** BALISE FERMANTE *******************************************************************************************
    function fonctionBaliseFermante($parseur, $nomBalise)
      {
        // On oublie la dernière balise rencontrée
        global $derniereBaliseRencontree;
        $derniereBaliseRencontree = "";

      global $profondeur;
      global $balisefermante;
    
     $balisefermante=$nomBalise;
    
      if ($balisefermante=="PRODUCTS") {exit;}

      $profondeur[$parseur]--;
     
      }//FIN balise fermante

    
    
    function fonctionTexte($parseur, $texte)
    {
        global $derniereBaliseRencontree;
        global $profondeur;
      global $id_produit;
      global $id_categorie;
      global $caracteristique;
      global $marchand;
      global $lien;
      global $logo;
      global $stock;
      global $prix;
      global $produit;
      global $marque;
      global $description;
      global $categorie;
      global $nombre_marchands;
      global $image;
      global $tarif_moins;
      

if (($derniereBaliseRencontree=="ID") && $profondeur[$parseur]==3) {$id_produit=$texte;}      
if (($derniereBaliseRencontree=="NAME") && $profondeur[$parseur]==3) {$produit=$texte;}
if (($derniereBaliseRencontree=="MANUFACTURER") && $profondeur[$parseur]==3) {$marque=$texte;}
if (($derniereBaliseRencontree=="DESCRIPTION") && $profondeur[$parseur]==3) {$description=$texte;}
if (($derniereBaliseRencontree=="CATEGORY") && $profondeur[$parseur]==3) {$categorie=$texte;}
if (($derniereBaliseRencontree=="CATEGORY-ID") && $profondeur[$parseur]==3) {$id_categorie=$texte;}      
if (($derniereBaliseRencontree=="NUMBER-OF-RETAILERS") && $profondeur[$parseur]==3) {$nombre_marchands=$texte;}
if (($derniereBaliseRencontree=="IMAGE-URL") && $profondeur[$parseur]==3) {$image=$texte;}
if (($derniereBaliseRencontree=="LOWEST-PRICE") && $profondeur[$parseur]==3) {$tarif_moins=$texte;}
if (($derniereBaliseRencontree=="HIGHEST-PRICE") && $profondeur[$parseur]==3)
                        {
                        $table="comparateur";
                        $query = 'INSERT INTO `'.$table.'` (`id_categorie`,`categorie`,`id_produit`,`produit`,`marque`,`description`,`image`,`nombre_marchands`,`tarif_moins`,`tarif_plus`) VALUES (\''.$id_categorie.'\', \''.$categorie.'\', \''.$id_produit.'\', \''.$produit.'\', \''.$marque.'\', \''.$description.'\', \''.$image.'\', \''.$nombre_marchands.'\', \''.$tarif_moins.'\', \''.$texte.'\');';
                        $result = mysql_query($query);
                        }
 
// ********************************************************  ECRITURE CARACTERISTIQUES **************************************************************************
 
if (($derniereBaliseRencontree=="NAME") && $profondeur[$parseur]==6) {$caracteristique=$texte;}
  if (($derniereBaliseRencontree=="VALUE") && $profondeur[$parseur]==6)
                        {
                        $table="comparateur_caracteristiques";
                        $query = 'INSERT INTO `'.$table.'` (`id_produit`,`id_categorie`,`caracteristique`,`valeur_caracteristique`) VALUES (\''.$id_produit.'\', \''.$id_categorie.'\', \''.$caracteristique.'\', \''.$texte.'\');';
                        $result = mysql_query($query);
                        }


//********************************************* ECRITURE MARCHANDS *******************************************************************************

if (($derniereBaliseRencontree=="NAME") && $profondeur[$parseur]==4) {$marchand=$texte;}
if (($derniereBaliseRencontree=="LINK") && $profondeur[$parseur]==4) {$lien=$texte;}
if (($derniereBaliseRencontree=="LOGO") && $profondeur[$parseur]==4) {$logo=$texte;}
if (($derniereBaliseRencontree=="STOCK-INFO") && $profondeur[$parseur]==4) {$stock=$texte;}
if (($derniereBaliseRencontree=="PRICE") && $profondeur[$parseur]==4) {$prix=$texte;}
if (($derniereBaliseRencontree=="PRICE-WITH-SHIPPING-MIN") && $profondeur[$parseur]==4)
                     {
                     $table="comparateur_marchands";
                     $query = 'INSERT INTO `'.$table.'` (`id_produit`,`id_categorie`,`marchand`,`lien`,`logo`,`stock`,`prix`,`prix_frais_port`) VALUES (\''.$id_produit.'\', \''.$id_categorie.'\', \''.$marchand.'\', \''.$lien.'\', \''.$logo.'\', \''.$stock.'\', \''.$prix.'\', \''.$texte.'\');';
                     $result = mysql_query($query);
                     }



         
    }

    // Création du parseur XML
    $parseurXML = xml_parser_create();

    xml_set_element_handler($parseurXML, "fonctionBaliseOuvrante", "fonctionBaliseFermante");

   xml_set_character_data_handler($parseurXML, "fonctionTexte");

    // Ouverture du fichier
    $fp = fopen($fichier, "r");
    if (!$fp) die("Impossible d'ouvrir le fichier XML");

    // Lecture ligne par ligne
    while ( $ligneXML = fgets($fp, 1024))
      {
        xml_parse($parseurXML, $ligneXML, feof($fp)) or
            die("Erreur XML");
      }
   
    xml_parser_free($parseurXML);
    fclose($fp);

echo "LECTURE ACCOMPLI";

mysql_close();   

?>


Cela commence à se préciser et à devenir intéressant.
A nous deux , je suis sur que l'on va optimiser tout ça :lol:

seabird
WRInaute occasionnel
WRInaute occasionnel
 
Messages: 305
Inscription: 1 Déc 2003

Message le Lun Juil 07, 2008 12:33

C'est encore moi. Bon j'ai modifier ton script de façon à afficher tous les group. Je fais le test, toujours avec un fichier de 900 produits de 7Mo.
Je suis arrivé à un temps d'exécution de 20s avec insertion en bdd . Yessssssssssssssssssss , 10s de gagné encore.
Peut-être peut-on l'améliorer encore.
Maintenant mettre qu'une seule table au lieu de trois comme tu le suggères. Je ne vois pas trop comment l'organiser.
Merci en tout cas pour cette suggestion.


Code: Tout sélectionner
<?php

include 'bdd.php';

     @mysql_connect($host,$user,$pass)
      or die("Impossible de se connecter");
   @mysql_select_db("$bdd")
       or die("Impossible de se connecter");
      

$profondeur = array(); // profondeur des items
$tableau = array(); // tableau pour l'enregistrement des contenus

global $i;
global $j;
$i=1;
$j=1;

  $fichier = "fichier.xml";

// *********************************************************** BALISE OUVRANTE *******************************************************************************************
   
   function fonctionBaliseOuvrante($parseur, $nomBalise, $tableauAttributs)
{
   global $profondeur;
   global $tableau;
 
     
   array_push( $profondeur, $nomBalise );
     
   if( count($tableauAttributs) > 0 )
   {
      $path = implode( "_", $profondeur );
      foreach( $tableauAttributs as $k => $v )
      {
   
         $tableau[$path."_".$k] = $v;
      }
   }
}   
   
function fonctionBaliseFermante($parseur, $nomBalise)
{
   global $profondeur;
   global $tableau;
   global $i;
   global $j;

   if ($nomBalise=="PRODUCT")
   {
      //print_r( $tableau );
         $table="comparateur";
         $query = 'INSERT INTO `'.$table.'` (`id_categorie`,`categorie`,`id_produit`,`produit`,`marque`,`description`,`image`,`nombre_marchands`,`tarif_moins`,`tarif_plus`) VALUES (\''.$tableau['PRODUCTS_PRODUCT_CATEGORY-ID'].'\', \''.$tableau['PRODUCTS_PRODUCT_CATEGORY'].'\', \''.$tableau['PRODUCTS_PRODUCT_ID'].'\', \''.$tableau['PRODUCTS_PRODUCT_NAME'].'\', \''.$tableau['PRODUCTS_PRODUCT_MANUFACTURER'].'\', \''.$tableau['PRODUCTS_PRODUCT_DESCRIPTION'].'\', \''.$tableau['PRODUCTS_PRODUCT_IMAGE-URL'].'\', \''.$tableau['PRODUCTS_PRODUCT_NUMBER-OF-RETAILERS'].'\', \''.$tableau['PRODUCTS_PRODUCT_LOWEST-PRICE'].'\', \''.$tableau['PRODUCTS_PRODUCT_HIGHEST-PRICE'].'\');';
         $result = mysql_query($query);
            
         $table="comparateur_caracteristiques";
         for($nbrs_carac=1;$nbrs_carac<$i;$nbrs_carac+=1)
            {
         $query = 'INSERT INTO `'.$table.'` (`id_produit`,`id_categorie`,`caracteristique`,`valeur_caracteristique`) VALUES (\''.$tableau['PRODUCTS_PRODUCT_ID'].'\', \''.$tableau['PRODUCTS_PRODUCT_CATEGORY-ID'].'\', \''.$tableau['PRODUCTS_PRODUCT_PROPERTIES_GROUP_PROPERTY_NAME_'.$nbrs_carac].'\', \''.$tableau['PRODUCTS_PRODUCT_PROPERTIES_GROUP_PROPERTY_VALUE_'.$nbrs_carac].'\');';
         $result = mysql_query($query);   
            }
            
         $table="comparateur_marchands";   
         for($nbrs_mag=1;$nbrs_mag<$j;$nbrs_mag+=1)
            {         
         $query = 'INSERT INTO `'.$table.'` (`id_produit`,`id_categorie`,`marchand`,`lien`,`logo`,`stock`,`prix`,`prix_frais_port`) VALUES (\''.$tableau['PRODUCTS_PRODUCT_ID'].'\', \''.$tableau['PRODUCTS_PRODUCT_CATEGORY-ID'].'\', \''.$tableau['PRODUCTS_PRODUCT_RETAILER_NAME_'.$nbrs_mag].'\', \''.$tableau['PRODUCTS_PRODUCT_RETAILER_LINK_'.$nbrs_mag].'\', \''.$tableau['PRODUCTS_PRODUCT_RETAILER_LOGO_'.$nbrs_mag].'\', \''.$tableau['PRODUCTS_PRODUCT_RETAILER_STOCK-INFO_'.$nbrs_mag].'\', \''.$tableau['PRODUCTS_PRODUCT_RETAILER_PRICE_'.$nbrs_mag] .'\', \''.$tableau['PRODUCTS_PRODUCT_RETAILER_PRICE-WITH-SHIPPING-MIN_'.$nbrs_mag].'\');';
         $result = mysql_query($query);
            }
 
      $tableau=array();
     $i=1;
      $j=1;
    }
     
     
   array_pop( $profondeur );
}   
   

function fonctionTexte($parseur, $texte)
{
   global $profondeur;
   global $tableau;
    global $i;
   global $j;


   $path = implode( "_", $profondeur );
   
   if ($path=="PRODUCTS_PRODUCT_PROPERTIES_GROUP_PROPERTY_NAME") {$path="PRODUCTS_PRODUCT_PROPERTIES_GROUP_PROPERTY_NAME_".$i;}
   if ($path=="PRODUCTS_PRODUCT_PROPERTIES_GROUP_PROPERTY_VALUE") {$path="PRODUCTS_PRODUCT_PROPERTIES_GROUP_PROPERTY_VALUE_".$i;$i++;}
   
   if ($path=="PRODUCTS_PRODUCT_RETAILER_NAME") {$path="PRODUCTS_PRODUCT_RETAILER_NAME_".$j;}
   if ($path=="PRODUCTS_PRODUCT_RETAILER_LINK") {$path="PRODUCTS_PRODUCT_RETAILER_LINK_".$j;}
   if ($path=="PRODUCTS_PRODUCT_RETAILER_LOGO") {$path="PRODUCTS_PRODUCT_RETAILER_LOGO_".$j;}
   if ($path=="PRODUCTS_PRODUCT_RETAILER_STOCK-INFO") {$path="PRODUCTS_PRODUCT_RETAILER_STOCK-INFO_".$j;}
   if ($path=="PRODUCTS_PRODUCT_RETAILER_PRICE") {$path="PRODUCTS_PRODUCT_RETAILER_PRICE_".$j;}
   if ($path=="PRODUCTS_PRODUCT_RETAILER_PRICE-WITH-SHIPPING-MIN") {$path="PRODUCTS_PRODUCT_RETAILER_PRICE-WITH-SHIPPING-MIN_".$j;$j++;}

   $tableau[$path] = $texte;
}
   

    // Création du parseur XML
    $parseurXML = xml_parser_create();

    xml_set_element_handler($parseurXML, "fonctionBaliseOuvrante", "fonctionBaliseFermante");

   xml_set_character_data_handler($parseurXML, "fonctionTexte");

    // Ouverture du fichier
    $fp = fopen($fichier, "r");
    if (!$fp) die("Impossible d'ouvrir le fichier XML");

    // Lecture ligne par ligne
    while ( $ligneXML = fgets($fp, 1024))
      {
   
        xml_parse($parseurXML, $ligneXML, feof($fp)) or
            die("Erreur XML");
      }
   
    xml_parser_free($parseurXML);
    fclose($fp);

echo "LECTURE ACCOMPLI";

?>


julienr
WRInaute impliqué
WRInaute impliqué
 
Messages: 911
Inscription: 5 Aoû 2003

Message le Lun Juil 07, 2008 13:32

voici plutot comment j'aurais vu les choses au niveau de la gestion des balises xml multiples
là dans cette version c stocker dans un tableau
du coup quand tu sais que tu n'as qu'une seule valeur c'est de rajouter [0]
sinon si c'est un attribut multiple, il suffit de lire les n valeurs dans le tableau

pour faire qu'une seule requête, regarde le code en dessous, cela veux entraine un explode lors que tu vas lire les données multiples; à voir si tu peux t'en sortir ainsi sauf que là c'est optimale en terme de requete et de coup de traitement

a+


Code: Tout sélectionner
function fonctionBaliseOuvrante($parseur, $nomBalise, $tableauAttributs)
{
   global $profondeur;
   global $tableau;
     
   array_push( $profondeur, $nomBalise );
      
   if( count($tableauAttributs) > 0 )
   {
      $path = implode( "_", $profondeur );
      foreach( $tableauAttributs as $k => $v )
      {
         $tableau[$path."_".$k][] = $v;
      }
   }
}   
   
function fonctionBaliseFermante($parseur, $nomBalise)
{
   global $profondeur;
   global $tableau;

   if ($nomBalise=="PRODUCT")
   {
         $query = "INSERT INTO `'.$table.'` (
         `id_categorie`,
         `categorie`,
         `id_produit`,
         `produit`,
         `marque`,
         `description`,
         `image`,
         `nombre_marchands`,
         `tarif_moins`,
         `tarif_plus`,
         `caracteristique`,
         `valeur_caracteristique`,
         `marchand`,
         `lien`,
         `logo`,
         `stock`,
         `prix`,
         `prix_frais_port`
         ) VALUES (
         '".$tableau['PRODUCTS_PRODUCT_CATEGORY-ID'][0]."',
         '".$tableau['PRODUCTS_PRODUCT_CATEGORY'][0]."',
         '".$tableau['PRODUCTS_PRODUCT_ID'][0]."',
         '".$tableau['PRODUCTS_PRODUCT_NAME'][0]."',
         '".$tableau['PRODUCTS_PRODUCT_MANUFACTURER'][0]."',
         '".$tableau['PRODUCTS_PRODUCT_DESCRIPTION'][0]."',
         '".$tableau['PRODUCTS_PRODUCT_IMAGE-URL'][0]."',
         '".$tableau['PRODUCTS_PRODUCT_NUMBER-OF-RETAILERS'][0]."',
         '".$tableau['PRODUCTS_PRODUCT_LOWEST-PRICE'][0]."',
         '".$tableau['PRODUCTS_PRODUCT_HIGHEST-PRICE'][0]."',
         '".implode( "|", $tableau['PRODUCTS_PRODUCT_PROPERTIES_GROUP_PROPERTY_NAME'])."',
         '".implode( "|", $tableau['PRODUCTS_PRODUCT_PROPERTIES_GROUP_PROPERTY_VALUE'])."'
       '".implode( "|", $tableau['PRODUCTS_PRODUCT_RETAILER_NAME'])."',
       '".implode( "|", $tableau['PRODUCTS_PRODUCT_RETAILER_LINK'])."',
       '".implode( "|", $tableau['PRODUCTS_PRODUCT_RETAILER_LOGO'])."',
       '".implode( "|", $tableau['PRODUCTS_PRODUCT_RETAILER_STOCK-INFO'])."',
       '".implode( "|", $tableau['PRODUCTS_PRODUCT_RETAILER_PRICE'])."',
       '".implode( "|", $tableau['PRODUCTS_PRODUCT_RETAILER_PRICE-WITH-SHIPPING-MIN'])."'
         );";
         $result = mysql_query($query);
           
      $tableau=array();
    }
     
   array_pop( $profondeur );
}   
   

function fonctionTexte($parseur, $texte)
{
   global $profondeur;
   global $tableau;

   $path = implode( "_", $profondeur );
     
   $tableau[$path][] = $texte;
}


Parser un xml ( durée du traitement )

Si vous avez aimé cette discussion, partagez-la sur vos réseaux sociaux préférés :

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité