Aller au contenu

Parsing XML en php


Recif

Sujets conseillés

Bonjour,

J'ai beau surfer sur les sites qui donnent des exemples, je suis complêtement à la rue en ce qui concerne le parsing xml en php! :wacko:

J'ai une simple page xml à récupérer :

<?xml version="1.0" encoding="iso-8859-1" ?> 
- <ListeArtiste>
 <nb_reponse>337</nb_reponse>
 <Artiste id="7732">Abba</Artiste>
 <Artiste id="7509">Ace Of Base</Artiste>
 <Artiste id="7733">Adamo</Artiste>
</ListeArtiste>

Et j'arrive pas à récupérer quoi que ce soit... Quelqu'un pourrait m'aider à chopper l'artiste id et le nom de l'artiste?...

Merci,

Stephane

Lien vers le commentaire
Partager sur d’autres sites

salut !

Si tu es en version 5 de PHP, tu as simpleXML qui est intégré. A toi les joies de la doc :-) Si tu es en PHP4, j'ai un bout de code pour toi. J'utilise l'ancien parser XML de PHP qui est un peu lourdinque à utiliser mais très simple d'emploi. J'en ai fait un petit RSS Reader tout pourri :)

Le principe général :

- on crée un parser XML

- on lui attribue des callbacks qui seront appelés en fonction de ce qu'il rencontre pendant le parsing

- on lui donne des data à parser

- et voilà :)

function xml_open($parser,$elmt,$attr)
{
global $lastelmt,$nb_rssnews;

$lastelmt=$elmt;
if ($elmt=="ITEM")
{
 $nb_rssnews++;
}
}

function xml_data($parser,$data)
{
global $lastelmt,$nb_rssnews,$rssnews,$rssencodage;

if ($rssencodage)
{
 $data=utf8_decode($data);
}
if ( $nb_rssnews != -1 )
{
 if ( $lastelmt == "TITLE" )
 {
 $rssnews[$nb_rssnews]["titre"].=$data;
 }
 if ( $lastelmt == "LINK" )
 {
 $rssnews[$nb_rssnews]["link"].=$data;
 }
 if ( $lastelmt == "PUBDATE")
 {
 $rssnews[$nb_rssnews]["pubdate"].=$data;
 }
 if ( $lastelmt == "DESCRIPTION" )
 {
 $rssnews[$nb_rssnews]["desc"].=$data;
 }
}
}

function xml_close($parser,$elmt)
{
}

function compare($a, $b)
{
if ( $a["ts"] < $b["ts"] )
{
 return(1);
}
if ( $a["ts"] > $b["ts"] )
{
 return(-1);
}
if ( $a["ts"] == $b["ts"] )
{
 return(0);
}
}

function ReadRSS($adresse,$encodage,&$resrssnews)
{
global $last_elmt;
global $nb_rssnews;
global $rssnews;
global $rssencodage;
 
$rssnews=array();

$rssencodage=$encodage;
$lastelmt="";
$nb_rssnews=-1;

$parser=xml_parser_create();
xml_set_element_handler($parser,"xml_open","xml_close");
xml_set_character_data_handler($parser,"xml_data");
$err=0;

@$fp = _AT_fopen($adresse,"r");
if ($fp)
{
 while ($data = fread($fp, 4096))
 {
 if ( !@xml_parse($parser, $data, feof($fp)) )
 {
   $err=1;
   break;
 }
 }
 fclose($fp);
}
else
{  
 $err=1;
}
xml_parser_free($parser);
$nb_rssnews++;

if ( !$err )
{
 for($i=0; $i<$nb_rssnews; $i++)
 {  
 if ( strlen( $rssnews[$i]["desc"] ) < 10 )
 {
   $rssnews[$i]["desc"]="";
 }
 
 sscanf($rssnews[$i]["pubdate"],"%s %02d %s %04d %02d:%02d:%02d GMT",
                   $rssnews[$i]["jour_str"],
                   $rssnews[$i]["jour"],
                   $rssnews[$i]["mois_str"],
                   $rssnews[$i]["annee"],
                   $rssnews[$i]["heure"],
                   $rssnews[$i]["minute"],
                   $rssnews[$i]["seconde"]);  
 
 if ($rssnews[$i]["mois_str"]=="Jan") $rssnews[$i]["mois"]=1;
 if ($rssnews[$i]["mois_str"]=="Feb") $rssnews[$i]["mois"]=2;
 if ($rssnews[$i]["mois_str"]=="Mar") $rssnews[$i]["mois"]=3;
 if ($rssnews[$i]["mois_str"]=="Apr") $rssnews[$i]["mois"]=4;
 if ($rssnews[$i]["mois_str"]=="May") $rssnews[$i]["mois"]=5;
 if ($rssnews[$i]["mois_str"]=="Jun") $rssnews[$i]["mois"]=6;
 if ($rssnews[$i]["mois_str"]=="Jul") $rssnews[$i]["mois"]=7;
 if ($rssnews[$i]["mois_str"]=="Aug") $rssnews[$i]["mois"]=8;
 if ($rssnews[$i]["mois_str"]=="Sep") $rssnews[$i]["mois"]=9;
 if ($rssnews[$i]["mois_str"]=="Oct") $rssnews[$i]["mois"]=10;
 if ($rssnews[$i]["mois_str"]=="Nov") $rssnews[$i]["mois"]=11;
 if ($rssnews[$i]["mois_str"]=="Dec") $rssnews[$i]["mois"]=12;
 
 $rssnews[$i]["ts"]=gmmktime(
         $rssnews[$i]["heure"],
         $rssnews[$i]["minute"],
         $rssnews[$i]["seconde"],
         $rssnews[$i]["mois"],
         $rssnews[$i]["jour"],
         $rssnews[$i]["annee"]);
 }
 
 
 
 usort($rssnews,"compare");
 
 $resrssnews=$rssnews;
 
 return(1);
}
return(0);
}

Lien vers le commentaire
Partager sur d’autres sites

Dans ce cas il faut que tu crees un parseur XML ... C'est pas tres complique, mais plus qu'avec php5 :)

Si t'es pas deja alle voir, tu peux essayer http://php.net/XML, dans les exemples ils montrent comment faire ce que tu cherches.

(desole pour les accents :) )

Lien vers le commentaire
Partager sur d’autres sites

Oui, j'ai déjà vue cette page... Mais je ne m'en suis pas sorti... C'est vraiment pas évident la logique là dedans :wacko:

Bon, je vais y remettre un peu le nez...

Lien vers le commentaire
Partager sur d’autres sites

Non, vraiment, c'est imbouffable, je n'arrive pas à dénicher la moindre piste logique là dedans... Quelqu'un pourrait me donner un exemple ou un début, quelque chose, je sais pas?... Un modele que je pourrais suivre ou autre?

Lien vers le commentaire
Partager sur d’autres sites

Ce qui est le plus simple c'est de transformer le xml en un tableau PHP. Il y a pas mal de fonctions qui trainent a ce sujet "xmlToArray".

En gros il te faut un parser, une fonction pour les elements de depart, pour les elements de fin, et une autre pour les donnees.

Voici un exemple qui te permet juste d'acceder a tes donnees, sans passer par un tableau :

go.xml :

<ListeArtiste>
<nb_reponse>337</nb_reponse>
<Artiste id="7732">Abba</Artiste>
<Artiste id="7509">Ace Of Base</Artiste>
<Artiste id="7733">Adamo</Artiste>
</ListeArtiste>

go.php :

<?php
$file = "go.xml";
$depth = array();

function startElement($parser, $name, $attrs)
{
  global $depth;
  for ($i = 0; $i < $depth[$parser]; $i++) {
      echo ". ";
  }
  if($attrs['ID'])
    echo "$name (".$attrs['ID'].")<br>";
  else
    echo "$name<br>";
  $depth[$parser]++;
}
function characterData($parser, $data)
{
  if(trim($data) == '') return false;
  global $depth;
  for ($i = 0; $i < $depth[$parser]; $i++) {
      echo ". ";
  }
  echo "'$data'<br>";
}

function endElement($parser, $name)
{
  global $depth;
  $depth[$parser]--;
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
if (!($fp = fopen($file, "r"))) {
  die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
  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);
?>

affichage :

LISTEARTISTE
. NB_REPONSE
. . '337'
. ARTISTE (7732)
. . 'Abba'
. ARTISTE (7509)
. . 'Ace Of Base'
. ARTISTE (7733)
. . 'Adamo'

Lien vers le commentaire
Partager sur d’autres sites

Ok, merci, c'est sympa.

Par contre j'abandonne le projet, trop complexe. La partie xml étant une petite partie... Je me suis aperçu que le reste était tout aussi complexe et que l'ensemble des données était très mal présenté... Tant pis. En tout cas merci ;)

Lien vers le commentaire
Partager sur d’autres sites

C'est un des flux de Sevenline, ca.

Utilise le kit php/xml downloadable dans la section MP3, il y a un parser tout pret avec quelques commentaires dedans.

Il doit etre facilement adaptable pour le flux karaoké.

Lien vers le commentaire
Partager sur d’autres sites

C'est un des flux de Sevenline, ca.

Utilise le kit php/xml downloadable dans la section MP3, il y a un parser tout pret avec quelques commentaires dedans.

Il doit etre facilement adaptable pour le flux karaoké.

<{POST_SNAPBACK}>

Argh!! Je savais pas!! :gueule:

Bon, ok, je vais jetter un oeil là dessus, merci pour le tuyau. ;)

Lien vers le commentaire
Partager sur d’autres sites

Bon alors, je explique en détail :-)

En PHP4, il y a des fonctions qui permettent de parcourir un fichier XML et de récupérer les informations. En fait, ça n'est pas réellement un fichier XML mais un "flux" XML. En gros, ça signifie des données brutes qui peuvent venir de sources diverses comme : mémoire, fichier, réseau, etc.

En l'occurence dans mon exemple je fonctionne avec un fichier. Le petit truc qui a dû te perturber c'est le fait que j'utilise une variable paramètre nommée $adresse.

C'est parce que je veux pouvoir lire un fichier XML aussi bien sur ma machine que sur une machine distante. Donc $adresse peut être "/mondir/fichiers/lefichier.xml" ou &quot;http://www.monsite.com/lefichier.xml".

Ensuite, comment fonctionne précisément les fonctions PHP4 pour le XML ?

C'est très simple.

- tu crées un parser. C'est une sorte d'objet interne à PHP4 qui va s'occuper de lire le XML que tu lui donnes. Tu crées le parser avec xml_parser_create sans aucun paramètre. Il te retourne un identifiant dont tu te serviras plus tard pour dire "je travailler avec tel parser".

parser=xml_parser_create();

- tu indiques ensuite à ton parser quelles sont les fonctions qu'il devra appeler selon les données qu'il rencontre dans le flux XML. xml_set_element_handler quand il s'agit des élements (ListeArtiste, Artiste) et xml_set_character_data_handler pour les données qui sont encapsulées dans les éléments (Abba, Ace Of Base, etc.Particularité pour les éléments : tu indiques deux fonctions. Celle qui sera appelée lorsque le parser rencontre un élément qui s'ouvre (<Artiste>) et celle lorsqu'il rencontre un élément qui se ferme (</Artiste>).

xml_set_element_handler($parser,"xml_open","xml_close");
xml_set_character_data_handler($parser,"xml_data");

- Viens enfin le grand moment où tu vas "nourrir" le parser en lui fournissant un flux XML. C'est simplement une ouverture de fichier (local ou distant), puis on lit le fichier morceau par morceau (en l'occurence des morceaux de 4096 octets) et on donne chaque morceau au parser.

@$fp = _AT_fopen($adresse,"r");
if ($fp)
{
while ($data = fread($fp, 4096))
{
 if ( !@xml_parse($parser, $data, feof($fp)) )
 {
  $err=1;
  break;
 }
}
}

- A chaque fois que le parser rencontrera un élément qui s'ouvre il appelera la fonction qu'on lui a indiqué, en l'occurence xml_open, et lorsqu'il se ferme ça sera xml_close. Ces deux fonctions ont l'identifiant du parser, le nom de l'élément et les attributs en paramètres.

- A chaque fois que le parser rencontre des données il appelle notre fonction xml_data. Les paramètres reçus sont l'identifiant du parser et les données elle-même.

- Dernier point : le parser lit le XML comme il vient. Autrement dit, il va appeler les fonctions au fur et à mesure de ce qu'il trouve. Ca signifie que tu es certain qu'il ne pas commencer par te retourner des infos en plein milieu du flux XML. Ca se fait séquentiellement, ce qui est un avantage.

Vala en espérant que ce soit plus clair. N'hésite pas à consulter la doc de PHP sur www.php.net

Antoine

Lien vers le commentaire
Partager sur d’autres sites

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...