как получить значение дочернего узла из парена, предпочтительнее другого дочернего значения в Groovy readyAPI - PullRequest
0 голосов
/ 29 января 2019

Я пытаюсь получить значения из ответа веб-службы в readyAPI, чтобы я мог передать его другому запросу веб-службы и создать автоматизированный поток тестирования.

Я пробовал разные фрагменты кода чаще всегоиз них была одна строка кода, которую я предпочитаю, если это возможно.Я могу взять значение из узла, набрав родительский узел по значению его атрибута.Я также могу получить родительский узел по значению атрибута дочерних узлов и использовать его для получения другого дочернего значения.

Вот несколько примеров:

Первый формат, который я могу использовать для получения значения потомков:

<webserviceResponse>
<documentslist>
<document @id="1">
        <payment @currency="USD" >
        <amount>1250.00</amount>
        </payment>
</document>
<document @id="2">
        <payment @currency="JPY" >
        <amount>150.00</amount>
        </payment>
</document>
<document @id="3">
        <payment @currency="EUR" >
        <amount>1170.00</amount>
        </payment>
</document>
<!-- etc. -->
</documentslist>

-----> Toполучить валюту для конкретного документа

def webServiceResponse = "webservice#Response"
int index=2
def currency = context.expand('${'+webServiceResponse+'//*:document[@id="['+index+']"]//*:payment/@currency}')

-----> Результатом этого является "JPY"


<webserviceResponse>
<documentslist>
<document @id="1">
        <payment @currency="USD" >
        <amount>1250.00</amount>
        </payment>
        <refund>true</refund>
</document>
<document @id="2">
        <payment @currency="JPY" >
        <amount>150.00</amount>
        </payment>
</document>
<document @id="3">
        <payment @currency="EUR" >
        <amount>1170.00</amount>
        </payment>
        <refund>false</refund>
</document>
<!-- etc. -->
</documentslist>

-------> Чтобы получить валюту, зависящую от существования определенного узла В этом примере мы просматриваем файл сверху вниз и находим все узлы возврата, а также берем значение валюты, которое находится в том же блоке, во второй раз, когда мыувидеть узел возврата.

def webServiceResponse = "webservice#Response"
int index=2
def currrency= context.expand('${'+webServiceResponse+'(//*:refund)['+index+']//parent::*//*:payment/@currency}')

--------> Результат для этого - "EUR"


Это то, что я не могу взять дочернее значение таким же образом.

<webserviceResponse>
<documentslist>
<document>
    <key>D_Computer</key>
    <currency>USD</currency>
    <amount>1250.00</amount>
    <refund>true</refund>
</document>
<document>
    <key>D_Keyboard</key>
    <currency>JPY</currency>
    <amount>150.00</amount>
</document>
<document>
    <key>D_Monitor</key>
    <currency>EUR</currency>
    <amount>1170.00</amount>
    <refund>false</refund>
</document>
<!-- etc. -->
</documentslist>

Моя проблема с этим, он не имеет никаких атрибутов, имеет только значения узлов.Я знаю, что у него, кстати, нет целого числа, но, возможно, я делаю неправильно, чего не понимаю.

Я хочу получить значение суммы, зависящее только от значения «ключевых» узлов, которое я собираюсь указать в сценарии.

Результат должен показать: 150,00

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Существует альтернативный способ сделать что-либо, используя Hashmap , если другой ответ не работает из-за пространств имен в вашем XML

Попробуйте этот метод

Мы получаемсначала все значения, используя getNodeValues ​​, а затем, так как у нас есть пара, мы помещаем в hashmap.

Теперь вы можете получить что угодно.

def groovyUtils=new com.eviware.soapui.support.GroovyUtils(context)
def xml=groovyUtils.getXmlHolder("Request1#Response");

def keys=xml.getNodeValues("//*:documentslist/*:document/*:key")
def amounts=xml.getNodeValues("//*:documentslist/*:document/*:amount")

log.info keys.toString()
log.info amounts.toString()

HashMap h1=[:]
// Add the pair into hashmap and then retrieve
for(int i=0;i<keys.size();i++)
{
    h1.put(keys[i],amounts[i])
}
def whichone="D_Computer"
log.info "Value for $whichone is " + h1.get(whichone)

enter image description here

Допустим, вы хотите получить более одного значения, тогда вы можете использовать массивы.т.е. принимать массивы в качестве ключа, валюты, суммы, возврата

, поэтому, если вы хотите получить возврат для ключа = 'Z'. Используя цикл for, вы можете знать, что Z присутствует в 3-х местах в массиве

тогда ваш возврат должен быть возвращен [3].Аналогично валюта [3] и сумма [3]

Оба ответа имеют свою актуальность

0 голосов
/ 31 января 2019

Спасибо за очень подробный и хорошо написанный вопрос.

Вы можете использовать ниже.Ваша проблема проста, так как в ней нет пространства имен.

Техника та же, что вы показывали, просто вам не нужно использовать @ в качестве атрибута

def groovyUtils=new com.eviware.soapui.support.GroovyUtils(context)
def xml=groovyUtils.getXmlHolder("NameOfRequest#Response");
def currency=xml.getNodeValue("//*:documentslist/*:document[key='${key}']/*:amount");
log.info "Value of $key  is " + currency

key="D_Monitor"
currency=xml.getNodeValue("//*:documentslist/*:document[key='${key}']/*:amount");
log.info "Value of $key  is " + currency

Заменить NameOfRequest с именем вашего запроса

enter image description here

Существует также альтернативный способ.Я опубликую это как отдельный ответ, чтобы не вызвать путаницу.Этот еще лучше, чем другой

...