Xquery SoapUI中的嵌套属性扩展

Xquery SoapUI中的嵌套属性扩展,xquery,soapui,Xquery,Soapui,简短版本:如何在SoapUI Pro 5中的XQuery中进行嵌套属性扩展,其中外部属性是对上一测试步骤的ResponseAsXML的引用,而内部属性来自属性文件 例如: 我的测试步骤如下所示: POST/GET http://myEndpoint.com/customers/{customerId}/emails for $email in //emails where $email/id/text()='${AddEmailToCustomer#ResponseAsXml#declare

简短版本:如何在SoapUI Pro 5中的XQuery中进行嵌套属性扩展,其中外部属性是对上一测试步骤的ResponseAsXML的引用,而内部属性来自属性文件

例如:

我的测试步骤如下所示:

POST/GET http://myEndpoint.com/customers/{customerId}/emails
for $email in //emails
where $email/id/text()='${AddEmailToCustomer#ResponseAsXml#declare namespace ns1='http://myEndpoint.com/customers/${#EmailProperties#customerId}/emails'; //ns1:Response[1]/ns1:id[1]}'
  • 调用AddCustomer,它也会添加电子邮件地址,并返回customerId
  • 使用属性传输将customerId存储在名为EmailProperties的属性文件中
  • 调用AddEmailToCustomer,向同一客户添加第二封电子邮件并返回新的emailId
  • 调用GetEmailsForCustomer,它将为客户返回两封电子邮件
  • 步骤3和步骤4的其余端点如下所示:

    POST/GET http://myEndpoint.com/customers/{customerId}/emails
    
    for $email in //emails
    where $email/id/text()='${AddEmailToCustomer#ResponseAsXml#declare namespace ns1='http://myEndpoint.com/customers/${#EmailProperties#customerId}/emails'; //ns1:Response[1]/ns1:id[1]}'
    
    在尝试验证步骤4时,我编写了一个XQuery,通过循环响应(因为我们无法保证电子邮件在响应中的顺序)来查找步骤3中添加的电子邮件。在我的XQuery中,如果我像这样在名称空间中硬编码customerId,它可以正常工作:

    for $email in //emails
    where $email/id/text()='${AddEmailToCustomer#ResponseAsXml#declare namespace ns1='http://myEndpoint.com/customers/1234/emails'; //ns1:Response[1]/ns1:id[1]}'
    
    但如果我尝试使用属性文件中的customerId,如下所示:

    POST/GET http://myEndpoint.com/customers/{customerId}/emails
    
    for $email in //emails
    where $email/id/text()='${AddEmailToCustomer#ResponseAsXml#declare namespace ns1='http://myEndpoint.com/customers/${#EmailProperties#customerId}/emails'; //ns1:Response[1]/ns1:id[1]}'
    
    我发现一个错误,它无法找到预期的子节点:

    ...Exception:org.custommonkey.xmlunit.Diff[different] Expected presence of child nodes to be 'true' but was 'false'...
    

    如何实现这一点?

    您可以对名称空间使用通配符来大大简化XPath:

    where $email/id/text()='${AddEmailToCustomer#ResponseAsXml#//*:Response[1]/*:id[1]}'
    

    正如@SiKing所建议的,您可以对名称空间使用通配符来简化XPath,如果您不关心检查名称空间(这是最常见的行为),这就足够了。但是,我认为您可以将名称空间放在属性中,以便检查可能的不同名称空间,因为您可以尝试声明XQuery匹配断言,如下所示:

    declare namespace ns1='http://myEndpoint.com/customers/${#EmailProperties#customerId}/emails';
    <XQueryResult>
    {
     for $email in //ns1:emails
     where $email/id/text()='${AddEmailToCustomer#Response#//ns1:Response[1]/ns1:id[1]}'
     return $email
    }
    </XQueryResult>
    
    declare namespace ns1='1'http://myEndpoint.com/customers/${#EmailProperties#customerId}/emails';
    {
    对于//ns1中的$email:emails
    其中$email/id/text()
    返回$email
    }
    
    请注意,如果
    EmailProperties
    是一个属性测试步骤,那么您必须使用
    ${EmailProperties#customerId}
    而不是
    ${EmailProperties#customerId}
    ,在这种情况下,我更喜欢使用
    \Response
    而不是
    \ResponseAsXml


    希望这能有所帮助,

    效果很好,谢谢!我没有意识到我可以为名称空间使用通配符:)SiKing的答案适用于这个测试用例,但是如果我真的需要处理多个名称空间,我会记住你的答案!谢谢