Forum Discussion

DatSupport's avatar
DatSupport
New Contributor
12 years ago

XQuery in propertyTransfer for multiple return elements

Hi, I am currently evaluating on the features of SOAP UI 4.5.2.

I have a scenario here that I would like to seek advise on iteration on a set of elements in a test request xml file.

Please refer to the scenario below:

Example, I have a sequence of requests whose responses have to be the request values of the following request. So far so good. Imagine, that not only single values are necessary but the response values of a specific element name <DatEquipmentId> that are returned n-times in the responses ind different nodes like that:

                  <ns3:Equipment>
<ns3:SeriesEquipment>
<ns3:EquipmentPosition>
<ns3:DatEquipmentId>26803</ns3:DatEquipmentId>
<ns3:ManufacturerEquipmentId>4UE</ns3:ManufacturerEquipmentId>
<ns3:Description>Airbag Fahrer-/Beifahrerseite</ns3:Description>
<ns3:EquipmentGroup>AIR1</ns3:EquipmentGroup>
</ns3:EquipmentPosition>
<ns3:EquipmentPosition>
<ns3:DatEquipmentId>40000</ns3:DatEquipmentId>
<ns3:Description>Anti-Blockier-System (ABS)</ns3:Description>
<ns3:EquipmentGroup>ABS</ns3:EquipmentGroup>
</ns3:EquipmentPosition>
</ns3:SeriesEquipment>
<ns3:SpecialEquipment>

<ns3:EquipmentPosition>
<ns3:DatEquipmentId>18603</ns3:DatEquipmentId>
<ns3:ManufacturerEquipmentId>8Q5</ns3:ManufacturerEquipmentId>
<ns3:Description>Xenon-Scheinwerfer Plus adaptive light (Abbiegelicht integriert)</ns3:Description>
<ns3:EquipmentGroup>BXEL</ns3:EquipmentGroup>
</ns3:EquipmentPosition>
</ns3:SpecialEquipment>
...
<ns3:DATECodeEquipment>
<ns3:EquipmentPosition>
<ns3:DatEquipmentId>97000</ns3:DatEquipmentId>
<ns3:Description>Motor 2,0 Ltr. - 103 kW TDI</ns3:Description>
</ns3:EquipmentPosition>
...


All those <DatEquipmentId> (hundreds of it) have to be used in the next following request within request parameter <equipment></equipment>, enclosed with its own tag.

I want to use only propertyTransfer to make it reuseable and tried it with the following code:

declare namespace ...;

for $b in //ns3:EquipmentPosition
return (<equipment>
{
for $y in //ns3:DatEquipmentId[$b]/text()
return string($y)
}
</equipment>)


As a result I got the following back in the following request:
<equipment>26803 40000 70303 70600 15804 15702 25702 4305 40808 40705 27805 13202 70108 70308 25805 35003 74300 27400 75205 26109 39307 10004 26901 69902 68909 18205 504 37704 86901 18301 61906 77602 33508 26903 69801 32704 32705 30305 27500 42001 31900 38106 35301 24612 24198 15201 72600 25802 22506 37901 28901 18909 1702 49004 29404 27202 68707 19102 19000 29500 18904 22202 18603 97000 10004 75205</equipment>


So, all results within one tag. But I want each of them enclosed in its own <equipment> tag.

So, I tried the next code:

declare namespace...;

for $b in //ns3:EquipmentPosition
let $y := //ns3:DatEquipmentId[$b]

for $avtext in $y
return (<equipment>{$avtext/text()}</equipment>)


As a result I got back only the first of all values, even enclosed in the correct tag:

<equipment>26803</equipment>



So, can someone help me to solve that problem, please? For different reasons I don't want to use groovy scripts, but only propertyTransfer. Is this possible?

Regards,
Heike
  • nmrao's avatar
    nmrao
    Icon for Champion Level 2 rankChampion Level 2
    would you like to try this code?
    for $id in //ns3:DatEquipmentId/text()
    return (<equipment>{data($id)}</equipment>)
  • PaulDonny's avatar
    PaulDonny
    Regular Contributor
    for $b in //ns3:EquipmentPosition
    return(<equipment>
    {
    let $y := //ns3:DatEquipmentId[$b]
    for $avtext in $y
    return (<equipment>{data($avtext)}</equipment>)
    }
    </equipment>)



    I combined a bit of everyone's code here to make it work out.

    And an example of the results:

    <equipment>26803</equipment><equipment>40000</equipment><equipment>18603</equipment><equipment>97000</equipment>


    BTW, thanks. I haven't used XQuery in quite a while and I really need to freshen up on it.
  • nmrao's avatar
    nmrao
    Icon for Champion Level 2 rankChampion Level 2
    If my understanding of your exact response is correct, the 2 line should do the job.
    Any way, glad you could proceed.
  • DatSupport's avatar
    DatSupport
    New Contributor
    Hi Guys,
    thank you for your response. I tried both of your proposals. While the first proposal of mrao only returned exactly one match, the proposal of PaulM was, referring to the result, a bit like my own ones, because there are enclosing <equipment> tags around the inner single <epuipment> tags (see below the red ones).


    <equipment><equipment>26803</equipment><equipment>40000</equipment><equipment>70303</equipment><equipment>29500</equipment><equipment>18904</equipment><equipment>22202</equipment><equipment>97000</equipment><equipment>10004</equipment><equipment>75205</equipment></equipment>

    The problem is, that I don't need to have the outer enclosing equipment tags. I only want to have each value enclosed by an equipment tag. But every time I just try to leave off the outer equipment I get a java.lang.reflect.InvocationTargetException. It's not possible to have the following code working:

    for $b in //ns3:EquipmentPosition
    return( /*here I left out the <equipment> tag */
    {
    let $y := //ns3:DatEquipmentId[$b]
    for $avtext in $y
    return (<equipment>{data($avtext)}</equipment>)
    }
    /* I left out the </equipment> tag, too */)


    What do I have to do to get only the inner equipment tags working?
    I hope you understand that problem.
    Regards,
    H
  • nmrao's avatar
    nmrao
    Icon for Champion Level 2 rankChampion Level 2
    Using the xml snippet from the original post to make xquery result(in a tool) since I dont have the exact response.
    Please see it returns as expected, used the same query i sent you (by removing the namespaces)
  • nmrao's avatar
    nmrao
    Icon for Champion Level 2 rankChampion Level 2
    You may see the difference in result when the other query is used, giving the same result multiple times due to additional for loop.

    The change to query made, removed '{}'

    for $b in //EquipmentPosition 
    return (
    let $y := //DatEquipmentId[$b]
    for $avtext in $y
    return (<equipment>{data($avtext)}</equipment>)
    )
  • PaulDonny's avatar
    PaulDonny
    Regular Contributor
    DatSupport wrote:
    Hi Guys,
    thank you for your response. I tried both of your proposals. While the first proposal of mrao only returned exactly one match, the proposal of PaulM was, referring to the result, a bit like my own ones, because there are enclosing <equipment> tags around the inner single <epuipment> tags (see below the red ones).


    <equipment><equipment>26803</equipment><equipment>40000</equipment><equipment>70303</equipment><equipment>29500</equipment><equipment>18904</equipment><equipment>22202</equipment><equipment>97000</equipment><equipment>10004</equipment><equipment>75205</equipment></equipment>

    The problem is, that I don't need to have the outer enclosing equipment tags. I only want to have each value enclosed by an equipment tag. But every time I just try to leave off the outer equipment I get a java.lang.reflect.InvocationTargetException. It's not possible to have the following code working:

    for $b in //ns3:EquipmentPosition
    return( /*here I left out the <equipment> tag */
    {
    let $y := //ns3:DatEquipmentId[$b]
    for $avtext in $y
    return (<equipment>{data($avtext)}</equipment>)
    }
    /* I left out the </equipment> tag, too */)


    What do I have to do to get only the inner equipment tags working?
    I hope you understand that problem.
    Regards,
    H



    Mine doesn't include the outer equipment tags so I would presume it is being caused by where you are putting the transfer (or getting the data from). I used, essentially, what you had posted above within SoapUI to do the transfer and here is my result:

    <soapenv:Body><equipment>26803</equipment><equipment>40000</equipment><equipment>18603</equipment><equipment>97000</equipment></soapenv:Body>


    That is with the request:

     <ns3:Equipment>
    <ns3:SeriesEquipment>
    <ns3:EquipmentPosition>
    <ns3:DatEquipmentId>26803</ns3:DatEquipmentId>
    <ns3:ManufacturerEquipmentId>4UE</ns3:ManufacturerEquipmentId>
    <ns3:Description>Airbag Fahrer-/Beifahrerseite</ns3:Description>
    <ns3:EquipmentGroup>AIR1</ns3:EquipmentGroup>
    </ns3:EquipmentPosition>
    <ns3:EquipmentPosition>
    <ns3:DatEquipmentId>40000</ns3:DatEquipmentId>
    <ns3:Description>Anti-Blockier-System (ABS)</ns3:Description>
    <ns3:EquipmentGroup>ABS</ns3:EquipmentGroup>
    </ns3:EquipmentPosition>
    </ns3:SeriesEquipment>
    <ns3:SpecialEquipment>
    <ns3:EquipmentPosition>
    <ns3:DatEquipmentId>18603</ns3:DatEquipmentId>
    <ns3:ManufacturerEquipmentId>8Q5</ns3:ManufacturerEquipmentId>
    <ns3:Description>Xenon-Scheinwerfer Plus adaptive light (Abbiegelicht integriert)</ns3:Description>
    <ns3:EquipmentGroup>BXEL</ns3:EquipmentGroup>
    </ns3:EquipmentPosition>
    </ns3:SpecialEquipment>
    <ns3:DATECodeEquipment>
    <ns3:EquipmentPosition>
    <ns3:DatEquipmentId>97000</ns3:DatEquipmentId>
    <ns3:Description>Motor 2,0 Ltr. - 103 kW TDI</ns3:Description>
    </ns3:EquipmentPosition>
    </ns3:DATECodeEquipment>
    </ns3:Equipment>



    In your Target are you possibly putting it into an equipment tag? If so, go to the parent.