Forum Discussion

evoks's avatar
evoks
Occasional Contributor
8 years ago

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

    • 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.