p
u
b
l
i
c
i
t
é
publicité
  1. #1
    Membre du Club
    Inscrit en
    février 2008
    Messages
    149
    Détails du profil
    Informations forums :
    Inscription : février 2008
    Messages : 149
    Points : 52
    Points
    52

    Par défaut Analyseur avec SAX en PHP

    Bonjour,

    je réalise un parseur xml avec sax, je ne suis pas loin de mon but, mais la je séche.

    J'utilise un script que j'ai pris dans un livre sur php5, sauf que celui-ci n'aborde pas trop les attributs et je ne m'en sort pas.

    Voici un apecu du flux a parsser: (j'ai ajouté des " " aux urls sinon elles étaient considérées comme des commentaires)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    <flux>
      <product id="3712570687" number="3009703025074645">
       <affiliateprogram id="3076"/>
     
      <info>
       <name>Robe grossesse imprimée.</name>
       <description state="long">En pur satin de coton, cette robe est un vrai coup de coeur ! On peut la mixer à une longue veste laineuse facile à dénicher sur le site. Patte de boutonnage sous l'encolure. Fronces sous l'empiècement devant, au dos, aux poignets et sur les épaules. Manches 3/4.</description>
       <manufacturer>COLLINE</manufacturer>
      </info>
     
      <category>
       <merchant>VETEMENTS GROSSESSE / Robe et jupe mode /rossesse</merchant>
      </category>
     
      <links>
       <deeplink>"http://www.site.com/ppc/?10500085C1525724405&ULP=[[3009703025074645]]"</deeplink>
       <image state="medium">
        <url>"http://www.site.com/productimage/74/bp/3X_00970_3025.jpg"</url>
       </image>
       <image state="large">
        <url>"http://www.site.com/productimage/74/BM/3X_00970_3025.jpg"</url>
       </image>
      </links>
     
    </product>
    </flux>
    Voici mon parseur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
     
    <?php
     
    class rss
    {
    	var $item = FALSE ;
    	var $chem = '' ;
    	var $id ;
    	var $number ;
    	var $id_programme ;
    	var $name ;	
    	var $description ;
    	var $manufacturer ;
    	var $merchant ;
    	var $deeplink ;
    	var $image_medium ;
    	var $image_large ;
    	var $resume = array() ;
     
    		function ouvre($sax, $nom, $attributs)
    		{
    			$this->chem .= '/'.$nom;
     
    			if ($this->chem=='/flux/product')
    			{
    				$this->id = '';
    				$this->number = '';
    				$this->id_programme = '';
    				$this->name = '';				
    				$this->description = '';
    				$this->manufacturer = '';
    				$this->merchant = '';
    				$this->deeplink = '';
    				$this->image_medium = '';
    				$this->image_large = '';
    				$this->item = TRUE;
    				$id = $attributs['id'];
    				$number = $attributs['number'];
    				echo '$id vaut:' . $id . '<br />';
    				echo '$number vaut:' . $number . '<br />';
    			}
    			elseif ($this->chem=='/flux/product/affiliateprogram')
    			{
    				$id_programme = $attributs['id'];				
    				echo '$id_programme vaut:' . $id_programme . '<br />';
    			}			
    		}		
     
    		function ferme($sax,$nom)
    		{
    			if ($this->chem=='/flux/product')
    			{
    				$name = htmlentities($this->name, ENT_QUOTES, 'UTF-8');				
    				$description = htmlentities($this->description, ENT_QUOTES, 'UTF-8');
    				$manufacturer = htmlentities($this->manufacturer, ENT_QUOTES, 'UTF-8');
    				$merchant = htmlentities($this->merchant, ENT_QUOTES, 'UTF-8');
    				$deeplink = htmlentities($this->deeplink, ENT_QUOTES, 'UTF-8');								
    				echo "$name<br />";
    				echo "$description<br />";
    				echo "$manufacturer<br />";
    				echo "$merchant<br />";
    				echo "$deeplink<br /><br />";	
    			}
     
    			$pos = strrpos($this->chem, '/');
    			$this->chem = substr($this->chem, 0, $pos);
    		}		
     
    		function texte($sax, $texte)
    		{
    			if ($this->chem == '/flux/product/info/name')
    			{
    				$this->name .= $texte;				
    			}
    			elseif ($this->chem == '/flux/product/info/description')
    			{
    				$this->description .= $texte;				
    			}
    			elseif ($this->chem == '/flux/product/info/manufacturer')
    			{
    				$this->manufacturer .= $texte;				
    			}
    			elseif ($this->chem == '/flux/product/category/merchant')
    			{
    				$this->merchant .= $texte;				
    			}
    			elseif ($this->chem == '/flux/product/links/deeplink')
    			{
    				$this->deeplink .= $texte;				
    			}			
    		}		
     
    }
     
    $rss = new rss();
    $sax = xml_parser_create();
    xml_parser_set_option($sax, XML_OPTION_CASE_FOLDING, FALSE);  // laisse le nom des balise en minuscule
    xml_set_object($sax, $rss);
    xml_set_element_handler($sax, 'ouvre', 'ferme');
    xml_set_character_data_handler($sax, 'texte');
    $fichier = 'http://www.mon-site.fr/flux.xml';
    $fp = fopen($fichier, 'r');
    while ($xml = fread($fp, 1024))
    {
    	xml_parse($sax, $xml, feof($fp));  // On execute
    }
    xml_parser_free($sax);
     
    ?>
    Donc voila:

    J'ai réussi a adapter le script de base pour récupérer le contenu du flux.

    j'ai adapté un peu "à l'arrache" pour récupérer les attributs, mais ça marche. Je dis à l'arrache car ce n'est pas simple du tout, je trouve. Je suis preneur d'une méthode plus propre bien entendu.

    Maintenant je voudrais mettre l'url de l'image medium dans la variable $image_medium et l'url de l'image large dans la variable $image_large

    Comment je peux faire pour dire si chem='/flux/product/links/image' et que l'attribut est "medium" donc j'enregistre dans $image_medium.

    et si chem='/flux/product/links/image' et que l'attribut est "large" donc j'enregistre dans $image_large.

    Je ne peux malheureusement pas modifier le flux.

    En espérant avoir réussi à me faire comprendre.

    Merci d'avance.

    PS: Je ne trouve pas grand chose d'intérréssent sur sax en php sur le net, donc pas facile de me débrouiller tout seul. Si vous avez des adresses qui pourrait m'aider, n'hésitez pas.

  2. #2
    Membre du Club
    Inscrit en
    février 2008
    Messages
    149
    Détails du profil
    Informations forums :
    Inscription : février 2008
    Messages : 149
    Points : 52
    Points
    52

    Par défaut Analyseur XML avec SAX en PHP

    Bonjour,

    N'ayant eu aucune réponse et n'ayant toujours pas résolu mon problème, je le reformule plus simplement (j'espère du moins) en espérant que quelqu'un pourra m'aider.

    je réalise un parseur xml avec sax en php. et je bloque à partir du moment ou il y a des éléments de même nom avec des attributs différents.

    voici un exemple pour résumé ce qui me pose problème.

    le flux:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <flux>
    	<product>
    		<info>
    			<description state="court">La description courte de mon produit.</description>
    			<description state="long">La description longue de mon produit.</description>
    		</info>
    	</product>
    </flux>
    mon parseur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     
    <?php
     
    class parseur
    {
    	//Je déclare mes variable.
    	var $item = FALSE ;
    	var $chem = '' ;
    	var $description_court ;	
    	var $description_long ;	
    	var $nouveau_art = array();
    	var $resume = array() ;
     
    		function ouvre($sax, $nom, $attributs) // Balise ouvrante
    		{
    			global $item, $chem, $description_long, $description_court, $nouveau_art ;
     
    			$this->chem .= '/'.$nom;
     
    			if ($this->chem=='/flux/product')
    			{
    				$this->description_court = '';
    				$this->description_long = '';				
    				$this->item = TRUE;						
    			}			
    			elseif ($this->chem=='/flux/product/info/description') // Je modifie $nom pour différencier description_court et description_long
    			{
    				$nom .= '_' . $attributs["state"];
    				$nom .= '_' . $attributs["state"];				
    			}					
    		}		
     
    		function ferme($sax,$nom)  // Balise fermante
    		{
    			global $item, $chem, $description_long, $description_court, $nouveau_art ;
     
    			if ($this->chem=='/flux/product')
    			{
    				$description_court = utf8_decode($this->description_court);				
    				$description_long = utf8_decode($this->description_long);								
     
    				// Je met le contenu dans un tableau pour le réutiliser ensuite.
    				$nouveau_art []= array ('description_court' => $description_long,
    										 'description_longue' => $description_long);				
     
    			}			
     
    			$pos = strrpos($this->chem, '/');
    			$this->chem = substr($this->chem, 0, $pos);
    		}		
     
    		function texte($sax, $texte) //Fonction texte
    		{
    			if ($this->chem == '/flux/product/info/description')
    			{
    				$this->description_court .= $texte;
    				$this->description_long .= $texte;				
    			}							
    		}		
    }
     
    $parseur = new parseur();
    $sax = xml_parser_create();
    xml_parser_set_option($sax, XML_OPTION_CASE_FOLDING, FALSE);  // laisse le nom des balise en minuscule
    xml_set_object($sax, $parseur);
    xml_set_element_handler($sax, 'ouvre', 'ferme');
    xml_set_character_data_handler($sax, 'texte'); // J'assigne la fonction texte à tout événement textuel.
    $fichier = 'flux.xml';
    $fp = fopen($fichier, 'r');
    while ($xml = fread($fp, 10000))
    {
    	xml_parse($sax, $xml, feof($fp));  // On execute l'ensemble
    }
    xml_parser_free($sax);  // Libére de la mémoire.
     
    // Je regarde ce qu'il y a dans mon tableau.
    echo '$nouveau_art contient:<br />';
    echo '<pre>';
    print_r($nouveau_art);
    echo '</pre>';
    ?>
    J'arrive a modifier le nom de l'élément en l'appelant nomElement_Attribut, mais je n'arrive pas a récupérer séparément le contenu de chaque élément (du même nom) avec un attribut différent.

    Dans l'exemple ci-dessus je met le contenu dans un tableau et à la fin je regarde ce qu'il contient.
    Actuellemnt j'obteiens ceci.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    $nouveau_art contient:
     
    Array
    (
        [0] => Array
            (
                [description_court] => La description courte de mon produit.La description longue de mon produit.
                [description_longue] => La description courte de mon produit.La description longue de mon produit.
            )
     
    )
    Les deux descriptions sont bout à bout, alors que je voudrais avoir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    $nouveau_art contient:
     
    Array
    (
        [0] => Array
            (
                [description_court] => La description courte de mon produit.
                [description_longue] => La description longue de mon produit.
            )
     
    )
    Si quelqu'un peut m'aider, me donner une piste pour résoudre mon problème, ce serait génial.
    Toute info est la bien venu.

    Je ne trouve pas grand chose sur le net. si vous avez des adresses sur le sujet, je suis preneur également.

    Merci d'avance.

  3. #3
    Invité de passage
    Homme Profil pro
    debutant
    Inscrit en
    avril 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : debutant
    Secteur : Biens de consommation

    Informations forums :
    Inscription : avril 2012
    Messages : 4
    Points : 3
    Points
    3

    Par défaut Analyseur avec SAX en PHP

    J'ai contourné ce problème ayant un parser du même style
    Je ne récupère pas les données par les attributs
    par contre je récupère les éléments sur la balise fermante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $image = array($this->image);
    et après on récupère $image[0] $image[1] ...

Discussions similaires

  1. generer fichier php pour obtenir fichier xml avec sax
    Par valmelissa dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 19/05/2011, 18h22
  2. [EXPAT] Parcours d'un XML (avec sax) en PHP
    Par GLSpirit dans le forum XML
    Réponses: 1
    Dernier message: 09/07/2007, 01h29
  3. limit et temps d'execution avec oracle et PHP
    Par dor_boucle dans le forum Oracle
    Réponses: 20
    Dernier message: 10/12/2005, 14h31
  4. [SAX] parsing avec sax
    Par jdar dans le forum XML
    Réponses: 4
    Dernier message: 03/12/2004, 21h34
  5. Pb d'execution de requete avec un script php
    Par ythierrin dans le forum Requêtes
    Réponses: 3
    Dernier message: 22/08/2003, 14h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo