Parser un xml voluminueux sur plusieurs pages ?

Consultez la formation au référencement naturel Google de WebRankInfo / Ranking Metrics

seabird
WRInaute impliqué
WRInaute impliqué
 
Messages: 261
Inscription: Lun Déc 01, 2003 17:57

Parser un xml voluminueux sur plusieurs pages ?

Message le Mer Juin 07, 2006 15:33

bonjour,

Actuellement je parse un fichier xml en php, en faisant une mise en cache du code généré. Cependant maintenant le fichier xml devient un peu long. Je voudrais donc le parser sur plusieurs pages? Afficher par exemple 20 résultats par page.
Voila le code que j'utilise:


Code: Tout sélectionner

<?php

// le répertoire "cache"

$dir_cache = 'cache/';

// nom du fichier mis en cache
$file_cache1 = 'flux1.html';

if (!is_dir($dir_cache)) {
   exit ('Répertoire cache "'.$dir_cache.'" inexistant !');
}


   // on impose la mise à jour avec une certaine periodicité
$date_modif1 = time();
   // le delai entre deux rafraichissements en secondes
   $delai1 = 43200;


// le fichier est-il en cache et suffisamment jeune
$file_cache1 = $dir_cache.$file_cache1;
$en_cache1 = file_exists($file_cache1);
if ($en_cache1) {
   $en_cache1 = ($date_modif1 < filemtime($file_cache1) + $delai1);
}

if (!$en_cache1) {
   // Lecture d'un fichier XML
function lit_xml1($fichier,$item,$champs) {
   // on lit le fichier
   if($chaine = @implode("",@file($fichier))) {
      // on explode sur <item>
      $tmp = preg_split("/<\/?".$item.">/",$chaine);
    
   
     $nombre = sizeof($tmp);

      // pour chaque <item>
      for($i=1;$i<$nombre -1;$i+=2)
         // on lit les champs demandés <champ>
         foreach($champs as $champ) {
            $tmp2 = preg_split("/<\/?".$champ.">/",$tmp[$i]);
            // on ajoute au tableau
            $tmp3[$i-1][] = @$tmp2[1];
         }
      // et on retourne le tableau
      return $tmp3;
   }
}

// Exemple :
$xml1 = lit_xml1("http://monsite.com/xml.php","item",array("title","description","link","category","url"));

      foreach($xml1 as $row1) {
         
      
      $data1 .= '<br><table width=400 height=190 align=center cellpadding=0 cellspacing=0 bgcolor="#F8D630"  border=2>';
      $data1 .= '<tr>';
      $data1 .= '<td colspan=2 height=25 align=center bordercolor=#FFFFCC><a href='.$row1[2].'><font color="#000000">'.$row1[0].'</font> </a></td>';
      $data1 .= '</tr>';
      $data1 .= '<tr>';
      $data1 .= '<td bordercolor=#FFFFCC height="136" width="133" valign="middle" align="center"><a href='.$row1[2].'><img src='.$row1[4].' border=0></a></td>';
      $data1 .= '<td  bordercolor=#FFFFCC ><span class="tailledescrip" ><div style="margin-left:10px;">'.$row1[1].'</div></span></td>';
      $data1 .= '</tr>';
      $data1 .= '<tr>';
      $data1 .= '<td colspan=2 height=25 bordercolor=#FFFFCC><p><em>catégorie :</em> '.$row1[3].' <em> </td>';
      $data1 .= '</tr>';
      $data1 .= '</table><br>';
      
      
   }
   
   $fd1 = fopen($file_cache1, "w");
   fputs($fd1, $data1);
   fclose($fd1);

} // fin if !$en_cache1

include $file_cache1;
?>



Je ne vois pas trop comment modifier ce code ?

Merci
Dernière édition par seabird le Ven Juin 16, 2006 10:50, édité 1 fois.


MagicYoyo
WRInaute accro
WRInaute accro
 
Messages: 2563
Inscription: Lun Mai 24, 2004 15:33

Message le Mer Juin 07, 2006 16:12

Code: Tout sélectionner
$nombre = sizeof($tmp);

      // pour chaque <item>
      for($i=1;$i<$nombre -1;$i+=2)

Je penses que c'est là qu'il faut chercher la solution. Mais je suis pas développeur, alors je voudrais pas mettre le dawa dans ton appli ! :P

seabird
WRInaute impliqué
WRInaute impliqué
 
Messages: 261
Inscription: Lun Déc 01, 2003 17:57

Message le Ven Juin 09, 2006 23:48

Je me demande s'il ne serais pas plus simple d'enregistrer le xml dans la base mysql et de travailler dessus ensuite.
A ce sujet est ce que cela est possible d'ailleurs ?

Parce que la avec le xml, je ne vois pas trop comment faire..

Merci

seabird
WRInaute impliqué
WRInaute impliqué
 
Messages: 261
Inscription: Lun Déc 01, 2003 17:57

Message le Mer Juin 14, 2006 23:02

C'est bon j'ai réussi à intégrer un système de pagination sur le parser Xml. J'ai fait plusieurs tests, tout fonctionne correctement.
Cependant j'ai un autre soucis, je viens d'essayer de parser un gros fichier xml ( 10Mo ) et forcément j'ai eu '500 Internal Server Error' , vu qu'avant d'afficher les résultats , je mets toutes les données dans un tableau qui forcément est immense.
A votre avis comment est-ce que je pourrais faire pour ne lire qu'une partie du fichier xml puis afficher , puis lire la suite , puis afficher etc... Je pense que c'est le seul moyen de m'en sortir non ?

Merci

jobi1722
Nouveau WRInaute
 
Messages: 15
Inscription: Mar Juin 22, 2004 14:41

Message le Mer Juin 14, 2006 23:20

Salut,

comme tu le disais precedemment, il serait peut-etre interessant de mettre tout ca dans une base MySql.

Tu utilise le XML pour une raison spéciale ?

seabird
WRInaute impliqué
WRInaute impliqué
 
Messages: 261
Inscription: Lun Déc 01, 2003 17:57

Message le Mer Juin 14, 2006 23:26

Le fichier Xml m'est fourni, je dois travailler avec et extraire les données. Mais la je coince un peu. Quelqu'un a-t-il déjà parser un xml volumineux ?

spidetra
WRInaute accro
WRInaute accro
 
Messages: 1500
Inscription: Lun Juil 07, 2003 13:06

Message le Mer Juin 14, 2006 23:34

...
Dernière édition par spidetra le Ven Aoû 04, 2006 13:27, édité 1 fois.

jobi1722
Nouveau WRInaute
 
Messages: 15
Inscription: Mar Juin 22, 2004 14:41

Message le Mer Juin 14, 2006 23:36

Si tu ne peux pas passer par une base Mysql...

Tu peux essayer de modifier le script... et ne remplir le tableau qu'avec les données qui t'interessent.

il faut que tu modifies la fonction lit_xml1 pour qu'elle accepte 2 nouveaux paramètres, l'enregistrement de départ et le nombre d'enregistrements que tu souhaites.

function lit_xml1($fichier,$item,$champs,$depart,$nb) {


Puis tu modifes :

$nombre = sizeof($tmp);
if($nombre>$depart+$nb) $fin = $nombre;
else $fin = $depart+$nb;
for($i=$depart;$i<$fin-1;$i+=2)
// on lit les champs demandés <champ>
foreach($champs as $champ) {
$tmp2 = preg_split("/<\/?".$champ.">/",$tmp[$i]);
// on ajoute au tableau
$tmp3[$i-1][] = @$tmp2[1];
}
// et on retourne le tableau
return $tmp3;
}

Ca devrait etre un truc du genre.

Sinon cherche sur internet, il y a des scripts qui permettent de récupérer le XML (je connais pas trop).

Essaye et tiens moi au courant... :)

seabird
WRInaute impliqué
WRInaute impliqué
 
Messages: 261
Inscription: Lun Déc 01, 2003 17:57

Message le Jeu Juin 15, 2006 7:23

jobi1722 a écrit:Si tu ne peux pas passer par une base Mysql...

Tu peux essayer de modifier le script... et ne remplir le tableau qu'avec les données qui t'interessent.

il faut que tu modifies la fonction lit_xml1 pour qu'elle accepte 2 nouveaux paramètres, l'enregistrement de départ et le nombre d'enregistrements que tu souhaites.

function lit_xml1($fichier,$item,$champs,$depart,$nb) {


Puis tu modifes :

$nombre = sizeof($tmp);
if($nombre>$depart+$nb) $fin = $nombre;
else $fin = $depart+$nb;
for($i=$depart;$i<$fin-1;$i+=2)
// on lit les champs demandés <champ>
foreach($champs as $champ) {
$tmp2 = preg_split("/<\/?".$champ.">/",$tmp[$i]);
// on ajoute au tableau
$tmp3[$i-1][] = @$tmp2[1];
}
// et on retourne le tableau
return $tmp3;
}

Ca devrait etre un truc du genre.

Sinon cherche sur internet, il y a des scripts qui permettent de récupérer le XML (je connais pas trop).

Essaye et tiens moi au courant... :)


J'ai déja essayé de faire ca , en ne remplissant que quelques enregistrements. Mais cela plante qd meme , le problème vient de

Code: Tout sélectionner
if($chaine = @implode("",@file($fichier))) {
      // on explode sur <item>
      $tmp = preg_split("/<\/?".$item.">/",$chaine);


La chaine est trop grande. C'est pour ça que je voudrais soit couper le xml en plusieurs fichiers, soit ne mettre dans la chaine qu'une partie du xml à chaque fois. hummmm....

seabird
WRInaute impliqué
WRInaute impliqué
 
Messages: 261
Inscription: Lun Déc 01, 2003 17:57

Message le Jeu Juin 15, 2006 23:43

Je suis en train de me décider a couper le xml en plusieurs fichiers. Mais j'ai un petit soucis:

Voila la structure du xml de 10Mo, tres simple.

<item>
........
</item>
<item>
.......
</item>
.....


Voila le code que j'ai ecrit:
J'ai choisi pour l'exemple des fichiers qui ne devrait contenir que 2 items

Code: Tout sélectionner
<?php

$fichier="essai.xml";
$nbrs_item=2;
$sauv="sav";
$compteur=0;
$nbrs_fichier=1;


$fp=fopen($fichier,"r");

    while (!feof($fp)) {

         while (($compteur <$nbrs_item )&& (!feof($fp)))
         
             { $ligne=fgets($fp,255);
                  $compteur=$compteur+substr_count($ligne,"</item>");
              $chaine.=$ligne;
             
      
            }//fin while compteur
      
      
      
$fp2 = fopen($sauv.$nbrs_fichier.'.xml',"w"); // ouverture du fichier en écriture

fputs($fp2, "$chaine"); // on écrit le texte choisi dans le fichier

fclose($fp2);
      
      
$compteur=0;
$nbrs_fichier+=1;
$ligne="";
$chaine.="";
                        } // fin feof
      
      fclose($fp);
   
?>


Pour le premier fichier sauvé, sav1.xml tout va bien. J'ai bien 2 item.
Pour le 2iéme par contre il en contient 4 , il s'additionnent à ceux de sav1. Et ainsi de suite.

En fait je pensais que puisque je ne fermais pas le fichier entre 2 sauvegardes la lecture continuerait vers le bas. Mais non cela recommence du début :-(.
Je coince un peu là. Comment donc enregistrer des fichiers qui vont contenir un nombre déterminé d'item ?

Merci pour votre aide.

seabird
WRInaute impliqué
WRInaute impliqué
 
Messages: 261
Inscription: Lun Déc 01, 2003 17:57

Message le Ven Juin 16, 2006 10:50

c'est bon j'ai trouvé :D .

Code: Tout sélectionner
<?php

$fichier="essai2.xml";
$nbrs_item=6;
$titre="sav";


$compteur=0;
$nbrs_fichier=1;


$fp=fopen($fichier,"r");

    while (!feof($fp)) {

         while (($compteur <=$nbrs_item)&&(!feof($fp)))
         
             { $ligne=fgets($fp,255);
               $compteur=$compteur+substr_count($ligne,"</item>");
              $chaine.=$ligne;
             
             
             
         if (( $compteur==$nbrs_item)||(($compteur <=$nbrs_item )&&(feof($fp))))
            {
       
            $fp2 = fopen($titre.$nbrs_fichier.'.xml',"w"); // ouverture du fichier en écriture

              fputs($fp2, "$chaine"); // on écrit le texte choisi dans le fichier

              fclose($fp2);
             
            $compteur+=1;
            }
             
             
             
             
             
            }//fin while compteur
       
       
       
      $chaine="";
   
       $nbrs_fichier+=1;
       
      $compteur=0;
       
      $ligne="";
       
      } // fin feof
       
      fclose($fp);
   
?>


dom84
Nouveau WRInaute
 
Messages: 46
Inscription: Mer Mai 31, 2006 13:24

Message le Ven Juin 16, 2006 11:17

Moi j ai aussi un probleme avec le parsing xml :

dans un premier temps, nous effectuons une requete vers un serveur qui a un temps de reponse plus ou moins long selon les specificités de la requete;
nous arrivons a parser cette requete avec un parser :

Code: Tout sélectionner
<?
class XMLParser {
   var $filename;
   var $xml;
   var $data;
   
   function XMLParser($xml_file)
   {
       $this->filename = $xml_file;
       $this->xml = xml_parser_create();
       xml_set_object($this->xml, $this);
       xml_set_element_handler($this->xml, 'startHandler', 'endHandler');
       xml_set_character_data_handler($this->xml, 'dataHandler');
       $this->parse($xml_file);
   }
   
   function parse($xml_file)
   {
       if (!($fp = fopen($xml_file, 'r'))) {
             die('Cannot open XML data file: '.$xml_file);
               return false;
       }

       $bytes_to_parse = 512;

       while ($data = fread($fp, $bytes_to_parse)) {
           $parse = xml_parse($this->xml, $data, feof($fp));
           
           if (!$parse) {
               die(sprintf("XML error: %s at line %d",
                   xml_error_string(xml_get_error_code($this->xml)),
                       xml_get_current_line_number($this->xml)));
                       xml_parser_free($this->xml
                     );
           }
       }

       return true;
   }
   
   function startHandler($parser, $name, $attributes)
   {
       $data['name'] = $name;
       if ($attributes) { $data['attributes'] = $attributes; }
       $this->data[] = $data;
   }

   function dataHandler($parser, $data)
     {
     if($data = trim($data))
         {
         $index = count($this->data) -1;
         if(isset($this->data[$index]['content']))
           $this->data[$index]['content'] .= $data;
           else $this->data[$index]['content'] = $data;
         }
     }


   function endHandler($parser, $name)
   {
       if (count($this->data) > 1) {
           $data = array_pop($this->data);
           $index = count($this->data) - 1;
           $this->data[$index]['child'][] = $data;
       }
   }
function ReturnData ()
{
  return $this->data;   
}
}
?>


Que pensez vous de ce parser ??

Sachant que nous avons de gros problemes de performances du fait de ce parsing... Le parsing prend beaucoup de ressources, et le trafic sur notre site augmentant, notre serveur sature.

Avez vous une solution ??
Merci d'avance

shrom
WRInaute passionné
WRInaute passionné
 
Messages: 865
Inscription: Lun Juil 05, 2004 22:37

Message le Ven Juin 16, 2006 13:13

Je vois pas bien l'intéret d'avoir à la base un fichier XML et de tout stocker dans des tableaux, c'est un peu contre productif.

S'il y a besoin de faire des traitement sur les données, autant utiliser DOM, ce sera plus efficace et si c'est pour faire de l'affichage direct, autant le faire directement à partir du parser SAX.

dom84
Nouveau WRInaute
 
Messages: 46
Inscription: Mer Mai 31, 2006 13:24

Message le Ven Juin 16, 2006 14:44

En fait on a deja une base de données et un tableau liste de resultats pour une requete donnée,
et on utilise le flux xml de partenaires pour ajouter leurs resultats aux notres par rapport a la requete donnée.

Du coup, on ne peut afficher directement les données du flux, c est pour cela qu on stocke au prealable dans un tableau, pour comparer les resultats avec les notres et les concatenér.


Avons nous une autre possibilité ?

dom84
Nouveau WRInaute
 
Messages: 46
Inscription: Mer Mai 31, 2006 13:24

Message le Lun Juin 19, 2006 8:23

Personne n ' a deja ete confronté a ce genre de probleme ?

Parser un xml voluminueux sur plusieurs pages ?

Formation recommandée sur ce thème :

Formation Référencement naturel Google : apprenez une méthode efficace pour optimiser à fond le référencement naturel dans Google de façon durable... Formation animée par Olivier Duffez et Fabien Facériès, experts en référencement naturel.

Tous les détails sur le site Ranking Metrics : programme, prix, dates et lieux, inscription en ligne.

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités