Parseur XML (fichier récupéré à partir d'un web service)

Parseur XML (fichier récupéré à partir d'un web service) - PHP - Programmation

Marsh Posté le 01-06-2010 à 15:44:44    

Pour commencer bonjour à ceux qui auront le courage de chercher une solution a mon problème.
 
Je me présente, je suis en BTS 1er année en info, et actuellement en stage.  
 
Mon problème vient que je suis censé parser un document xml que j'ai au préalablement récupéré via un web service. J'ai réussi la première étape (du moins je crois) mais quand je veux parser mon fichier, il me dit que mon fichier est vide.
 
Tout d'abord voici le code de ma requête au webservice.

Code :
  1. try
  2. {
  3.      $client = new SoapClient('https://oasis.emn.fr/opdotnet/webservices/Formation.asmx?WSDL');
  4.      echo '<hr /><br />';
  5.      echo  '<br /><br />
  6.         <b>Invocation de getOffre() :</b>';
  7.      echo '<br />';
  8. $params = array(
  9.   'guid'=> '',
  10.       'idCommunaute'=> 2,
  11.       'strTypeReferentiel'=>'',
  12.       'strVisibilite'=>'',
  13.       'sIdVue'=>'423',
  14.       'sIdCatalogue'=>'',
  15.       'sIdDomaine'=>'',
  16.       'strListeTypeReferentielsCibles'=>'',
  17.       'sChampDyn'=>'',
  18.       'sChampFact'=>'',
  19.       'sDateModificationDebut'=>'',
  20.       'sDateModificationFin'=>'',
  21.       'sChampDynLiens'=>'',
  22.       'EtatsProcess'=>'',
  23. );
  24.     try {
  25. $ret=$client->getOffre($params);
  26. $xml = simplexml_load_string($ret->getOffreResult, 'SimpleXMLElement', LIBXML_NOCDATA);
  27. }
  28. catch(Exception $e) {
  29.   return false;
  30. };
  31.    
  32. }
  33. catch(Exception $e)
  34. {
  35.      echo '<br /><hr />';
  36.      echo "<b>Exception:</b> " . $e;
  37. }
  38. $file = fopen('getOffre.xml','w'); // j'enregistre mon résultat dans un fichier 'getOffre.xml'
  39. fputs($file, $xml);
  40. fclose($file);


 
et une partie du résultat quand je l'affiche "brut" (sans parseur)

Code :
  1. SimpleXMLElement Object ( [vues] => SimpleXMLElement Object ( [vue] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 423 ) [nom] => Formations Doctorale [champs] => SimpleXMLElement Object ( [champ] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 757 [typedonnee] => NUM ) [code] => RES_CDE_ANA [nom] => Centre analytique [valeur] => SimpleXMLElement Object ( ) [valeurAffichee] => SimpleXMLElement Object ( ) [idvaleur] => SimpleXMLElement Object ( ) ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 752 [typedonnee] => TXT ) [code] => FRT_COD_PRO [nom] => Format de codification des process [valeur] => SimpleXMLElement Object ( ) [valeurAffichee] => SimpleXMLElement Object ( ) [idvaleur] => SimpleXMLElement Object ( ) ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 754 [typedonnee] => ORG ) [code] => ORG_FOR [nom] => Site [valeur] => SimpleXMLElement Object ( ) [valeurAffichee] => SimpleXMLElement Object ( ) [idvaleur] => SimpleXMLElement Object ( ) ) [3] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 762 [typedonnee] => USR ) [code] => RES_USR_CON [nom] => Interlocuteur [valeur] => SimpleXMLElement Object ( ) [valeurAffichee] => SimpleXMLElement Object ( ) [idvaleur] => SimpleXMLElement Object ( ) ) [4] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 1154 [typedonnee] => SEL ) [code] => FPC_VUE_SESSION [nom] => Vue des données de base process [valeur] => SimpleXMLElement Object ( ) [valeurAffichee] => SimpleXMLElement Object ( ) [idvaleur] => SimpleXMLElement Object ( ) ) ) ) [catalogues] => SimpleXMLElement Object ( [catalogue] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 166 [referentiel] => FPC ) [nom] => Doctorants [domaine] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 166 [referentiel] => FPC ) [nom] => Doctorants [description] => SimpleXMLElement Object ( ) [domaine] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 167 [referentiel] => FPC ) [nom] => 1 - COMMUNICATION ET MANAGEMENT [description] => SimpleXMLElement Object ( ) [element] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2288 [referentiel] => FPC ) ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2289 [referentiel] => FPC ) ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2290 [referentiel] => FPC ) ) [3] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2338 [referentiel] => FPC ) ) ) ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 168 [referentiel] => FPC ) [nom] => 2 - STRATEGIE ENTREPRISE ET MANAGEMENT DE PROJET [description] => SimpleXMLElement Object ( ) [element] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2292 [referentiel] => FPC ) ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2293 [referentiel] => FPC ) ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2294 [referentiel] => FPC ) ) ) ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 169 [referentiel] => FPC ) [nom] => 3 - INNOVATION ET VALORISATION [description] => SimpleXMLElement Object ( ) [element] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2341 [referentiel] => FPC ) ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2342 [referentiel] => FPC ) ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2298 [referentiel] => FPC ) ) [3] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2295 [referentiel] => FPC ) ) [4] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2296 [referentiel] => FPC ) ) [5] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2297 [referentiel] => FPC ) ) ) ) [3] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 170 [referentiel] => FPC ) [nom] => 5 - OUVERTURE SCIENTIFIQUE ET ENJEUX DE LA SOCIETE [description] => SimpleXMLElement Object ( ) [element] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2305 [referentiel] => FPC ) ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2302 [referentiel] => FPC ) ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2301 [referentiel] => FPC ) ) [3] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2339 [referentiel] => FPC ) ) [4] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2340 [referentiel] => FPC ) ) [5] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2304 [referentiel] => FPC ) ) ) ) [4] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 171 [referentiel] => FPC ) [nom] => 6 - PROJET PROFESSIONNEL ET INSERTION [description] => SimpleXMLElement Object ( ) [element] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2310 [referentiel] => FPC ) ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2307 [referentiel] => FPC ) ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2308 [referentiel] => FPC ) ) [3] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 2309 [referentiel] => FPC ) ) ) ) [5] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 172 [referentiel] => FPC ) [nom] => 4 -


 
Mon maître de stage (qui n'a jamais utilisé de parseur) ma gentiment donné la tâche d'en utiliser un pour un résultat plus lisible.
 
Voice un parseur basique qui est juste censé afficher le contenu des balises;
 

Code :
  1. $fichier = "getOffre.xml";
  2.     // Ma propre fonction de traitement du texte
  3.     // qui est appelée par le "parseur"
  4.     function fonctionTexte($parseur, $texte)
  5.     {
  6.         // Dans l'immédiat nous nous contentons d'afficher
  7.         // le texte brut accompagné d'un simple retour à la ligne
  8.         echo $texte."<br/>";
  9.     }
  10.     // Création du parseur XML
  11.     $parseurXML = xml_parser_create();
  12.     // Je précise le nom de la fonction a appeler
  13.     // lorsque du texte est rencontré
  14.     xml_set_character_data_handler($parseurXML, "fonctionTexte" );
  15.     // Ouverture du fichier
  16.     $fp = fopen($fichier, "r" );
  17.     if (!$fp) die("Impossible d'ouvrir le fichier XML" );
  18.     // Lecture ligne par ligne
  19.     while ( $ligneXML = fgets($fp, 1024)) {
  20.         // Analyse de la ligne
  21.         // REM: feof($fp) retourne TRUE s'il s'agit de la dernière
  22.         //      ligne du fichier.
  23.      
  24.         xml_parse($parseurXML, $ligneXML, feof($fp)) or
  25.             die("Erreur XML" );
  26.     }
  27.    
  28.     xml_parser_free($parseurXML);
  29.     fclose($fp);


 
Or celui-ci ne retourne rien. Et avec des parseurs un peu plus "évolué". J'ai un message d'érreur comme quoi la chaîne que je rentre dans le parseur est vide.  
 
Autre version pour récupérer le xml :

Code :
  1. /*$file = new DomDocument(); // Instanciation de la classe DomDocument : création d'un nouvel objet.
  2. $resultat_html = ''; // Initialisation de la chaîne qui contient le résultat.
  3. $file->loadXML($xml);
  4. $file->save('getOffre.xml');


 
Donc mon erreur vient bien de la récupération du xml mais je ne vois pas d'ou.
 
Si quelqu'un peut m'expliquer à quel niveau je m'y prend mal je lui en serait reconnaissant.
Merci d'avance.


Message édité par Azax le 02-06-2010 à 12:55:04
Reply

Marsh Posté le 01-06-2010 à 15:44:44   

Reply

Marsh Posté le 01-06-2010 à 17:46:07    

SimpleXML EST un parseur XML.
Pas besoin de sauver la réponse sur le disque pour l'interpréter.
 
T'as juste à utiliser ton objet SimpleXML.
Du genre $simplexml->maBalise['monAttribut']. Ni plus ni moins. Faut juste caster dans le type de base voulu, car ça renvoi toujours un objet SimpleXMLElement.
 
Si tu veut le contenu d'un SimpleXMLElement en chaine : $maChaine = $simplexml->saveXML();


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 01-06-2010 à 19:50:18    

tu mets la balise [ code] pas la balise spoiler merci


---------------
Blablaté par Harko
Reply

Marsh Posté le 02-06-2010 à 13:24:20    

Merci de ces précisions, mais en faite j'ai trouvé une autre solution ce matin.*
 
j'utilise un getLastReponse qui me renvoi bien un fichier xml ce coup ci.
 

Code :
  1. $ret=$client->getOffre($params);
  2. //$xml = simplexml_load_string($ret->getOffreResult, 'SimpleXMLElement', LIBXML_NOCDATA);
  3. //echo "Response:\n"  . $client ->  __getLastResponse () . "\n" ;  
  4. $rep = $client ->  __getLastResponse () . "\n" ;


La mon fichier xml contient bien le code souhaité.
 
Maintenant dans ce code, je dois récupérer la valeur de certaines balises, pas toute.
Dois-je utiliser la méthode DOM ? j'ai consulté quelques tutos a ce sujet. Si oui pouvez-vous me donnez un exemple s'il vous plait? car je n'y arrive pas avec ceux des tutos.  
Par exemple dans le code ci-dessous je veux juste récupérer les valeurs en rouges.

Code :
  1. <offre>
  2. <vues>
  3.   <vue id="423">
  4.    <nom>Formations Doctorale</nom>
  5.     <champs>
  6. +
  7.      <champ id="757" typedonnee="NUM">
  8.        <code>RES_CDE_ANA</code>
  9.        <nom>Centre analytique</nom>
  10.        <valeur></valeur>
  11.        <valeurAffichee></valeurAffichee>
  12.        <idvaleur></idvaleur>
  13.      </champ>
  14. +
  15.    
  16.    <catalogues>
  17.     <catalogue id="166" referentiel="FPC">
  18.         <nom>Doctorants</nom>
  19.        <domaine id="166" referentiel="FPC">
  20.          <nom>Doctorants</nom>
  21.          <description></description>
  22.          <domaine id="167" referentiel="FPC">
  23.        <nom>1 - COMMUNICATION ET MANAGEMENT</nom>
  24.           <description></description>
  25.           <element id="2288" referentiel="FPC"/>
  26.           <element id="2289" referentiel="FPC"/>
  27.           <element id="2290" referentiel="FPC"/>
  28.           <element id="2338" referentiel="FPC"/>
  29.         </domaine>
  30.        <domaine id="168" referentiel="FPC">
  31.           <nom>2 - STRATEGIE ENTREPRISE ET MANAGEMENT DE PROJET</nom>
  32.           <description></description>
  33.           <element id="2292" referentiel="FPC"/>
  34.           <element id="2293" referentiel="FPC"/>
  35.           <element id="2294" referentiel="FPC"/>
  36.        </domaine>
  37.       <domaine id="169" referentiel="FPC">
  38.         <nom>3 - INNOVATION ET VALORISATION</nom>
  39.         <description></description>
  40.         <element id="2341" referentiel="FPC"/>
  41.         <element id="2342" referentiel="FPC"/>
  42.         <element id="2298" referentiel="FPC"/>
  43.         <element id="2295" referentiel="FPC"/>
  44.         <element id="2296" referentiel="FPC"/>
  45.         <element id="2297" referentiel="FPC"/>
  46.       </domaine>


 
Si vous pouvez m'expliquer la méthode a suivre, merci d'avance.

Reply

Marsh Posté le 02-06-2010 à 13:49:04    

Deux possibilité, soit c'est du SOAP "classique", et donc tu fait :
 

Code :
  1. $result = $soapClient->getOffre($params);
  2. $monInfo = result->offre->vues->vue->catalogues->catalogue->nom;


 
C'est directement mappé en "Object". Alors c'est chiant pour les attributs par contre, mais tu peut faire que le SoapClient désérialize dans un type PHP perso qui ferait ça mieux.
 
Si ton getOffre renvoi du XML, là c'est de ce style :

Code :
  1. $result = $soapClient->getOffre($params);
  2. $simplexml = new SimpleXMLElement($result);
  3. $monInfo = simple->offre->vues->vue->catalogues->catalogue->nom;


 
Et SimpleXMLElement permet de faire des foreach pour iterer sur les balises de même nom/même niveau. (exemple: foreach ($simplexml->offres->offre as $offre) {}).


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 02-06-2010 à 14:33:18    

Je peux utiliser le SimpleXMLElement et le DOM dans le même scripts?
 
Parce que encore le DOM j'arrive un peu à comprendre mais pour le simpleXML j'ai du mal.
 
   

Code :
  1. $simplexml = new SimpleXMLElement($rep);
  2.  
  3.      $monInfo = $simplexml->offre->vues->vue->catalogues->catalogue->nom;
  4.  echo $monInfo;


 
$rep étant la réponse xml.
Le echo ne me montre rien.
De plus je ne peux pas récupérer les attributs avec cette méthode.
EDIT :
 

Code :
  1. $dom = new DomDocument();
  2.    $dom->load("/tmp/getOffreXml.xml" );
  3. //   $racine = $dom->documentElement;
  4. //  echo $racine->nodeName."\n";
  5.  
  6.   $listeId = $dom->getElementsByTagName('element');
  7.   foreach($listeId as $element)
  8.   {
  9.     echo $element->nodeValue;
  10.     if ($element->hasAttribute("id" )) {
  11.         echo  " - " . $element->getAttribute("id" )."\n";
  12.     }
  13.   }


 
Voila je récupère toute mes id.
Maintenant il faut que je les stocks dans une variable pour les réutilisés pour une autre requête soap getModule qui m'affichera donc le contenu de mes uv (qui correspondent au id).
 
En gros je veux que mon résultat final soit un tableau, avec mes nom de thématique, avec pour chaque thématique ses différentes uv. Un fois cela fait en clickant sur l'uv j'aurais la fiche complète de celle-ci.
 
Merci encore de ta réponse Mei.
Si j'ai encore des problèmes avec le Dom je re-posterais sur ce même sujet.


Message édité par Azax le 02-06-2010 à 14:45:53
Reply

Marsh Posté le 02-06-2010 à 14:42:22    

Si les attributs sont utilisables comme des tableaux. Genre $a['href'] pour <a href="" />...
 
SimpleXML est une sur-couche de DOMDocument. Après c'est comme tu le sens, mais SimpleXMLElement reste plus concis et plus lisible.
 
(du echo de XML, bien sur, faut ouvrir la source pour le voir, sinon le navigateur tant à vouloir l'interpréter.)


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |
Reply

Marsh Posté le 02-06-2010 à 16:24:13    

Voila j'ai un peu avancé, mais je suis bloqué.
 

Code :
  1. $dom = new DomDocument;
  2. $dom->preserveWhiteSpace = FALSE;
  3. $dom->load('/tmp/getOffreXml.xml');
  4.      
  5.      $params2 = $dom->getElementsByTagName('domaine'); //digg categories with in Section
  6.      $i=0; // values is used to iterate categories  
  7.         foreach ($params2 as $p) {
  8.            echo "&nbsp;&nbsp;- Thematique Name :-> ".$params2->item($i)->nodeValue."<br>"; //get Category attributes
  9.            $params3 = $params2->item($i)->getElementsByTagName('element'); //dig Arti into Categories
  10.            $j=0;//values used to interate Arti
  11.                 foreach ($params3 as $p2)
  12.                  {
  13.                     echo "&nbsp;&nbsp;&nbsp;- Element Attribute id : ".$params3->item($j)->getAttribute('id').""; //get arti atributes
  14.                               $j++; 
  15.                   }           
  16.          $i++;
  17.       }


 
Avec ce code j'affiche mes thématiques avec leur uv (les id).
Sauf que j'ai le résultat suivant
 

Code :
  1. Invocation de getOffre() :
  2.   - Thematique Name :-> Doctorants1 - COMMUNICATION ET MANAGEMENT2 - STRATEGIE ENTREPRISE ET MANAGEMENT DE PROJET3 - INNOVATION ET VALORISATION5 - OUVERTURE SCIENTIFIQUE ET ENJEUX DE LA SOCIETE6 - PROJET PROFESSIONNEL ET INSERTION4 - LANGUES
  3.    - Element Attribute id : 2288   - Element Attribute id : 2289   - Element Attribute id : 2290   - Element Attribute id : 2338   - Element Attribute id : 2292   - Element Attribute id : 2293   - Element Attribute id : 2294   - Element Attribute id : 2341   - Element Attribute id : 2342   - Element Attribute id : 2298   - Element Attribute id : 2295   - Element Attribute id : 2296   - Element Attribute id : 2297   - Element Attribute id : 2305   - Element Attribute id : 2302   - Element Attribute id : 2301   - Element Attribute id : 2339   - Element Attribute id : 2340   - Element Attribute id : 2304   - Element Attribute id : 2310   - Element Attribute id : 2307   - Element Attribute id : 2308   - Element Attribute id : 2309   - Element Attribute id : 2299   - Element Attribute id : 2300[BALISE]- Thematique Name :-> 1 - COMMUNICATION ET MANAGEMENT
  4.    - Element Attribute id : 2288   - Element Attribute id : 2289   - Element Attribute id : 2290   - Element Attribute id : 2338  - Thematique Name :-> 2 - STRATEGIE ENTREPRISE ET MANAGEMENT DE PROJET
  5.    - Element Attribute id : 2292   - Element Attribute id : 2293   - Element Attribute id : 2294  - Thematique Name :-> 3 - INNOVATION ET VALORISATION
  6.    - Element Attribute id : 2341   - Element Attribute id : 2342   - Element Attribute id : 2298   - Element Attribute id : 2295   - Element Attribute id : 2296   - Element Attribute id : 2297  - Thematique Name :-> 5 - OUVERTURE SCIENTIFIQUE ET ENJEUX DE LA SOCIETE
  7.    - Element Attribute id : 2305   - Element Attribute id : 2302   - Element Attribute id : 2301   - Element Attribute id : 2339   - Element Attribute id : 2340   - Element Attribute id : 2304  - Thematique Name :-> 6 - PROJET PROFESSIONNEL ET INSERTION
  8.    - Element Attribute id : 2310   - Element Attribute id : 2307   - Element Attribute id : 2308   - Element Attribute id : 2309  - Thematique Name :-> 4 - LANGUES
  9.    - Element Attribute id : 2299   - Element Attribute id : 2300 [BALISE]


 
Et la partie qui m'intéresse est celle entre les balises rouge, de plus j'aimerais bien la "ranger" de façon à ce qu'elle soit plus claire. Faut-il une DTD ou quelques choses dans le genre?  
J'aimerais que ca ressemble plus a ca :
- Thématique Name :-> le nom de la thématique
            - Element id : 1992
            -  Element id : 1993
            -  Element id : 1994
            -  Element id : 1995
Thématique Name :-> le nom de la thématique
            -  Element id : 1996
           - Element id : 1997


Message édité par Azax le 02-06-2010 à 16:27:06
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed