Forum Discussion

coopernico46's avatar
coopernico46
Occasional Contributor
7 years ago
Solved

How to extract a value from a label if the label is repeated

Hi all

 

I'm newbie with SOAP but i'm trying to do my best with my very first TestSet automation.

 

At the moment (most of the test case is done) i have only one issue, i don't know how to look into the Response for a special value (to put it into a propertie) if this value is in a label that is repeated through the Response.

 

For example:

 

I would like to extract the "PricedCategoryCode" value but only if the BreakdownType value contain a "C" and Amount Value = 100, so in thsi example the value to extrat to a propertie would be "ST"

 

 

<alpha:CategoryOptions>
                  <alpha:CategoryOption CategoryLocation="Deluxe" PricedCategoryCode="RS">
                     <alpha:PriceInfos>
                        <alpha:PriceInfo Amount="1289.00" BreakdownType="0201A" NCCFAmount="0.00" NonRefundableType="1" PromotionDescription="STD 1" FareCode="D2042767"/>
                        <alpha:PriceInfo Amount="0" BreakdownType="0201A" FareCode="D2042767"/>
                        <alpha:PriceInfo BreakdownType="01 A" FareCode="D2042767"/>
                        <alpha:PriceInfo BreakdownType="01 " FareCode="D2042767"/>
                        <alpha:PriceInfo Amount="1289.00" BreakdownType="0202C" NCCFAmount="0.00" NonRefundableType="1" PromotionDescription="STD 1" FareCode="D2042767"/>
                        <alpha:PriceInfo Amount="0" BreakdownType="0202A" FareCode="D2042767"/>
                        <alpha:PriceInfo BreakdownType="02 A" FareCode="D2042767"/>
                        <alpha:PriceInfo BreakdownType="02 " FareCode="D2042767"/>
                     </alpha:PriceInfos>
                  </alpha:CategoryOption>
                  <alpha:CategoryOption CategoryLocation="Deluxe" PricedCategoryCode="ST">
                     <alpha:PriceInfos>
                        <alpha:PriceInfo Amount="100.00" BreakdownType="0201C" NCCFAmount="0.00" NonRefundableType="1" PromotionDescription="STD 1" FareCode="D2042767"/>
                        <alpha:PriceInfo Amount="0" BreakdownType="0201A" FareCode="D2042767"/>
                        <alpha:PriceInfo BreakdownType="01 A" FareCode="D2042767"/>
                        <alpha:PriceInfo BreakdownType="01 " FareCode="D2042767"/>
                        <alpha:PriceInfo Amount="1139.00" BreakdownType="0202C" NCCFAmount="0.00" NonRefundableType="1" PromotionDescription="STD 1" FareCode="D2042767"/>
                        <alpha:PriceInfo Amount="0" BreakdownType="0202A" FareCode="D2042767"/>
                        <alpha:PriceInfo BreakdownType="02 A" FareCode="D2042767"/>
                        <alpha:PriceInfo BreakdownType="02 " FareCode="D2042767"/>
                     </alpha:PriceInfos>
                  </alpha:CategoryOption>

 

This response change every time y execute my code, so for me, if there are more than one value that match with the criterial, the first one will be fine for me.

 

 

Thanks in advance for your support!

 

 

  • As stated, using find you will only get the first result, so no issues with multiple results. The alternative would be findAll.

     

    To solve the error you just need to make sure the result for categoryCode is a String by getting the text(). Same thing as the line above it.

     

    String categoryCode = new XmlSlurper().parseText(context.response)
    .CategoryOption
    .find {it.PriceInfos.PriceInfo.find { it.'@BreakdownType'.text() == "02 A" }}
    .'@PricedCategoryCode'.text()
    context.testCase.setPropertyValue('CategoryList', categoryCode)

    Sorry I missed this before.

  • nmrao's avatar
    nmrao
    6 years ago

    coopernico46,
    See demo script. (use "log.info" instead of println)

    https://ideone.com/GIA7pN

     

    See the colored text (changes)

    def categoryCode = new XmlSlurper().parseText(context.response).'**'.find{ 
        it.PriceInfos.PriceInfo.find {
            it.'@BreakdownType'.text() == "02 A"
        }
    }.@PricedCategoryCode?.text()
    context.testCase.setPropertyValue('PricedCategoryCode', categoryCode)

18 Replies

  • JHunt's avatar
    JHunt
    Community Hero

    I had to tidy up your XML a little (since you didn't provide the namespace definition and left off the closing tag). Though if you use your real XML you shouldn't need to change anything. Here's the XML I used.

     

     

    String xml = '''<CategoryOptions>
        <CategoryOption CategoryLocation="Deluxe" PricedCategoryCode="RS">
         <PriceInfos>
            <PriceInfo Amount="1289.00" BreakdownType="0201A" NCCFAmount="0.00" NonRefundableType="1" PromotionDescription="STD 1" FareCode="D2042767"/>
            <PriceInfo Amount="0" BreakdownType="0201A" FareCode="D2042767"/>
            <PriceInfo BreakdownType="01 A" FareCode="D2042767"/>
            <PriceInfo BreakdownType="01 " FareCode="D2042767"/>
            <PriceInfo Amount="1289.00" BreakdownType="0202C" NCCFAmount="0.00" NonRefundableType="1" PromotionDescription="STD 1" FareCode="D2042767"/>
            <PriceInfo Amount="0" BreakdownType="0202A" FareCode="D2042767"/>
            <PriceInfo BreakdownType="02 A" FareCode="D2042767"/>
            <PriceInfo BreakdownType="02 " FareCode="D2042767"/>
         </PriceInfos>
        </CategoryOption>
        <CategoryOption CategoryLocation="Deluxe" PricedCategoryCode="ST">
         <PriceInfos>
            <PriceInfo Amount="100.00" BreakdownType="0201C" NCCFAmount="0.00" NonRefundableType="1" PromotionDescription="STD 1" FareCode="D2042767"/>
            <PriceInfo Amount="0" BreakdownType="0201A" FareCode="D2042767"/>
            <PriceInfo BreakdownType="01 A" FareCode="D2042767"/>
            <PriceInfo BreakdownType="01 " FareCode="D2042767"/>
            <PriceInfo Amount="1139.00" BreakdownType="0202C" NCCFAmount="0.00" NonRefundableType="1" PromotionDescription="STD 1" FareCode="D2042767"/>
            <PriceInfo Amount="0" BreakdownType="0202A" FareCode="D2042767"/>
            <PriceInfo BreakdownType="02 A" FareCode="D2042767"/>
            <PriceInfo BreakdownType="02 " FareCode="D2042767"/>
         </PriceInfos>
        </CategoryOption>
    </CategoryOptions>'''

    Then this script returns "ST":

     

    new XmlSlurper().parseText(xml).CategoryOption.find{ 
        it.PriceInfos.PriceInfo.find {
            it.'@BreakdownType'.text().contains('C') && it.'@Amount'.text() == "100.00"
        }
    }.'@PricedCategoryCode'

     

    • coopernico46's avatar
      coopernico46
      Occasional Contributor

      Hi JHunt

       

      Sorry for the delay.

       

      I'm trying to implement your code into my project but i'm so newbi with soapui.

       

      Where should i type your code? In a property transfer element as Xquery? In a Groovy script?

       

       

      Let me attach a screenshoot where you can take a look over my project, with the CategoryList Response and how i'm getting a category right now.

       

      My problem, as i try to explain in my first post, is that i want to choose a category from the whole CategoryList Response and then move this specific Category to a property at testset level call ChooseCategory to be used along the rest of the test set.

      • nmrao's avatar
        nmrao
        Champion Level 3
        You could use "Script Assertion" for the above code with minimal change to what is suggested by JHunt

        //Use below statement for xml assignment (whole fixed xml response)
        String xml = context.response

  • JHunt's avatar
    JHunt
    Community Hero

    Yes, as suggested by nmrao, add the code as a Script Assertion on your request test step. To transfer to a project property, use setPropertyValueByName:

     

    new XmlSlurper().parseText(xml)
     .CategoryOption.find {
        it.PriceInfos.PriceInfo.find { it.'@BreakdownType'.text().contains('C') && it.'@Amount'.text() == "100.00" }
    }.'@PricedCategoryCode' .with { context.project.setPropertyValueByName("Some property", it) }

     

     

    • coopernico46's avatar
      coopernico46
      Occasional Contributor

      Hi JHunt and nmrao

       

      I just modify a little bit the script due to:

       

      - My properties are in a testCase level, not at project level 

      - I decided to filter just by one of the properties,

      - To add the xml = context.response 

       

      So,at this moment, the script look as you see below:

       

      def xml = context.response
      new XmlSlurper().parseText(xml)
      .CategoryOption.find { 
      it.PriceInfos.PriceInfo.find { it.'@BreakdownType'.text() == "02 A" }
      }.'@PricedCategoryCode'
      .with { context.testCase.setPropertyValueByName("PricedCategoryCode", it)}

      but when i try to execute, the system always send me the message 

       

      No signature of method: groovy.util.slurpersupport.NodeChildren.setPropertyValueByName() is applicable for argument types: (java.lang.String, groovy.util.slurpersupport.Attributes) values: [PricedCategoryCode, ]

      After a lot of Headaches i think that the problem could be that, there is more than one

      @PricedCategoryCode

       

      that meet my conditions. Could this be possible? how can i solved it (for example taken the first @PriceCategoryCode that meet my conditions)?

       

      Thank you so much for your appreciated support

      • nmrao's avatar
        nmrao
        Champion Level 3
        coopernico46,

        Do you need to use the extracted for the same test case or is it required for the tests across the project?

  • JHunt's avatar
    JHunt
    Community Hero

    As stated, using find you will only get the first result, so no issues with multiple results. The alternative would be findAll.

     

    To solve the error you just need to make sure the result for categoryCode is a String by getting the text(). Same thing as the line above it.

     

    String categoryCode = new XmlSlurper().parseText(context.response)
    .CategoryOption
    .find {it.PriceInfos.PriceInfo.find { it.'@BreakdownType'.text() == "02 A" }}
    .'@PricedCategoryCode'.text()
    context.testCase.setPropertyValue('CategoryList', categoryCode)

    Sorry I missed this before.