Forum Discussion

evoks's avatar
evoks
Occasional Contributor
7 years ago
Solved

GroovyScript: Parse SOAP Response and get node names and node values

Hi all,

 

I have a SOAP response like this : 

 

 

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Header>
      <MessageID xmlns="http://www.w3.org">uuid: ...</MessageID>
   </S:Header>
   <S:Body>
      <ns3:ResponseElement xmlns:ns2="http://www.example.com/services/common/example/xsd" xmlns:ns3="http://www.example.com/example/xsd">
         <Info>
            <Data>
               <Site>OneValue</Site>
            </Data>
            <OtherData>
               <Code>01234</Code>
               <Time>2017-05-28</Time>
               <SecondCode>ThirdValue</SecondCode>
               <Number>000</Number>
            </OtherData>
         </Info>
         <Info>
            <Data>
               <Site>OneValue</Site>
            </Data>
            <OtherData>
               <Code>56789</Code>
               <Time>2017-07-30</Time>
               <SecondCode>ThirdValue</SecondCode>
               <Number>111</Number>
            </OtherData>
         </Info>
      </ns3:ResponseElement>
   </S:Body>
</S:Envelope>

 

And I succeed to get some datas with this code :

 

def WebServiceResponse = context.expand( '${#[MyWebService]#Response#declare namespace SOAP-ENV=\'http://schemas.xmlsoap.org/soap/envelope/\'; //SOAP-ENV:Body[1]}' )
def ParsingResult = new XmlSlurper().parseText(WebServiceResponse)
def Collection = ParsingResult.'**'.collectEntries {!it.childNodes()?[it.name(), it.text()]:[:]}

for(int i = 0;i<8;i++) {
log.info (Collection.collect()[i].toString())
}

 

My output : 

 

Tue Jun 06 13:23:00 CEST 2017:INFO: Site=OneValue
Tue Jun 06 13:23:00 CEST 2017:INFO: Code=56789
Tue Jun 06 13:23:00 CEST 2017:INFO: Time=2017-07-30
Tue Jun 06 13:23:00 CEST 2017:INFO: SecondCode=ThirdValue
Tue Jun 06 13:23:00 CEST 2017:INFO: Number=111

 

But I cannot iterate in the first node "Info" and get its node values. I only get the second part. I want this output :

 

Site=OneValue
Code=01234
Time=2017-05-28
SecondCode=ThirdValue
Number=000

Site=OneValue
Code=56789
Time=2017-07-30
SecondCode=ThirdValue
Number=111

 

Could you help me to get a solution for this problem ? 

Many thanks in advance.

  • Hi,

     

    Ok, no problem. Although I think you can surely assume that given that it's a SOAP response we can start at the Body element - would that be OK?

     

    If so, here is a recursive alternative:

     

    def results=[]
    
    def printNode
    printNode = { output,node ->         
        node.children().each{ printNode(results,it) }
        if (node.children().size()==0) output << node.name()+'='+node.text() //Exlude parent elements
    }
    
    slurperResponse.'**'.findAll { it.name() == 'Body' }.each { printNode(results,it) }
    
    results.each{
    	log.info it
    }

    This should:

    • Iterate over all child elements (not attributes, could add that)
    • Only print the child element names and values (not the parent ones, to get those remove the if statement that excludes them) 

    Is this what you need?

    Regards,

    Rup

13 Replies

    • rupert_anderson's avatar
      rupert_anderson
      Valued Contributor

      Hi,

       

      Is this what you want? (have refactored it slightly):

       

       

      def response='''
      <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
         <S:Header>
            <MessageID xmlns="http://www.w3.org">uuid: ...</MessageID>
         </S:Header>
         <S:Body>
            <ns3:ResponseElement xmlns:ns2="http://www.example.com/services/common/example/xsd" xmlns:ns3="http://www.example.com/example/xsd">
               <Info>
                  <Data>
                     <Site>OneValue</Site>
                  </Data>
                  <OtherData>
                     <Code>01234</Code>
                     <Time>2017-05-28</Time>
                     <SecondCode>ThirdValue</SecondCode>
                     <Number>000</Number>
                  </OtherData>
               </Info>
               <Info>
                  <Data>
                     <Site>OneValue</Site>
                  </Data>
                  <OtherData>
                     <Code>56789</Code>
                     <Time>2017-07-30</Time>
                     <SecondCode>ThirdValue</SecondCode>
                     <Number>111</Number>
                  </OtherData>
               </Info>
            </ns3:ResponseElement>
         </S:Body>
      </S:Envelope>
      '''
      
      def slurperResponse = new XmlSlurper().parseText(response)
      slurperResponse.Body.ResponseElement.Info.each{
      	log.info it.Data.Site
      	log.info it.OtherData.Code
      	log.info it.OtherData.Time
      	log.info it.OtherData.SecondCode
      	log.info it.OtherData.Number
      }

      You can hopefully just replace response with your WebServiceResponse.

       

      Regards,

      Rupert

       

      • evoks's avatar
        evoks
        Occasional Contributor

        You're right, but if I have another parsing response, node names will change. So, I am not able to know node names.

         

         

        I have to provide a code which is parsing node names and values associated without know them.