Как получить значение дочернего узла из парена, предпочтительнее другого дочернего значения в Groovy readyAPI

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

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

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

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

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

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

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 ответа

Решение

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

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

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

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 на имя вашего запроса

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

Есть альтернативный способ сделать что-то, используя 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)

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

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

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

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

Другие вопросы по тегам