XQuery in soapUI Part 1: For and Return Clauses

A few weeks ago I spent a few posts looking at XPath assertions in soapUI; in this post I'll take a look at XQuery assertions.  XQuery assertions can be used to retrieve data from XML using a SQL-like syntax.  The advantage of XQuery over XPath is that it can be used to check multiple node values with a single expression.  XPath expressions in soapUI must resolve to a single value (a count, a Boolean, a node, a node value, etc.); while you can use an XPath expression to validate some large chunk of static data, XQuery provides a little more flexibility, allowing you to pick and choose the nodes you'd like to have returned-- particularly useful in cases where there's a mix of static and dynamic data.

For an example, let's look at the Euro 2004 web service I introduced a few posts back and look at the AllPlayerNames request.  You can download a stripped down "test suite" consisting of a single test case here.  Import the project into soapUI and run the test request; it should return a list of participating players in the Euro 2012 tournament:


Let's say (strictly for the sake of this example) we're only interested in validating the iId, sName, and sCountryName values for each player, verifying they match their expected values.  Expand the Assertions panel for the test request, click the icon to add a new assertion, and select the XQuery Match assertion type (part of the Property Content group in the Add Assertion dialog) to bring up the assertion editor.

As with XPath assertions, you'll need to make some namespace declarations; click the Declare button at the top of the editor to let soapUI do this for you.  The XQuery expression below returns the iId, sName, and sCountryName values for all players; enter it beneath the namespace declarations as shown:


Click the "Select from current" button to evaluate the XQuery expression.  Here's a snippet of the results:


Let's break down the expression, starting with the for clause: for $x in //m:tPlayerNames.  If you're familiar with for-in or foreach-in loops in some programming languages, used to iterate through a collection and perform some action on each of its members, this is a bit similar.  The for clause here essentially translates to "for each member in the set of elements returned by //m:tPlayerNames..."  The clause also assigns those elements to the variable $x in subsequent lines of the expression.

The return clause does the heavy lifting, retrieving data associated with each element via XPath expressions.  For example, $x/m:iId/text() returns the value of the iId child element for each element. The text() function may be new for some-- it simply indicates that you want the actual inner value (i.e., the value between tags) of an element.  With soapUI's XPath expressions, the text() function isn't necessary (specifying an element is enough to indicate you want its value and not the node itself), it is required for XQuery expressions.

Tags are used to group and organize expression results.  Experimenting a little bit with the expression, you'll see a couple of general rules.  If the XPath expression in the for clause returns multiple nodes, the entire expression should be wrapped in tags (like the "playerList" tag above).  Likewise, you'll receive an error if you try to alter the example expression by removing the "player" tag around the return XPath expressions-- because there are multiple XPath expressions applied to each element, a tag is needed to separate each element's returned data (each id, name, and country set).  The "id", "name", and "country" tags are not in fact necessary, but they make the results more readable.

Within tags, brackets ( "{" and "}" ) are used to identify expression content that needs to be evaluated, as opposed to literal text, which can also be included between tags.  Here's a variation on the example expression that includes some literal text:


Here's what the result looks like:


As you can see, the literal characters within the tags (but outside the brackets) are left intact in the expression output.

Now that you're familiar with the basic syntax of XQuery expressions, we'll look at where and order by clauses in the next post.