IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

comment trouver la valeur d'un champ d'une chaine de caractère en XML qui est mal structurée


Sujet :

Langage PHP

  1. #1
    Membre habitué
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Points : 140
    Points
    140
    Par défaut comment trouver la valeur d'un champ d'une chaine de caractère en XML qui est mal structurée
    Bonjour,
    je reçois par un web service

    soit
    <?xml version="1.0" encoding="utf-8"?><transaction success="false">
    <!--Here is the information from webService-->
    <success>false</success>
    soit
    <?xml version="1.0" encoding="utf-8"?><transaction success="true">
    <!--Here is the information from webService-->
    <success>true</success>

    Il faut que je trouve la valeur "false" ou "true" dans <success>
    Ce que je fais :
    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
    /*
    $info = curl_getinfo($curl);
    $recu = $response;																
    */								
     
    $recuTest = '<?xml version="1.0" encoding="utf-8"?><transaction success="false">
    <!--Here is the information from webService-->
    <isSuccess>false</isSuccess>';
    $docDom = new DOMDocument();
    $docDom->loadXML($recuTest);                 /////////// on line 11
     
    echo $docDom->saveXML();
     
     
    $trouver =  $docDom->getElementsByTagName('isSuccess');
     
     
     
     
    echo '---<br>';
     
    foreach ($trouver as $val) {
        echo $val->nodeValue, PHP_EOL;
     
    		if (($val->nodeValue) == 'false')
    		{
    			echo "<p>faux</p>";
    			//donc je peux traiter pour cette condition : alert par email
    		}
    		else
    		{
    			echo "<p>vrai</p>";
    			//donc je peux traiter pour cette condition : tout va bien
    		}
     
    	}
    et voici le message d'erreur :
    Warning: DOMDocument::loadXML(): Premature end of data in tag transaction line 1 in Entity, line: 3 in E:\sites\rep_ws.php on line 11
    Par contre lorsque je supprime 1re ligne dans ma variable "$recuTest" tout marche bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $recuTest = '
    <!--Here is the information from webService-->
    <isSuccess>false</isSuccess>';
    voici ce que je vois sans erreur :
    <?xml version="1.0"?>
    <!--Here is the information from webService-->
    <isSuccess>false</isSuccess>
    ---<br>false
    <p>faux</p>
    Que je dois faire ?
    Comment je peux trouver la valeur de <success> lorsque je reçois les informations comme cela :
    '<?xml version="1.0" encoding="utf-8"?><transaction success="false">
    <!--Here is the information from webService-->
    <isSuccess>false</isSuccess>
    Merci

  2. #2
    Membre habitué
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Points : 140
    Points
    140
    Par défaut
    J'ai une solution, mais pas très belle : par la fonction ""
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $a_supprimer = '<?xml version="1.0" encoding="utf-8"?><transaction success="false">';
    $remplacer_par = '';
     
    $recuTest = str_replace($a_supprimer, $remplacer_par, $recuTest);
    Mais, un jour, si le web service change quelque chose (un chiffre ou caractère) dans la variable "$recuTest", ma solution ne marchera plus puisque la variable, "$a_supprimer ", ne contiendra plus de bonne valeur

    Est-ce que vous avez une autre idée ?

    Merci

    Voici le code actuel :
    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
    /*
    $info = curl_getinfo($curl);
    $recu = $response;																
    */								
     
    $recuTest = '<?xml version="1.0" encoding="utf-8"?><transaction success="false">
    <!--Here is the information from webService-->
    <isSuccess>false</isSuccess>';
     
    $a_supprimer = '<?xml version="1.0" encoding="utf-8"?><transaction success="false">';
    $remplacer_par = '';
     
    $recuTest = str_replace($a_supprimer, $remplacer_par, $recuTest);
     
    $docDom = new DOMDocument();
    $docDom->loadXML($recuTest);
     
    echo $docDom->saveXML();
     
     
    $trouver =  $docDom->getElementsByTagName('isSuccess');
     
     
     
     
    echo '---<br>';
     
    foreach ($trouver as $val) {
        echo $val->nodeValue, PHP_EOL;
     
    		if (($val->nodeValue) == 'false')
    		{
    			echo "<p>faux</p>";
    			//donc je peux traiter pour cette condition : alert par email
    		}
    		else
    		{
    			echo "<p>vrai</p>";
    			//donc je peux traiter pour cette condition : tout va bien
    		}
     
    	}

  3. #3
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    A partir du moment ou le XML est mal formaté, je ne sais pas si cela vaut la peine de s’embêter a vouloir le lire comme du XML (surtout vu sa taille).

  4. #4
    Membre habitué
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Points : 140
    Points
    140
    Par défaut
    Bonjour sabotage,
    Ok, je ne suis pas obligé de lire comme du XML comme tu dis.

    Alors à quelle façon puis-je lire pour trouver si "success" est "false" ou "true" ?

  5. #5
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    La manière la plus simple est de chercher "<isSuccess>true</isSuccess>" dans le contenu.

  6. #6
    Membre habitué
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Points : 140
    Points
    140
    Par défaut
    Merci sabotage,

    Citation Envoyé par sabotage Voir le message
    La manière la plus simple est de chercher "<isSuccess>true</isSuccess>" dans le contenu.
    Est-ce que je les cherche avec la fonction : "strpos" ?

    Voici ce que je fais :
    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
    $recuTest = '<?xml version="1.0" encoding="utf-8"?><transaction success="true">
    <!--Here is the information from webService-->
    <isSuccess>true</isSuccess>';
     
     
     
    $trouver   = '<transaction success="true">';
    $result = strpos($recuTest, $trouver);
     
    if ($result == true) 
    	{
    		echo "<p>c'est vrai</p>";
    				//donc je peux traiter pour cette condition : tout va bien
    	} 
    else
    	{
    		echo "<p>c'est faux</p>";
    				//donc je peux traiter pour cette condition : alert par email
    	}
     
     
     
    $trouverXml   = '<isSuccess>true</isSuccess>';
    $resultXml = strpos($recuTest, $trouverXml);
     
    if ($resultXml == true) 
    	{
    		echo "<p>2e : c'est vrai</p>";
    				//donc je peux traiter pour cette condition : tout va bien
    	} 
    else
    	{
    		echo "<p>2e c'est faux</p>";
    				//donc je peux traiter pour cette condition : alert par email
    	}
    Est-ce que c'est bon ou bien il y a une autre meilleure solution que la mienne ?

    Merci

  7. #7
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 912
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 912
    Points : 6 705
    Points
    6 705
    Par défaut
    Sinon tu peux toujours profiter des avantages de la structure en chargeant ton contenu comme du HTML.

    Ainsi DOMDocument sera plus coulant avec les erreurs de formatage et refermera les tags restés ouverts. Ça évite une manipulation directe de la chaîne plus hasardeuse:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    libxml_use_internal_errors(true); // évite l'affichage des warnings
     
    $dom = new DOMDocument;
    $dom->loadHTML($xml);
     
    $nodeList = $dom->getElementsByTagName('issuccess');
     
    if ($nodeList->length) {
        echo $nodeList->item(0)->nodeValue;
    }

  8. #8
    Membre habitué
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Points : 140
    Points
    140
    Par défaut
    Super Cool, CosmoKnacki, merci.

    Par contre, je dois désactiver le rapport d'erreur libxml avec ton code, sinon il y a des alertes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    libxml_use_internal_errors(true); // évite l'affichage des warnings  // alerts parce qu'il y a des erreurs dans la réponse en xml
    • Warning: DOMDocument::loadHTML(): Tag transaction invalid in Entity, , line: 1 in
    • Warning:

    DOMDocument::loadHTML(): Tag issuccess invalid in Entity, line: 3 in
    Puisque ces alertes ne viennent pas de ton code, tout va bien :
    C'est à cause de $recuTest (qui contient un xml mal structuré).
    Donc tout va bien et ce que tu me proposes est une solution solide!

    Un grand merci CosmoKnacki.


    Du coup, je ne sais plus laquelle est le meilleur solution pour moi :

    Celle de "strpos" ou celle du " contenu comme du HTML" ?

    Merci encore

  9. #9
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 912
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 912
    Points : 6 705
    Points
    6 705
    Par défaut
    Il n'y a pas de solution idéale, mais juste celle qui correspond le mieux à ton besoin.

    Si tu es sûre de ton fait strpos peut très bien convenir. Par contre si les balises que tu cherches peuvent avoir ou pas un ou plusieurs attributs ou si la casse peut varier, dans ce cas DOMDocument sera un meilleur choix.(Cela-dit, pour la casse, il existe stripos)

    Mais attention car dans un cas extrême où le XML est mal formé; si le chargement en HTML avec DOMDocument est capable de corriger certaines erreurs, il ne peut pas faire face à tout, et tu n'as pas le contrôle sur la manière dont ces erreurs sont corrigées, c'est automatique. Dans ce cas, ta seule option est de te tourner vers des manipulations de chaîne pour corriger l'erreur de la manière que tu souhaites.

  10. #10
    Membre habitué
    Homme Profil pro
    Aprenti
    Inscrit en
    Mai 2015
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Aprenti

    Informations forums :
    Inscription : Mai 2015
    Messages : 199
    Points : 140
    Points
    140
    Par défaut
    Merci CosmoKnacki,

    C'est cool...

    Bonne journée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 05/03/2012, 20h35
  2. Comment récupérer la valeur d'un champ d'une fenêtre modale
    Par lodan dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 04/09/2011, 19h02
  3. Extraire des champs dans une chaine de caractère
    Par clemuche dans le forum Requêtes
    Réponses: 1
    Dernier message: 26/02/2009, 00h24
  4. Réponses: 2
    Dernier message: 28/03/2008, 19h24
  5. Réponses: 4
    Dernier message: 18/07/2007, 15h10

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