Build, protect and deploy apps across any platform and mobile device
Leverage a complete UI toolbox for web, mobile and desktop development
Automate UI, load and performance testing for web, desktop and mobile
Rapidly develop, manage and deploy business apps, delivered as SaaS in the cloud
Build mobile apps for iOS, Android and Windows Phone
Optimize data integration with high-performance connectivity
Connect to any cloud or on-premise data source using a standard interface
Build engaging multi-channel web and digital experiences with intuitive web content management
Automate decision processes with a no-code business rules engine
In part 1, we exposed data in XML documents residing in the file system via either SOAP or REST, using DataDirect XQuery and a servlet container such as Tomcat, JBoss, WebSphere, WebLogic, etc. The queries that were run were analogous to a "SELECT * from" SQL statement. They brought back everything.
What if you needed to be more selective? What if you needed to limit or restrict the data that was returned?
To refresh: in the previous post we used a query stored in a file called "AllProducts.xquery". It contained this query.
This query was run against all files with a ".xml" extension in the specified folder. This group of files is known as a "collection", in xquery terminology.
Running the "AllProducts.xquery" query aggregated all the different product entries scattered across the ".xml" files in the specified folder. What if we wanted to restrict what is returned? How about returning only those items that have a "dept" value of "MEN"? or "ACC"? or "WMN"?
The original query can be modified to further narrow down the results we want. In this case, we want product detail only for those products that have the attribute "dept" with a value of "MEN". We will append additional qualifiers onto the query that returned all the info. In this case, by specifying "[@dept = "MEN"], we are directing XQuery to further subset the results, only returning those items in the "/catalog/product" part of the XML "collection" that have an attribute of "dept" which has a value of "MEN"! Think of it like working with SQL, starting with a "SELECT" statement that returns a whole table, and then you refine that SQL statement such that you only want "State = 'PA'" or "ORDER STATUS = 'shipped'".
The new query has been stored in its own file, AllMenProducts.xquery, for integration via the XQueryWebService servlet running in the same application context on Tomcat. If we invoke it via REST within FireFox, we get the expected results! The URL shows the webapp context, ProductInfo, along with the particular query being invoked, AllMenProducts.xquery.
Similarly, using the SOAP client, we can inspect the auto-generated WSDL. (The separate queries show up as unique methods within a particular context.) Not very exciting, since we'll simply be invoking the "AllMenProducts.xquery" operation.
When invoked, we again get the expected results.
But what if you didn't want to hardcode which value you wanted to search on? What if it's the "MEN" department now, but you want to then query the "WMN" or the "ACC" values. Do you have to write a separate query for each?
Of course not! We are going to use external variables.
Let's continue to build upon the XQuery statements we've successfully developed. Where we previously hard-coded a value for the "MEN" attribute, we are now going to use a variable.
The query needs to be "enhanced" to incorporate an external variable declaration, as well replacing the hard-coded value with the external variable.
This external variable is a placeholder that receives a value at execution time. The value can be passed via a SOAP invocation or via REST.
The use of a variable is expressed in the WSDL associated with this XQuery. (Remember, the WSDL is auto-generated by the XQueryWebService servlet that is included with Progress DataDirect XQuery.)
It shows that a variable named "department" of type "xs:string" is required. With this particular SOAP client (a native COCOA Macintosh application, available on Google code), you can provide a value for the "department" variable and then execute the SOAP request, yielding the expected results.
Similarly, if being integrated into a RESTful architecture, the URL incorporating an external variable is very easy to understand.
In this case, the URL is:
Invoking this in FireFox yields:
Continuing this idea, if you just want to retrieve the Product Information where the value of the attribute "department" is "WMN", the URL is as follows:
Calling this in Firefox yields:
By passing in a value for the external variable, the query is able to be changed at runtime! Using either SOAP or REST!
Hopefully, this has given you an introduction as to how Progress DataDirect XQuery can be used to expose files and selectively extract data from XML files resident in the file system via SOAP or REST. If you'd like to read more about XQuery, in general, I have found Priscilla Walmsley's book "XQuery" to be extremely informative. It's now also available as a Kindle ebook!
More information on the XQueryWebService is available in Chapter 9 of the Progress DataDirect XQuery User Guide (.pdf download or online version).
View all posts from Greg Stasko on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Copyright © 2017, Progress Software Corporation and/or its subsidiaries or affiliates.
All Rights Reserved.
Progress, Telerik, and certain product names used herein are trademarks or registered trademarks of Progress Software Corporation and/or one of its subsidiaries or affiliates in the U.S. and/or other countries. See Trademarks or appropriate markings.