如何使用Rest-assured从具有多个命名空间的SOAP XML响应中提取值?

huangapple go评论76阅读模式
英文:

How to extract value from SOAP XML response with multiple namespaces using Rest-assured?

问题

我有以下来自我使用Rest Assured进行调用的SOAP响应:

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Header>
      <epns:context xmlns:epns="http://mywebservice/v6">
         <epns:userId>SYSTEM</epns:userId>
         <epns:systemId>WEBSERVICE</epns:systemId>
         <epns:realmId />
      </epns:context>
   </env:Header>
   <S:Body>
      <ns0:liststatusResponse xmlns:ns0="http://mywebservice/v6/workflow" xmlns:asst="http://mywebservice/v6" xmlns:status="http://mywebservice/v6" xmlns:thirdparty="http://mywebservice/v6/thirdparty/v6">
         <return xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="status:agreementstatus">
            <status:level>IN-PROGRESS</status:level>
            <status:nextWorkDate>2020-07-31T09:36:50+01:00</status:nextWorkDate>
            <status:type>788</status:type>
            <status:agreementNumber>89ADFGH</status:agreementNumber>
         </return>
      </ns0:liststatusResponse>
   </S:Body>
</S:Envelope>

我需要提取多个值,例如在第一个<return...>块中的status:type中的788

我有一个用于检查响应中返回的值的测试工具:

@Test
public static void xmlPathTester() {
  XmlPath xmlPath = new XmlPath(XML);
  List<String> results = xmlPath.getList("S:Envelope.S:Body.ns0:liststatusResponse.return.status:type.text()");
    for (String result : results) {
        System.out.println(result);
    }
}

但是目前它只返回一个结果,即一个空字符串。

我不清楚我哪里出错了。

英文:

I have the following SOAP Response returned from a call I make using Rest Assured:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;S:Envelope xmlns:S=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:env=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
   &lt;env:Header&gt;
      &lt;epns:context xmlns:epns=&quot;http://mywebservice/v6&quot;&gt;
         &lt;epns:userId&gt;SYSTEM&lt;/epns:userId&gt;
         &lt;epns:systemId&gt;WEBSERVICE&lt;/epns:systemId&gt;
         &lt;epns:realmId /&gt;
      &lt;/epns:context&gt;
   &lt;/env:Header&gt;
   &lt;S:Body&gt;
      &lt;ns0:liststatusResponse xmlns:ns0=&quot;http://mywebservice/v6/workflow&quot; xmlns:asst=&quot;http://mywebservice/v6&quot; xmlns:status=&quot;http://mywebservice/v6&quot; xmlns:thirdparty=&quot;http://mywebservice/v6/thirdparty/v6&quot;&gt;
         &lt;return xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:type=&quot;status:agreementstatus&quot;&gt;
            &lt;status:level&gt;IN-PROGRESS&lt;/status:level&gt;
            &lt;status:nextWorkDate&gt;2020-07-31T09:36:50+01:00&lt;/status:nextWorkDate&gt;
            &lt;status:type&gt;788&lt;/status:type&gt;
            &lt;status:agreementNumber&gt;89ADFGH&lt;/status:agreementNumber&gt;
         &lt;/return&gt;
      &lt;/ns0:liststatusResponse&gt;
   &lt;/S:Body&gt;
&lt;/S:Envelope&gt;

I need to extract several values, for example788 in status:type in the first &lt;return... block.

I have a test utility for checking returned values from the response:

@Test
public static void xmlPathTester() {
  XmlPath xmlPath = new XmlPath(XML);
  List&lt;String&gt; results = xmlPath.getList(&quot;S:Envelope.S:Body.ns0:liststatusResponse.return.status:type.text()&quot;);
    for (String result : results) {
        System.out.println(result);
    }
}

But this currently returns 1 result ~ an empty String.

It's not clear to me where I am going wrong.

答案1

得分: 1

"When you use XmlPath, don't provide namespaces."

XmlPath path = XmlPath.from(xml);
    path.getList("Envelope.Body.liststatusResponse.return.type.text()").forEach(System.out::println);

This code returns:

788

In order to declare namespaces you have to make XmlPath namespace aware as per documentation:

given().
        config(RestAssured.config().xmlConfig(xmlConfig().with().namespaceAware(true))).
when().
         get("/package-db-xml").
then().
         body(hasXPath("/db:package-database", namespaceContext));

and since you have multiple namespaces I would just use non-namespace XmlPath


<details>
<summary>英文:</summary>

When you use XmlPath, don&#39;t provide namespaces.

XmlPath path = XmlPath.from(xml);
path.getList("Envelope.Body.liststatusResponse.return.type.text()").forEach(System.out::println);


This code returns:

788


In order to declare namespaces you have to make XmlPath namespace aware as per [documentation][1]:

given().
config(RestAssured.config().xmlConfig(xmlConfig().with().namespaceAware(true))).
when().
get("/package-db-xml").
then().
body(hasXPath("/db:package-database", namespaceContext));


and since you have multiple namespaces I would just use non-namespace XmlPath


  [1]: https://github.com/rest-assured/rest-assured/wiki/Usage#xml-namespaces

</details>



huangapple
  • 本文由 发表于 2020年8月3日 18:15:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/63227560.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定