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

Composants VCL Delphi Discussion :

Comment retirer l'enveloppe SOAP d'un document XML avec TXMLDocument


Sujet :

Composants VCL Delphi

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 63
    Points : 44
    Points
    44
    Par défaut Comment retirer l'enveloppe SOAP d'un document XML avec TXMLDocument
    Je travaille actuellement sur une application sous XE7 et avec TXMLDocument. Je dois lire la valeur contenu dans un un nœud d'un document XML. Ce fichier XML est une réponse à une requête SOAP,
    lorsque je retire (manuellement) l'enveloppe SOAP (les balises <soap:Envelope> et <soap:Body> ) du document et teste un code comme celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ShowMessage(XMLDocument1.ChildNodes['Noeud1'].ChildNodes['Noeud2'].Text);
    la valeur que je recherche s'affiche mais si je garde l'enveloppe, j'ai une valeur null en retour bien que le nœud contienne une valeur texte non null.
    Voici à quoi ressemble ce document XML :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <soap:Body>
          <Corps de la réponse>
     
     
          </Corps de la réponse>
        </soap:Body>
    </soap:Envelope>
    Ma question est la suivante : Comment retirer l'enveloppe SOAP d'un document XML avec TXMLDocument ?
    Je vous remercie d'avance pour toute réponse ou aide.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Comment récupère tu le XML SOAP ?
    Si tu utilises un THTTPRIO et un TXMLData, ce dernier contient juste le contenu XML pour le Corps, ou alors c'est que je n'ai pas compris ta demande !
    Tu as bien déclaré dans ton client tes classes TRemotable (voir l'expert qui le fait automatiquement depuis le WSDL)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 63
    Points : 44
    Points
    44
    Par défaut
    J'utilise un THTTPRIO avec lequel j'envoie la requête et je reçois la réponse que j'enregistre sous forme de fichier XML, jusque là tout fonctionne parfaitement bien. Ma demande porte sur le fichier xml de réponse que je n'arrive pas à parser en utilisant TXMLDocument. En fait, quand je supprime les balises qui forme l'enveloppe et que j'essaie de récupérer la valeur d'un nœud ça marche mais si je teste le même code en gardant ces balises, j'ai NULL comme valeur de renvoie alors que le nœud contient bien une valeur texte.

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Tu n'as pas besoin de parser le contenu, les objets TRemotable le font déjà !
    Tu as bien importé le WSDL pour générer ton Wrapper ?
    L'expert est disponible dans un menu de Delphi (Fichier | Nouveau | WebService | Importateur WSDL)
    mais tu peux aussi WSDLImp en ligne de commande
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 63
    Points : 44
    Points
    44
    Par défaut
    Je pense qu'il n'y a pas besoin d'importer le WSDL, j'ai juste renseigné les paramètres URL et SOAPAction du composant THTTPRIO et j'ai reçu la réponse (sous forme de fichier XML) du service web.
    J'utilise ensuite un TXMLDocument pour accéder au valeur contenu dans les nœuds du fichier XML. Le problème est que la ligne de code (ci-dessous) me renvoie NULL si je garde l'enveloppe SOAP du fichier XML et me renvoie la bonne valeur lorsque je la retire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ShowMessage(XMLDocument1.ChildNodes['Noeud1'].ChildNodes['Noeud2'].Text);

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Si tu connais le nom de <Corps_de_la_réponse> et qu'il ne change JAMAIS !
    tu peux faire l'extraction très simplement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    XML := Copy(ChaineSOAP, Pos(ChaineSOAP, '<Corps_de_la_réponse>') + Length('<Corps_de_la_réponse>'), Pos(ChaineSOAP, '</Corps_de_la_réponse>') - (Pos(ChaineSOAP, '<Corps_de_la_réponse>') + Length(<Corps_de_la_réponse>)));
    Je te laisse corriger les +1 ou -1 pour avoir le bon nombre de caractères dans le 3eme paramètre

    Bon, je suppose que ce n'est pas aussi simple dans ton cas,
    sinon tu aurais trouvé cette solution évidente tout seul !



    As-tu essayé ceci en chargeant tout le document ?

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
       <soap:Body>
          <Noeud1>
            <Noeud2 Attr1="Même pas mal">Trop Facile</Noeud2> 
          </Noeud1>
        </soap:Body>
    </soap:Envelope>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ShowMessage(XMLDocument1.ChildNodes['soap:Envelope'].ChildNodes['soap:Body'].ChildNodes[0].ChildNodes[0].Text);
    Mais cela aussi c'est tellement évident que cela doit être plus compliqué


    Personnellement, je trouve que la syntaxe ChildNodes[...].ChildNodes[...].ChildNodes[...].ChildNodes[...].ChildNodes[...]... est horrible !
    XPATH c'est chiant genre /*[local-name()="Envelope"]/*[local-name()="Body"]/*[local-name()="Noeud1"]/*[local-name()="Noeud2"
    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
    var
      DomNodeSelectIntf: IDomNodeSelect;
      DomNode: IDOMNode;
      DomNodeEx: IDOMNodeEx;
    begin
      XMLDocument1.XML := Memo1.Lines;
      XMLDocument1.Active := True;
     
      // - Via IDomNodeSelect.selectNode
      if Assigned(XMLDocument1.DOMDocument) and Supports(XMLDocument1.DOMDocument, IDomNodeSelect, DomNodeSelectIntf) then
      begin
          DomNode := DomNodeSelectIntf.selectNode('/*[local-name()="Envelope"]/*[local-name()="Body"]/*[local-name()="Noeud1"]/*[local-name()="Noeud2"]');
        if Supports(DomNode, IDOMNodeEx, DomNodeEx) then
        begin
          ShowMessage('IDomNodeSelect.selectNode'
            + sLineBreak + 'Node : ' + DomNode.nodeName
            + sLineBreak + 'Text : ' + DomNodeEx.Text
            + sLineBreak + 'Attr1 : ' + DomNode.attributes.getNamedItem('Attr1').nodeValue);
        end
        else
        begin
          ShowMessage('IDomNodeSelect.selectNode'
            + sLineBreak + 'Node : ' + DomNode.nodeName
            + sLineBreak + 'Attr1 : ' + DomNode.attributes.getNamedItem('Attr1').nodeValue);
        end;
      end;
    end;
    XPATH c'est standard mais c'est pas très facile à lire
    Donc je me suis fait ma routine pour la lisibilité
    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
     
    function FindNodeEx(ANode: IXMLNode; const APath: array of string; APathIndex: Integer = 0): IXMLNode;
    var
      I: Integer;
    begin
      if APathIndex < High(APath) then
      begin
        for I := 0 to ANode.ChildNodes.Count - 1 do
        begin
          if SameText(ANode.ChildNodes[I].NodeName, APath[APathIndex]) then
            Exit(FindNodeEx(ANode.ChildNodes[I], APath, APathIndex + 1));
        end;
      end
      else if APathIndex = High(APath) then
      begin
        for I := 0 to ANode.ChildNodes.Count - 1 do
        begin
          if SameText(ANode.ChildNodes[I].NodeName, APath[APathIndex]) then
            Exit(ANode.ChildNodes[I]);
        end;
      end
      else if SameText(ANode.NodeName, APath[APathIndex]) then
        Exit(ANode);
     
      Result := nil;
    end;
    cela permet un appel très lisible, Memo1 contient le XML ci-dessus

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var
      XMLNode: IXMLNode;
    begin
      XMLDocument1.XML := Memo1.Lines;
      XMLDocument1.Active := True;
     
      // - Via FindNodeEx
      XMLNode := FindNodeEx(XMLDocument1.Node, ['soap:Envelope', 'soap:Body', 'Noeud1', 'Noeud2']);
      ShowMessage('FindNodeEx'
            + sLineBreak + 'Node : ' + XMLNode.NodeName
        + sLineBreak + 'Text : ' + XMLNode.Text
        + sLineBreak + 'Attr1 : ' + XMLNode.Attributes['Attr1']);
    end;


    A l'époque de D6 et D7, j'ai intégré plus de 5 WebService en tant que client (j'en étais l'auteur en PHP4-NuSOAP pour certains) , j'ai toujours utilisé le WSDL !
    Pourquoi ne pas utiliser ce qui existe ?



    Une contrainte imposée dans votre devoir pour l'école de manipuler le XML à la main ?



    Une seule fois, j'ai du le faire via un TXMLData issu d'un WS en Microsoft BizTalk, le leader peut toujours faire du non-standard que cela en devient un standard quelques années plus tard
    Mais même dans ce cas, je suis passé par le WSDL pour me créer un objet TRemotable qui s'occupe d'extraire le simple XML à partir du message SOAP
    Plus fiable que le Copy si ton contenu évolue !

    As-tu essayer d'utiliser le TXMLData pour extraire le XML dans le SOAP ?
    Au final, le TXMLData ne contiendra QUE le XML de données dans sa propriété TXMLData.XMLNode ce qui résoud ton problème de l'enveloppe SOAP
    Et ce qui est merveilleux lorsque l'on utilise ce qui existe, c'est que XMLNode c'est un IXMLNode qui propose la propriété TXMLData.XMLNode.ChildNodes


    Tu as une version XE7, TXMLData est inclus ! Profites-en !
    En Delphi 7, il y a plus de 10 ans, cela n'étais pas le cas, il a fallu que je cherche

    Au final tu pourrais écrire en utilisant le WSDL et le générateur de code source

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ShowMessage((THTTPRIO as IMonService).GetXML().XMLData.XMLNode.ChildNodes['Noeud1'].ChildNodes['Noeud2'].Text);
    Faut-il écouter les conseils des développeurs expérimentés lorsque l'on est un étudiant !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. comment parser un document xml avec gwt?
    Par zemzoum89 dans le forum GWT et Vaadin
    Réponses: 3
    Dernier message: 01/12/2010, 15h05
  2. Réponses: 1
    Dernier message: 13/04/2010, 08h48
  3. [XSLT]Comment copier un document xml avec xslt.
    Par maa dans le forum XSL/XSLT/XPATH
    Réponses: 9
    Dernier message: 07/05/2009, 14h02
  4. Réponses: 5
    Dernier message: 03/11/2006, 18h38
  5. comment associer les couleur a un document xml avec xslt
    Par moh_yougo dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 30/01/2006, 16h08

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