3

Given the below SOAP response, how would I use XPATH to do some testing/validation of the content of the response? NOTE: I am using RunScope to test our API.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetValidDataExtractResponse xmlns="http://some.namespace">
<GetValidDataForExtractResult>
<long>1001</long>
<long>1002</long>
  </GetValidDataForExtractResult>
</GetValidDataExtractResponse>
</soap:Body>
</soap:Envelope>

I can get a valid value back by using: /soap:Envelope/soap:Body But, this doesn't get me very far beyond "does something exist in the body". I'd like to be able to determine if the "GetValidDataExtractResponse" node contains something, also if the "etValidRentalUnitIdsForExtractResult" node contains X number of items or if that node contains certain values.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
coach_rob
  • 877
  • 13
  • 28
  • Unlike forum sites, we don't use "Thanks", or "Any help appreciated", or signatures on [so]. See "[Should 'Hi', 'thanks,' taglines, and salutations be removed from posts?](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts). – John Saunders Oct 31 '14 at 03:39
  • To me, one of the best things about SO is people not constantly telling me what I've done wrong (like forum sites). But, thanks for the reminder. – coach_rob Nov 01 '14 at 14:45

2 Answers2

1

You can check for the existence of a child node as parent[child]. So here's some ideas, assuming you have a namespace alias x set up for http://some.namespace, and that you've made a typo in the closing tags):

  • "Find GetValidDataExtractResponse with a GetValidDataForExtractResult child":

x:GetValidDataExtractResponse[x:GetValidDataForExtractResult]
  • "Find GetValidDataForExtractResult with exactly two long children":

x:GetValidDataForExtractResult[count(x:long)=2]
  • Find the GetValidDataForExtractResult with a long child with a '1001' as a text value

x:GetValidDataForExtractResult[x:long/text()='1001']

I don't personally use RunScope, but I would imagine it has a way to test if an xpath nodes select returns zero nodes (or a null element for a single node select).

StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • This looks very promising. Explain to me how to setup an alias. – coach_rob Oct 29 '14 at 23:09
  • @coach_rob You don't need to prefix the elements that belong to the default namespace, just use the element name in the XPath query. – Darrel Miller Oct 29 '14 at 23:26
  • @coach_rob The count operator does not work within the property name. You could use a script based assertion to do more sophisticated tests. See https://www.runscope.com/docs/radar/scripts and we enable this https://code.google.com/p/marknote/wiki/DevelopersGuide XML parser in scripts. – Darrel Miller Oct 29 '14 at 23:32
  • @DarrelMiller - I'm trying to set a variable called "IdsList" using this: /soap:Envelope/soap:Body/GetValidDataExtractResponse/GetValidDataExtractResult but RunScope can't parse. Am I reading your first response incorrectly? – coach_rob Oct 30 '14 at 16:24
  • Try using namespace agnostic syntax. If this works: `//*[local-name()='GetValidDataExtractResponse/GetValidDataExtractResult']` then I'm pretty certain that you will need to accomodate namespaces - `GetValidDataExtractResponse` et al are not in the global namespace, it is in `xmlns="http://some.namespace"` – StuartLC Oct 30 '14 at 16:27
  • @coach_rob Your sample data is not working for me either. I look into this with the team tomorrow. – Darrel Miller Oct 31 '14 at 03:05
1

Ok, this is not pretty, but it may just work for you. Using the scripts capability in Runscope tests you can extract the values from the body. Here is an example that extracts the first "long" value.

var parser = new marknote.Parser();
var doc = parser.parse(response.body);

var envelope = doc.getRootElement();
var body = envelope.getChildElement("soap:Body");
var resp = body.getChildElement("GetValidDataExtractResponse");
var result = resp.getChildElement("GetValidDataForExtractResult");
var long = result.getChildElement("long");
variables.set("id", long.getText());
Darrel Miller
  • 139,164
  • 32
  • 194
  • 243