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

XML/XSL et SOAP Discussion :

[SOAPUI] Groovy récupérer items multiples


Sujet :

XML/XSL et SOAP

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Février 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut [SOAPUI] Groovy récupérer items multiples
    Bonjour,

    J'utilise SoapUi 5.4.0 et en cherchant j'ai essayé de créer un script Groovy mais je suis bloqué.

    Je souhaite récupérer tous les objets de ma réponse et les stocker dans un fichier.

    Voici la réponse sur laquelle je me base:
    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
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
       <S:Body>
          <ps:MessagePullReply xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
             <requestReceptionTime>2018-05-15 17:59:50</requestReceptionTime>
             <requestId>9126093</requestId>
             <sendTime>2018-05-15 17:59:50</sendTime>
             <status>OK</status>
             <data>
                <marshalledMessages>
                   <item><![CDATA[<ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>197e9f71-a43f-42e9-bb9f-b89f980a916d</uuid><timestamp>2018-05-15 17:54:54 094</timestamp><subscriptionUuid>412134bd-9c3e-45c7-bded-f1f438bf057e</subscriptionUuid><parentMessageId>20180515175451E395948V1</parentMessageId></ps:DataMessage>]]></item>
                   <item><![CDATA[<ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>7018e927-38ba-4c86-950f-fcec9b44edb9</uuid><timestamp>2018-05-15 17:54:55 092</timestamp><subscriptionUuid>1ed22a1e-0983-4cc1-b40d-631cf52dda3f</subscriptionUuid><parentMessageId>20180515175454E385799V93</parentMessageId></ps:DataMessage>]]></item>
                   <item><![CDATA[<ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>e9d7ed1c-ecef-48d1-8cd8-13244ce58d46</uuid><timestamp>2018-05-15 17:54:59 788</timestamp><subscriptionUuid>412134bd-9c3e-45c7-bded-f1f438bf057e</subscriptionUuid><parentMessageId>20180515175458E390413V20</parentMessageId></ps:DataMessage>]]></item>
                   <item><![CDATA[<ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>f41f0490-3b5d-421d-bf13-fbc7b5c27be3</uuid><timestamp>2018-05-15 17:55:00 162</timestamp><subscriptionUuid>412134bd-9c3e-45c7-bded-f1f438bf057e</subscriptionUuid><parentMessageId>20180515175459E389396V33</parentMessageId></ps:DataMessage>]]></item>
                   <item><![CDATA[<ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>2115e7d4-30a9-4569-879e-488699c611eb</uuid><timestamp>2018-05-15 17:55:06 137</timestamp><subscriptionUuid>412134bd-9c3e-45c7-bded-f1f438bf057e</subscriptionUuid><parentMessageId>20180515175505E388496V37</parentMessageId></ps:DataMessage>]]></item>
                   <item><![CDATA[<ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>eceff4e7-f737-47b3-86c3-36abc9ea0681</uuid><timestamp>2018-05-15 17:55:06 782</timestamp><subscriptionUuid>1ed22a1e-0983-4cc1-b40d-631cf52dda3f</subscriptionUuid><parentMessageId>20180515175505E365026V57</parentMessageId></ps:DataMessage>]]></item>
                </marshalledMessages>
                <hasMoreMessages>true</hasMoreMessages>
             </data>
          </ps:MessagePullReply>
       </S:Body>
    </S:Envelope>

    Voici le script que j'utilise:
    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
    import javax.xml.parsers.*;
    import javax.xml.xpath.*;
    import org.w3c.dom.*;
    import java.util.*
    import java.io.*;
     
    def groovyUtils=new com.eviware.soapui.support.GroovyUtils(context)
     
    def reponse = groovyUtils.getXmlHolder( testRunner.testCase.testSteps["pullMessages"].testRequest.response.getContentAsXml());
     
     
    PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("C:/Users/Clem/Documents/test.xml", true)));
    StringBuilder sb = new StringBuilder();
     
    def items = reponse.getDomNodes("//*:item");
    def itemsCount = items.length;
    items.each{it->item = it.firstChild.nodeValue.trim();
    sb.append(item);}
     
     
    for(def i = 1; i < itemsCount+1;i++){
     
    	def node = reponse.getDomNodes("//*:item["+i+"]/*");
    	node.each{ it -> sb.append(it.firstChild.nodeValue.trim());}
     
    		pw.println(sb.toString());
    		sb = new StringBuilder();
    		sb.append(item);
    	}
     
    	pw.close();


    Voici ce que je trouve dans mon fichier test.xml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>197e9f71-a43f-42e9-bb9f-b89f980a916d</uuid><timestamp>2018-05-15 17:54:54 094</timestamp><subscriptionUuid>412134bd-9c3e-45c7-bded-f1f438bf057e</subscriptionUuid><parentMessageId>20180515175451E395948V1</parentMessageId></ps:DataMessage>
    <ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>eceff4e7-f737-47b3-86c3-36abc9ea0681</uuid><timestamp>2018-05-15 17:55:06 782</timestamp><subscriptionUuid>1ed22a1e-0983-4cc1-b40d-631cf52dda3f</subscriptionUuid><parentMessageId>20180515175505E365026V57</parentMessageId></ps:DataMessage>
    <ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>eceff4e7-f737-47b3-86c3-36abc9ea0681</uuid><timestamp>2018-05-15 17:55:06 782</timestamp><subscriptionUuid>1ed22a1e-0983-4cc1-b40d-631cf52dda3f</subscriptionUuid><parentMessageId>20180515175505E365026V57</parentMessageId></ps:DataMessage>
    <ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>eceff4e7-f737-47b3-86c3-36abc9ea0681</uuid><timestamp>2018-05-15 17:55:06 782</timestamp><subscriptionUuid>1ed22a1e-0983-4cc1-b40d-631cf52dda3f</subscriptionUuid><parentMessageId>20180515175505E365026V57</parentMessageId></ps:DataMessage>
    <ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>eceff4e7-f737-47b3-86c3-36abc9ea0681</uuid><timestamp>2018-05-15 17:55:06 782</timestamp><subscriptionUuid>1ed22a1e-0983-4cc1-b40d-631cf52dda3f</subscriptionUuid><parentMessageId>20180515175505E365026V57</parentMessageId></ps:DataMessage>
    <ps:DataMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><uuid>eceff4e7-f737-47b3-86c3-36abc9ea0681</uuid><timestamp>2018-05-15 17:55:06 782</timestamp><subscriptionUuid>1ed22a1e-0983-4cc1-b40d-631cf52dda3f</subscriptionUuid><parentMessageId>20180515175505E365026V57</parentMessageId></ps:DataMessage>
    J'ai donc le premier résultat que je souhaite puis 5 fois le dernier.

    Qu'ai-je loupé pour ne pas récupérer les éléments intermédiaires ?


    Merci d'avance pour vos réponses

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Hello,

    la logique de ce code est très très bizarre.

    A un moment tu te retrouves avec une variable def items qui contient tous les éléments que tu veux. Puis tu fais un each dessus.
    Il n'y a aucune raison pour que ce each ne fasse pas tout le reste du travail. Et le reste du travail c'est juste, écrire chaque élément dans ce fichier.

    Donc le each devrait faire, pour chaque élément, l'écrire dans le fichier.
    Et après le each, rien. Juste fermer le fichier.

    Le StringBuilder est inutile, tu peux écrire dans le PrintWriter directement.

    Toi tu fais d'abord un each, puis ensuite une boucle on se demande bien pourquoi, et donc c'est complètement illogique et à partir de là tu t'emmêles tous les pinceaux avec les variables d'avant. Ça n'est pas surprenant au fond.
    Bref, tu as un each, tu n'as pas besoin d'une autre boucle. C'est en faisant d'autres que tu t'es planté.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Février 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Hello,

    Merci de ta réponse.

    Donc si je comprends bien (je n'ai que peu de base en code) voici ce que je devrais faire ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def items = reponse.getDomNodes("//*:item");
     
    items.each{
    	it->item = it.firstChild.nodeValue.trim();
    	pw.println(it.toString());
    	}
     
    pw.close();

    Clem

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Euh non, si tu fais une variable item il faudrait aussi t'en servir.

    Ce serait plutôt

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Février 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Super cela fonctionne super bien

    Merci beaucoup !


    Je souhaiterais maintenant sauvegarder chaque item dans un fichier unique (pour avoir un xml propre et unique).
    Chaque fichier sera nommé en fonction de son uuid, dans le dossier du subscriptionUuid.


    Au lieu donc de créer un fichier avant et d'insérer l'item à chaque ligne, je voudrais créer le fichier s'il n'existe pas et y mettre le contenu de chaque item.

    Voici donc le bout de code que j'ai changé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def items = reponse.getDomNodes("//*:item");
     
    items.each{
    	it->item = it.firstChild.nodeValue.trim();
    	def fileName = it.subscriptionUuid+"/"+it.uuid+".xml";
    	def inputFile = new File("C:/Users/clem/FichiersXML/"+fileName);
    	if (!inputFile.exists()){inputFile.write(item)}
     
    	}
    Malheureusement j'ai l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    groovy.lang.MissingPropertyException: No such property: subscriptionUuid for class: org.apache.xmlbeans.impl.store.Xobj$ElementXobj error at line: 17
    J'ai comme l'impression que je n'appelle pas correctement ce qu'il y a dans les balises de mon résultat...

    Une idée ?

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Hélas, je connais suffisamment SoapUI et Groovy pour comprendre ce qui n'allait pas dans ton code d'avant. Mais je ne les connais pratiquement pas en général.

    Ton problème c'est que tu as besoin d'accéder à la structure interne des <ps:DataMessage> que tu reçois en réponse, mais cette réponse est sous forme de texte, donc tu ne les as qu'en tant que texte.
    Il faudrait que tu les parses de String vers une structure XML ou un objet Java qui mappe de XML vers une classe qui t'arrange. Mais je ne sais pas du tout ce que SoapUI et Groovy offrent pour faire ça.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Février 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Grâce à te réponse j'ai trouvé !

    J'ai ajouté une étape pour convertir le String en Xml !

    J'en ai même profité pour faire du pretty print

    Voici donc le code utilisé (ça peut servir à d'autres !):

    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
    import javax.xml.parsers.*;
    import javax.xml.xpath.*;
    import org.w3c.dom.*;
    import java.util.*
    import java.io.*;
    import groovy.xml.*;
     
    def groovyUtils=new com.eviware.soapui.support.GroovyUtils(context)
     
    def reponse = groovyUtils.getXmlHolder( testRunner.testCase.testSteps["pullMessages"].testRequest.response.getContentAsXml());
     
    def items = reponse.getDomNodes("//*:item");
     
     
    items.each{
    	it->item = it.firstChild.nodeValue.trim();
    	def root = new XmlSlurper().parseText(item);
    	def fileName =  root.subscriptionUuid.toString()+"/"+root.uuid+".xml";
    	def inputFile = new File("C:/Users/FichiersXML/"+fileName);
    	if (!inputFile.exists()){inputFile.write(XmlUtil.serialize(item))}
    	}

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Février 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Février 2016
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Bonjour de nouveau,

    J'essaie d'améliorer mon code pour nommer mon fichier en fonction de données multiples inclues dans la réponse de la requête.

    Dans l'arborescence de la réponse, j'ai une balise <eventHistory> qui contient un ou plusieurs <item>.

    Comment faire pour récupérer uniquement les infos du dernier <item> ?

    Quand je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    items.each{
    	it->item = it.firstChild.nodeValue.trim();
    	def root = new XmlSlurper().parseText(item);
    	def fileName =  root.subscriptionUuid.toString()+"/"+root.uuid.toString()+"_"+root.eventHistory.item.sequenceNumber.toString()+".xml";
    	def inputFile = new File("C:/Users/FichiersXML/"+fileName);
    	if (!inputFile.exists()){inputFile.write(XmlUtil.serialize(item))}
    	}
    Le nom du fichier est composé de la concaténation des <sequenceNumber>de tous les <item>.

    Exemple pour 5 items:

    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
       <eventHistory>
          <item>
             <sequenceNumber>1</sequenceNumber>
          </item>
          <item>
             <sequenceNumber>2</sequenceNumber>
          </item>
          <item>
             <sequenceNumber>3</sequenceNumber>
          </item>
          <item>
             <sequenceNumber>4</sequenceNumber>
          </item>
          <item>
             <sequenceNumber>5</sequenceNumber>
          </item>
       </eventHistory>
    9fe7edf4-3fa9-4795-a205-82666b93400a_12345.xml.

    Je voudrais avoir 9fe7edf4-3fa9-4795-a205-82666b93400a_5.xml


    Auriez-vous une solution?


    Clément.

  9. #9
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Le root là, c'est déjà l'élément ps:DataMessage et c'est pour ça, je ne vois pas comment il peut y avoir une structure root.eventHistory.item... là-dedans. La façon la plus simple à faire pour que le nom du fichier reflète une indice unique pour chaque item est de mettre la position des "item" dans marshalledMessages, comme ça:
    Code groovy : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int n=0
    items.each{
    	it->item = it.firstChild.nodeValue.trim();
    	def root = new XmlSlurper().parseText(item);
            //def fileName =  root.subscriptionUuid.toString()+"/"+root.uuid.toString()+"_"+root.eventHistory.item.sequenceNumber.toString()+".xml";
            def fileName =  root.subscriptionUuid.toString()+"/"+root.uuid.toString()+"_"+(++n)+".xml";
    	def inputFile = new File("C:/Users/FichiersXML/"+fileName);
    	if (!inputFile.exists()){inputFile.write(XmlUtil.serialize(item))}
    }
    Voilà !

Discussions similaires

  1. Listview récupérer Item
    Par toutyx dans le forum VBA Access
    Réponses: 1
    Dernier message: 04/06/2007, 18h04
  2. Récupérer liste multiple
    Par nizarsm dans le forum ASP
    Réponses: 3
    Dernier message: 20/11/2006, 08h47
  3. Récupérer valeurs multiples d'une JLIST
    Par bobic dans le forum Composants
    Réponses: 3
    Dernier message: 14/09/2006, 16h37
  4. [ListBox] Récupérer sélection multiple ?
    Par Kylen dans le forum ASP.NET
    Réponses: 4
    Dernier message: 29/06/2006, 14h57
  5. CR9 - Récupérer valeurs multiples d'un champ paramètre
    Par CR9-Deb dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 06/07/2005, 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