XML naviguer en profondeur ??

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par seabird, 31 Mai 2008.

  1. seabird
    seabird WRInaute occasionnel
    Inscrit:
    1 Décembre 2003
    Messages:
    318
    J'aime reçus:
    0
    Bonjour,

    J'ai à ma disposition un flux de cette structure.

    Code:
    <Categories>
    	<Country>FR</Country>
    	<Language>FrFr</Language>
    	<Category>
    		<Name>NOM1</Name>
    		<ID>1</ID>
    		<Url>URL1</Url>
    			<Category>
    				<Name>NOM2</Name>
    				<ID>5</ID>
    				<Url>URL2</Url>
    				<ProductCategory>
    					<Name>NOM3</Name>
    					<ID>6</ID>
    					<Url>URL3</Url>
    				</ProductCategory>
    				<ProductCategory>
    					<Name>NOM4</Name>
    					<ID>9</ID>
    					<Url>URL4</Url>
    				</ProductCategory>
    			</Category>
    	</Category>
    </Categories>
    J'ai des problèmes pour lire les éléments en profondeurs. En effet comment distinguer les item category qui ont des profondeurs différentes ??

    En général je lit mes fichiers xml avec cette fonction sans problème, mais j'ai toujours eu des fichiers sans profondeur.

    Code:
    function lit_xml1($fichier,$item,$champs) {
    
       if($chaine = @implode("",@file($fichier))) {
    
          $tmp = preg_split("/<\/?".$item.">/",$chaine);
    	 
    
    	  $nombre = sizeof($tmp);
    
    
          for($i=1;$i<$nombre -1;$i+=2)
    
             foreach($champs as $champ) {
                $tmp2 = preg_split("/<\/?".$champ.">/",$tmp[$i]);
    
                $tmp3[$i-1][] = @$tmp2[1];
    			
    			
             }
    
          return $tmp3;
       }
    }

    J'utilise aussi ce code, mais la aussi je bloque pour naviguer en profondeur:

    Code:
    <?php
        $fichier = "fichier.xml";
    
        // Ma propre fonction de traitement des balises ouvrantes
        function fonctionBaliseOuvrante($parseur, $nomBalise, $tableauAttributs)
        {
            // En fait... nous nous conteterons de mémoriser le nom de la balise
            // afin d'en tenir compte dans la fonction "fonctionTexte"
    
            global $derniereBaliseRencontree;
    
            $derniereBaliseRencontree = $nomBalise;
        }
       
        // Ma propre fonction de traitement des balises fermantes
        function fonctionBaliseFermante($parseur, $nomBalise)
        {
            // On oublie la dernière balise rencontrée
            global $derniereBaliseRencontree;
    
            $derniereBaliseRencontree = "";
        }
    
        // Ma propre fonction de traitement du texte
        // qui est appelée par le "parseur"
        function fonctionTexte($parseur, $texte)
        {
            global $derniereBaliseRencontree;
            
            // Selon les cas, nous affichons le texte
            // ou nous proposons un lien
            // ATTENTION: Par défaut les noms des balises sont
            //            mises en majuscules
            
            switch ($derniereBaliseRencontree) {
                case "TITLE": 
                    echo $texte;
                    break;
                case "LINK":
                    echo ":<a href=\"$texte\">L'article complet</a><br />";
                    break;
            }         
        }
    
        // Création du parseur XML
        $parseurXML = xml_parser_create();
    
        // Je précise le nom des fonctions à appeler
        // lorsque des balises ouvrantes ou fermantes sont rencontrées
        xml_set_element_handler($parseurXML, "fonctionBaliseOuvrante"
                                           , "fonctionBaliseFermante");
    
        // Je précise le nom de la fonction à appeler
        // lorsque du texte est rencontré
        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)) {
            // Analyse de la ligne
            // REM: feof($fp) retourne TRUE s'il s'agit de la dernière
            //      ligne du fichier.
            xml_parse($parseurXML, $ligneXML, feof($fp)) or
                die("Erreur XML");
        }
        
        xml_parser_free($parseurXML);
        fclose($fp);
    ?>
    
    Comment faites-vous en général ??

    Merci
     
  2. Bool
    Bool WRInaute passionné
    Inscrit:
    26 Février 2004
    Messages:
    1 543
    J'aime reçus:
    0
    Hello,

    selon les cas j'utilise SimpleXML (pour des volumes de données assez petit), ou bien xml_parser mais en maintenant "une pile" des tags afin de connaître l'arborescence exacte.

    XMLReader serait également possible, l'approche étant sensiblement la même que xml_parser.
     
  3. seabird
    seabird WRInaute occasionnel
    Inscrit:
    1 Décembre 2003
    Messages:
    318
    J'aime reçus:
    0
    je ne vois pas trop comment connaitre l'arborescence. je sèche un peu là .. :?. Et je n'ai que PHP4 à ma disposition.
     
  4. Bacteries
    Bacteries WRInaute passionné
    Inscrit:
    27 Mai 2004
    Messages:
    1 253
    J'aime reçus:
    0
    Utilise SimpleXML comme suggéré par Bool, tu peux même faire du xpath via la méthode ->xpath() donc tu pourras faire ce que tu veux (le XML c'est fait pour être manipulé comme un arbre, DOM par exemple, pas un fichier texte!).

    Après le Xpath ça dépend de ce que tu veux faire mais c'est relativement simple.
     
  5. Bool
    Bool WRInaute passionné
    Inscrit:
    26 Février 2004
    Messages:
    1 543
    J'aime reçus:
    0
    dans ta fonction "baliseouvrante" tu fais un array_push() sur un tableau commun, et dans ta fonction "balisefermante" tu fais un array_pop().
    Hop c'est magique, ton tableau t'indique où tu te trouves dans ton arborescence.

    Dans tous les cas, il serait peut être temps de passer à PHP 5...
     
  6. seabird
    seabird WRInaute occasionnel
    Inscrit:
    1 Décembre 2003
    Messages:
    318
    J'aime reçus:
    0
    Merci pour ta suggestion , mais j'ai du mal à saisir la subtilité :?
    je ne vois pas trop ...
     
  7. Bool
    Bool WRInaute passionné
    Inscrit:
    26 Février 2004
    Messages:
    1 543
    J'aime reçus:
    0
    bah essayes dans ce cas...

    au pire tu peux jouer sur une méthode moins "propre" avec un compteur que tu incrémentes en cas d'ouverture de balise et que tu décrémentes en cas de fermeture. Ainsi il t'indiquera en permanence la "profondeur" actuelle.
     
  8. seabird
    seabird WRInaute occasionnel
    Inscrit:
    1 Décembre 2003
    Messages:
    318
    J'aime reçus:
    0
    Bon je pense avoir trouvé , ce n'est peut être pas tres élégant, mais ça marche. Merci de ta suggestion Bool :D .

    J'ai fait par exemple un test sur ce fichier xml:
    Code:
    <?xml version="1.0"?>
    <rss version="2.0">
      <channel>
    
    	<item>
    		<title>niveau4</title>
    		<link>niveau4</link>
    	</item>
        <item>
    		<title>niveau4</title>
    		<link>niveau4</link>
    		
    		<item>
    			<title>niveau5</title>
    			<link>niveau5</link>
    			
    			<item>
    				<title>niveau6</title>
    				<link>niveau6</link>
    			</item>	
    			
    		</item>	
    		
    	</item>	  	
    	
      </channel>
    </rss>    

    J'utilise donc ce code et j'affiche par exemple les données de profondeur 5 .
    Maintenant je me demande s'il n'y a pas moyen d'optimiser un peu.
    Code:
    
    <?php
    
    $profondeur = array();
    
    
        $fichier = "http://domaine.com/fluxrss.rss";
    
    
        function fonctionBaliseOuvrante($parseur, $nomBalise, $tableauAttributs)
          {
    
            global $derniereBaliseRencontree;
            $derniereBaliseRencontree = $nomBalise;
          
          global $profondeur;
          
          
          $profondeur[$parseur]++;
    
       //   print "Début de l'élément : ".$nomBalise."\n -- ";
    
          //print "profondeur : ".$profondeur[$parseur]." "; echo"<br>";
          
          }
       
        // Ma propre fonction de traitement des balises fermantes
        function fonctionBaliseFermante($parseur, $nomBalise)
          {
            // On oublie la dernière balise rencontrée
            global $derniereBaliseRencontree;
            $derniereBaliseRencontree = "";
    
          global $profondeur;
             
          
          //print "Fin de l'élément : ".$nomBalise." ";
    
          //print "profondeur : ".$profondeur[$parseur]." ";
    
          $profondeur[$parseur]--;
    
       
          //echo"<br>";   echo"<br>";      
          
          }
    
        function fonctionTexte($parseur, $texte)
        {
            global $derniereBaliseRencontree;
            global $profondeur;
    if (($derniereBaliseRencontree=="TITLE")&& $profondeur[$parseur]==5) {echo "<b>$texte</b>";echo"<br>";  }
      if (($derniereBaliseRencontree=="LINK")&& $profondeur[$parseur]==5) echo "<a href=\"$texte\"><b>Lien</b></a><br />";   
             
        }
    
        // 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);
    
    
    
    ?>
    
    
    Vous avez des suggestions ?
     
  9. seabird
    seabird WRInaute occasionnel
    Inscrit:
    1 Décembre 2003
    Messages:
    318
    J'aime reçus:
    0
    Salut,

    Je viens de trouver une autre méthode pour parser le flux et connaitre la profondeur.
    Ici j'affiche les balises "title" et "link" de profondeur 4.

    Par contre, je pense qu'il y a plus judicieux pour enregistrer le tableau des balises de leur profondeur et de leur contenu. ( il y a des positions vides , vu la manière d'enregistrer que j'utilise. )
    Quelqu'un à une idée ?


    Code:
    <?php
    $xml_doc = "test.xml";
    
    //on ouvre le fichier xml en lecture
    $handle = fopen ($xml_doc, "r");
    
    //on lit les données jusqu'à la fin du fichier et on les stocke dans un chaîne
    $data_to_parse = fread ($handle, filesize ($xml_doc));
    
    //on ferme le fichier xml
    fclose ($handle);
    
    //on crée un parseur XML
    $xml_parser = xml_parser_create();
    
    //on lui indique de ne pas transformer les balises en majuscule
    xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING,0);
    
    //on démarre l'analyse du XML et on stocke les données dans des tableaux
    xml_parse_into_struct($xml_parser, $data_to_parse, $tableau_valeurs, $tableau_index);
    
    //on détruit le parseur
    xml_parser_free($xml_parser);
    
    
    		for ($i=0; $i < count($tableau_valeurs); $i++)
    				{
    				//on fait un tableau des balises de leur profondeur et de leur contenu
    				$info[$tableau_valeurs[$i]["tag"]][$tableau_valeurs[$i]["level"]][$i] = $tableau_valeurs[$i]["value"];
    				}
    
    
    
    
    	for ($i=0; $i < count($tableau_valeurs); $i++)
    				{
    				if($info['title']['4'][$i]!="") {  echo $info['title']['4'][$i];echo"<br>";}
    				if($info['link']['4'][$i]!="") {  echo $info['link']['4'][$i];echo"<br><br>";}
    				}
    
    ?>
     
Chargement...
Similar Threads - XML naviguer profondeur Forum Date
tarifs flux xml programme TV Sport Développement d'un site Web ou d'une appli mobile 14 Novembre 2021
Gestion sitemap.xml sur un site multilingue Crawl et indexation Google, sitemaps 5 Octobre 2020
Parser en php un fichier xml Développement d'un site Web ou d'une appli mobile 12 Juin 2020
Supprimer le sitemap HTML et garder le XML Crawl et indexation Google, sitemaps 27 Avril 2020
Formule import xml Google sheet Débuter en référencement 6 Avril 2020
Besoin d'un sitemap.xml pour web app en REACT? Débuter en référencement 13 Février 2020
WordPress Yoast - Attachment-sitemap.xml à faire indexer ? Débuter en référencement 1 Février 2020
Parser un fichier xml : simplexml_load_file Développement d'un site Web ou d'une appli mobile 5 Avril 2019
Aide pour fichier XML e-commerce 28 Mars 2019
Comment intégrer un flux XML affiliation sur mon site WordPress ? Monétisation d'un site web 3 Octobre 2018
Quels outils pour générer un sitemap xml en ligne ? Référencement Google 20 Septembre 2018
Foaf, rdfs, purl, schema, sioct, xsd, xmlns signification de tout ces termes Référencement Google 22 Août 2018
Comment indiquer mon sitemap XML à Google ? Crawl et indexation Google, sitemaps 13 Août 2018
PHP : script pour mettre catalogue xml clickbank dans mysql Développement d'un site Web ou d'une appli mobile 6 Décembre 2017
Référencement et importation xml Référencement Google 23 Mai 2017
Google XML Sitemaps (wordpress). images en attachment Développement d'un site Web ou d'une appli mobile 10 Octobre 2016
Importance du crawl en cas de présence d'un sitemap XML dans Search Console Crawl et indexation Google, sitemaps 23 Juin 2016
[résolu] recupération de flux xml et erreur encodage des caractères Développement d'un site Web ou d'une appli mobile 27 Janvier 2016
Lastmod et priority utiles dans sitemap.xml ? Débuter en référencement 18 Septembre 2015
intégrer un flux XML e-commerce 26 Avril 2015